package cmd import ( "fmt" "os/exec" "runtime" "forgejo.zerova.net/public/fgj-sid/internal/api" "forgejo.zerova.net/public/fgj-sid/internal/config" "github.com/spf13/cobra" ) var openCmd = &cobra.Command{ Use: "open [issue-or-pr-number]", Aliases: []string{"o"}, Short: "Open a repository, issue, or pull request in a browser", Long: `Open the repository page in a web browser. When an issue or pull request number is given, that page is opened instead. Repository is auto-detected from the current git context, or specified with -R.`, Example: ` # Open the current repository fgj open # Open a specific repository fgj open -R owner/repo # Open issue or PR #42 (Forgejo routes both via the same number) fgj open 42 fgj open '#42' # Print the URL instead of launching a browser fgj open 42 --url`, Args: cobra.MaximumNArgs(1), RunE: runOpen, } func init() { rootCmd.AddCommand(openCmd) addRepoFlags(openCmd) openCmd.Flags().Bool("url", false, "Print URL instead of opening a browser") } func runOpen(cmd *cobra.Command, args []string) error { repo, _ := cmd.Flags().GetString("repo") 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(), getCwd()) if err != nil { return err } url := fmt.Sprintf("https://%s/%s/%s", client.Hostname(), owner, name) if len(args) == 1 { num, err := parseIssueArg(args[0]) if err != nil { return fmt.Errorf("invalid issue or PR number %q: %w", args[0], err) } issue, _, err := client.GetIssue(owner, name, num) if err != nil { return fmt.Errorf("failed to look up #%d: %w", num, err) } kind := "issues" if issue.PullRequest != nil { kind = "pulls" } url = fmt.Sprintf("https://%s/%s/%s/%s/%d", client.Hostname(), owner, name, kind, num) } printOnly, _ := cmd.Flags().GetBool("url") if printOnly || !ios.IsStdoutTTY() { fmt.Fprintln(ios.Out, url) return nil } if err := launchBrowser(url); err != nil { fmt.Fprintf(ios.ErrOut, "Could not open browser (%v); URL: %s\n", err, url) return nil } fmt.Fprintf(ios.ErrOut, "Opening %s in your browser.\n", url) return nil } // launchBrowser opens url in the OS default browser. func launchBrowser(url string) error { var cmd *exec.Cmd switch runtime.GOOS { case "darwin": cmd = exec.Command("open", url) case "windows": cmd = exec.Command("cmd", "/c", "start", "", url) default: cmd = exec.Command("xdg-open", url) } return cmd.Start() }