package view
import (
"fmt"
"net/http"
"strings"
"time"
"github.com/MakeNowJust/heredoc/v2"
"github.com/spf13/cobra"
"gitcode.com/gitcode-cli/cli/api"
cmdutil "gitcode.com/gitcode-cli/cli/pkg/cmdutil"
"gitcode.com/gitcode-cli/cli/pkg/iostreams"
)
const msTimestampThreshold = 100_000_000_000
type ViewOptions struct {
IO *iostreams.IOStreams
HttpClient func() (*http.Client, error)
Org string
RunnerGroupID string
JSON bool
}
func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Command {
opts := &ViewOptions{
IO: f.IOStreams,
HttpClient: f.HttpClient,
}
cmd := &cobra.Command{
Use: "view <runner-group-id>",
Short: "View a runner group",
Long: heredoc.Doc(`
View the detail of a single organization runner group.
The runner group id is the ` + "`id`" + ` returned by ` + "`gc actions runner-group list`" + `.
Use --json for a faithful, machine-readable copy of the API response.
`),
Example: heredoc.Doc(`
# View a runner group
$ gc actions runner-group view <runner-group-id> --org my-org
# Faithful JSON output
$ gc actions runner-group view <runner-group-id> --org my-org --json
`),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
opts.RunnerGroupID = strings.TrimSpace(args[0])
if opts.RunnerGroupID == "" {
return cmdutil.NewUsageError("runner group id is required")
}
if runF != nil {
return runF(opts)
}
return viewRun(opts)
},
}
cmd.Flags().StringVar(&opts.Org, "org", "", "Organization path (required)")
cmd.MarkFlagRequired("org")
cmdutil.AddJSONFlag(cmd, &opts.JSON)
return cmd
}
func viewRun(opts *ViewOptions) error {
if opts.Org == "" {
return cmdutil.NewUsageError("--org is required")
}
if opts.RunnerGroupID == "" {
return cmdutil.NewUsageError("runner group id is required")
}
client, err := cmdutil.AuthenticatedClientFromFactory(opts.HttpClient)
if err != nil {
return err
}
detail, rawBody, err := api.GetOrgRunnerGroup(client, opts.Org, opts.RunnerGroupID)
if err != nil {
return fmt.Errorf("failed to get runner group: %w", err)
}
if opts.JSON {
if _, err := opts.IO.Out.Write(rawBody); err != nil {
return fmt.Errorf("failed to write JSON output: %w", err)
}
_, err := fmt.Fprintln(opts.IO.Out)
return err
}
printRunnerGroupDetail(opts.IO, detail)
return nil
}
func printRunnerGroupDetail(io *iostreams.IOStreams, d *api.RunnerGroupDetail) {
cs := io.ColorScheme()
fmt.Fprintf(io.Out, "%s %s\n", cs.Bold("ID:"), d.RunnerGroupID)
fmt.Fprintf(io.Out, "%s %s\n", cs.Bold("Name:"), d.RunnerGroupName)
share := "no"
if d.ShareAll {
share = "yes"
}
fmt.Fprintf(io.Out, "%s %s\n", cs.Bold("Share All:"), share)
publicShare := "no"
if d.ShareAllPublicRepos {
publicShare = "yes"
}
fmt.Fprintf(io.Out, "%s %s\n", cs.Bold("Share Public:"), publicShare)
fmt.Fprintf(io.Out, "%s %d\n", cs.Bold("Shared Repos:"), d.ExplicitSharedRepoCount)
fmt.Fprintf(io.Out, "%s %s\n", cs.Bold("Created:"), formatTimestamp(d.CreatedAt))
fmt.Fprintf(io.Out, "%s %s\n", cs.Bold("Updated:"), formatTimestamp(d.UpdatedAt))
}
func formatTimestamp(ts int64) string {
if ts <= 0 {
return "unknown"
}
secs := ts
if ts >= msTimestampThreshold {
secs = ts / 1000
}
return time.Unix(secs, 0).UTC().Format(time.RFC3339)
}