From 7ee5a619106d30daeeb0572fee71e342ee0b4ff4 Mon Sep 17 00:00:00 2001 From: sid Date: Sat, 21 Mar 2026 21:50:24 -0600 Subject: [PATCH] =?UTF-8?q?feat:=20v0.3.0b=20=E2=80=94=20add=20repo=20edit?= =?UTF-8?q?=20command,=20fix=20repo=20create=20--public=20flag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add `fgj repo edit` for changing visibility, description, homepage, and default branch on existing repositories - Fix `repo create --public` flag which was defined but never read --- CHANGELOG.md | 11 +++++ README.md | 10 +++- cmd/repo.go | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++ cmd/root.go | 2 +- 4 files changed, 146 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f00005..227ecde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0b] - 2026-03-21 + +### Added + +#### Repository Management +- `fgj repo edit` - Edit repository settings (visibility, description, homepage, default branch) + +### Fixed +- `fgj repo create --public` flag was defined but never read; now properly wired up + ## [0.3.0a] - 2026-03-21 ### Added @@ -165,6 +175,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Cobra framework for CLI structure - Viper for configuration management +[0.3.0b]: https://forgejo.zerova.net/sid/fgj-sid/releases/tag/v0.3.0b [0.3.0a]: https://forgejo.zerova.net/sid/fgj-sid/releases/tag/v0.3.0a [0.3.0]: https://codeberg.org/romaintb/fgj/releases/tag/v0.3.0 [0.2.0]: https://codeberg.org/romaintb/fgj/releases/tag/v0.2.0 diff --git a/README.md b/README.md index db31990..adea186 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ - Multi-instance support (works with any Forgejo or Gitea instance) - Pull request management (create, list, view, merge, diff, comment, review) - Issue tracking (create, list, view, comment, close, labels) -- Repository operations (view, list, create, clone, fork) +- Repository operations (view, list, create, edit, clone, fork) - Forgejo Actions (workflow runs, watch/rerun/cancel, enable/disable, secrets, variables) - Releases (create, upload, delete) - Raw API access (`fgj api`) for arbitrary REST calls @@ -207,6 +207,12 @@ fgj repo clone owner/repo -p ssh # Fork a repository fgj repo fork owner/repo + +# Edit repository settings +fgj repo edit owner/repo --public +fgj repo edit owner/repo --private +fgj repo edit owner/repo -d "New description" --homepage https://example.com +fgj repo edit --default-branch develop ``` ### Releases @@ -460,7 +466,7 @@ Contributions are welcome! Please feel free to submit a Pull Request at [forgejo - `pr checks`, `pr ready/draft` - `issue reopen`, `issue assign` - `release edit`, `release download`, `release generate-notes` -- `repo delete`, `repo rename`, `repo visibility` +- `repo delete`, `repo rename` We welcome contributions to implement any of these features! diff --git a/cmd/repo.go b/cmd/repo.go index ef14353..7ca22cd 100644 --- a/cmd/repo.go +++ b/cmd/repo.go @@ -62,10 +62,33 @@ Name can be "reponame" (creates under your account) or "org/reponame" RunE: runRepoCreate, } +var repoEditCmd = &cobra.Command{ + Use: "edit [owner/name]", + Short: "Edit repository settings", + Long: "Edit settings of an existing repository such as visibility, description, homepage, and default branch.", + Example: ` # Make a repository private + fgj repo edit owner/repo --private + + # Make a repository public + fgj repo edit owner/repo --public + + # Update description and homepage + fgj repo edit owner/repo -d "New description" --homepage https://example.com + + # Change default branch + fgj repo edit --default-branch develop + + # Edit current repo (auto-detected from git context) + fgj repo edit --public`, + Args: cobra.MaximumNArgs(1), + RunE: runRepoEdit, +} + func init() { rootCmd.AddCommand(repoCmd) repoCmd.AddCommand(repoCloneCmd) repoCmd.AddCommand(repoCreateCmd) + repoCmd.AddCommand(repoEditCmd) repoCmd.AddCommand(repoForkCmd) repoCmd.AddCommand(repoListCmd) repoCmd.AddCommand(repoViewCmd) @@ -82,6 +105,15 @@ func init() { repoCreateCmd.MarkFlagsMutuallyExclusive("public", "private") repoCloneCmd.Flags().StringP("protocol", "p", "https", "Clone protocol: https or ssh") + + repoEditCmd.Flags().StringP("repo", "R", "", "Repository in owner/name format") + repoEditCmd.Flags().StringP("description", "d", "", "Repository description") + repoEditCmd.Flags().String("homepage", "", "Repository home page URL") + repoEditCmd.Flags().String("default-branch", "", "Default branch name") + repoEditCmd.Flags().Bool("private", false, "Make the repository private") + repoEditCmd.Flags().Bool("public", false, "Make the repository public") + repoEditCmd.Flags().Bool("json", false, "Output updated repository as JSON") + repoEditCmd.MarkFlagsMutuallyExclusive("public", "private") } func runRepoView(cmd *cobra.Command, args []string) error { @@ -270,6 +302,7 @@ func runRepoCreate(cmd *cobra.Command, args []string) error { } private, _ := cmd.Flags().GetBool("private") + public, _ := cmd.Flags().GetBool("public") description, _ := cmd.Flags().GetString("description") addReadme, _ := cmd.Flags().GetBool("add-readme") gitignore, _ := cmd.Flags().GetString("gitignore") @@ -278,6 +311,11 @@ func runRepoCreate(cmd *cobra.Command, args []string) error { doClone, _ := cmd.Flags().GetBool("clone") team, _ := cmd.Flags().GetString("team") + // --public explicitly sets private=false (default behavior, but makes intent clear) + if public { + private = false + } + cfg, err := config.Load() if err != nil { return err @@ -383,3 +421,91 @@ func parseCreateName(name string) (org, repoName string, isOrg bool, err error) } return "", name, false, nil } + +func runRepoEdit(cmd *cobra.Command, args []string) error { + var repo string + if len(args) > 0 { + repo = args[0] + } + if r, _ := cmd.Flags().GetString("repo"); r != "" { + repo = r + } + + owner, name, err := parseRepo(repo) + if err != nil { + return err + } + + cfg, err := config.Load() + if err != nil { + return err + } + + client, err := api.NewClientFromConfig(cfg, "", getDetectedHost()) + if err != nil { + return err + } + + opt := gitea.EditRepoOption{} + changed := false + + if cmd.Flags().Changed("description") { + d, _ := cmd.Flags().GetString("description") + opt.Description = &d + changed = true + } + if cmd.Flags().Changed("homepage") { + h, _ := cmd.Flags().GetString("homepage") + opt.Website = &h + changed = true + } + if cmd.Flags().Changed("default-branch") { + b, _ := cmd.Flags().GetString("default-branch") + opt.DefaultBranch = &b + changed = true + } + if cmd.Flags().Changed("private") { + p := true + opt.Private = &p + changed = true + } + if cmd.Flags().Changed("public") { + p := false + opt.Private = &p + changed = true + } + + if !changed { + return fmt.Errorf("no changes specified; use flags like --public, --private, --description, --homepage, or --default-branch") + } + + repository, _, err := client.EditRepo(owner, name, opt) + if err != nil { + return fmt.Errorf("failed to edit repository: %w", err) + } + + jsonFlag, _ := cmd.Flags().GetBool("json") + if jsonFlag { + return writeJSON(repository) + } + + fmt.Printf("Repository updated: %s\n", repository.HTMLURL) + if opt.Private != nil { + if *opt.Private { + fmt.Println("Visibility: private") + } else { + fmt.Println("Visibility: public") + } + } + if opt.Description != nil { + fmt.Printf("Description: %s\n", *opt.Description) + } + if opt.Website != nil { + fmt.Printf("Homepage: %s\n", *opt.Website) + } + if opt.DefaultBranch != nil { + fmt.Printf("Default branch: %s\n", *opt.DefaultBranch) + } + + return nil +} diff --git a/cmd/root.go b/cmd/root.go index 3c11c7d..35d0e59 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -18,7 +18,7 @@ var rootCmd = &cobra.Command{ Short: "Forgejo CLI tool - work seamlessly with Forgejo from the command line", Long: `fgj is a command line tool for Forgejo instances (including Codeberg). It brings pull requests, issues, and other Forgejo concepts to the terminal.`, - Version: "0.3.0a", + Version: "0.3.0b", SilenceErrors: true, }