feat: v0.3.0b — add repo edit command, fix repo create --public flag
- 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
This commit is contained in:
parent
43e43e7024
commit
7ee5a61910
4 changed files with 146 additions and 3 deletions
11
CHANGELOG.md
11
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
|
||||
|
|
|
|||
10
README.md
10
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!
|
||||
|
||||
|
|
|
|||
126
cmd/repo.go
126
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue