mirror of
https://gitea.com/gitea/tea.git
synced 2026-10-26 11:01:25 +01:00
refactor(repo,org,team,release): trim help texts, obvious comments and single-use helpers
Signed-off-by: bircni <bircni@icloud.com>
This commit is contained in:
11 files changed
+55
-129
No files matched your search
@@ -21,11 +21,7 @@ func (a *application) adminCommand() *cobra.Command {
|
||||
group := &cobra.Command{Use: "admin", Short: "Manage instance administration", Long: "Administer the Gitea instance. These commands need an administrator account."}
|
||||
users := &cobra.Command{Use: "user", Short: "Manage registered accounts", Long: `List, view, create, edit and delete the accounts of the instance. These commands need an
|
||||
administrator account.`}
|
||||
users.AddCommand(a.adminUserListCommand(), a.adminUserViewCommand())
|
||||
for _, verb := range []string{"create", "edit"} {
|
||||
users.AddCommand(a.adminUserChangeCommand(verb))
|
||||
}
|
||||
users.AddCommand(a.adminUserDeleteCommand())
|
||||
users.AddCommand(a.adminUserListCommand(), a.adminUserViewCommand(), a.adminUserChangeCommand("create"), a.adminUserChangeCommand("edit"), a.adminUserDeleteCommand())
|
||||
group.AddCommand(users)
|
||||
return group
|
||||
}
|
||||
@@ -149,7 +145,6 @@ $ tea admin user view bob --json email,admin`,
|
||||
}
|
||||
}
|
||||
|
||||
// adminUserChangeCommand creates or edits an account.
|
||||
func (a *application) adminUserChangeCommand(verb string) *cobra.Command {
|
||||
var username, email, fullName, description, website, location, visibility, password, passwordFile string
|
||||
var admin, active, restricted, prohibitLogin, mustChangePassword, allowGitHook, allowImportLocal, allowCreateOrganization bool
|
||||
@@ -330,9 +325,8 @@ func (a *application) adminUserDeleteCommand() *cobra.Command {
|
||||
var purge bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete <username>", Short: "Delete an account", Args: argsExact(1), ValidArgsFunction: a.completeAdminUsers(),
|
||||
Long: `Delete an account. Gitea refuses while the user owns repositories or is the last owner of an
|
||||
organization: transfer or delete those first, or pass --purge to delete the account with
|
||||
everything it owns. A purge cannot be undone, so a terminal asks you to type the username.`,
|
||||
Long: `Delete an account. Gitea refuses while the user owns repositories or organizations, unless
|
||||
--purge deletes the account with everything it owns.`,
|
||||
Example: `$ tea admin user delete spammer
|
||||
# also delete the user's repositories, packages and organization memberships
|
||||
$ tea admin user delete spammer --purge`,
|
||||
|
||||
+11
-26
@@ -18,23 +18,17 @@ import (
|
||||
|
||||
// validateBranch rejects invalid Git refs before making requests.
|
||||
func validateBranch(name string) error {
|
||||
if name == "" || name == "@" || strings.HasPrefix(name, "-") || strings.HasPrefix(name, "/") || strings.HasSuffix(name, "/") || strings.HasSuffix(name, ".") || strings.Contains(name, "..") || strings.Contains(name, "@{") || strings.Contains(name, "//") || strings.ContainsAny(name, " ~^:?*[\\\t\r\n") {
|
||||
return clierr.Wrap(clierr.Usage, errors.New("invalid branch name"))
|
||||
}
|
||||
invalid := name == "" || name == "@" || strings.HasPrefix(name, "-") || strings.HasPrefix(name, "/") || strings.HasSuffix(name, "/") || strings.HasSuffix(name, ".") || strings.Contains(name, "..") || strings.Contains(name, "@{") || strings.Contains(name, "//") || strings.ContainsAny(name, " ~^:?*[\\\t\r\n") ||
|
||||
strings.ContainsFunc(name, func(r rune) bool { return r < 32 || r == 127 })
|
||||
for part := range strings.SplitSeq(name, "/") {
|
||||
if strings.HasPrefix(part, ".") || strings.HasSuffix(part, ".lock") {
|
||||
return clierr.Wrap(clierr.Usage, errors.New("invalid branch name"))
|
||||
}
|
||||
invalid = invalid || strings.HasPrefix(part, ".") || strings.HasSuffix(part, ".lock")
|
||||
}
|
||||
for _, r := range name {
|
||||
if r < 32 || r == 127 {
|
||||
return clierr.Wrap(clierr.Usage, errors.New("invalid branch name"))
|
||||
}
|
||||
if invalid {
|
||||
return clierr.Wrap(clierr.Usage, errors.New("invalid branch name"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateBranches validates every branch name.
|
||||
func validateBranches(names []string) error {
|
||||
for _, name := range names {
|
||||
if err := validateBranch(name); err != nil {
|
||||
@@ -249,7 +243,10 @@ $ tea branch delete old-a old-b --yes`,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
subject := branchSubject(args)
|
||||
subject := "branch " + args[0]
|
||||
if len(args) > 1 {
|
||||
subject = fmt.Sprintf("%d branches (%s)", len(args), strings.Join(args, ", "))
|
||||
}
|
||||
if err := a.confirmAction(cmd, terminal.Confirmation{Prompt: "Delete " + subject + " from " + target.Repo + "?"}); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -263,14 +260,6 @@ $ tea branch delete old-a old-b --yes`,
|
||||
return command
|
||||
}
|
||||
|
||||
// branchSubject names one or more branches in a prompt: "branch main" or "2 branches (a, b)".
|
||||
func branchSubject(names []string) string {
|
||||
if len(names) == 1 {
|
||||
return "branch " + names[0]
|
||||
}
|
||||
return fmt.Sprintf("%d branches (%s)", len(names), strings.Join(names, ", "))
|
||||
}
|
||||
|
||||
func (a *application) branchProtectCommand() *cobra.Command {
|
||||
var rule services.Protection
|
||||
var pattern string
|
||||
@@ -278,12 +267,8 @@ func (a *application) branchProtectCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "protect <branch>...",
|
||||
Short: "Protect branches",
|
||||
Long: `Add a protection rule for each branch. By default nobody can push to a protected branch directly
|
||||
and pull requests need one approving review to merge; --allow-push lets users or teams push, and
|
||||
--required-approvals changes the review count.
|
||||
|
||||
The branches must exist. --pattern protects every branch that matches a glob instead, such as
|
||||
release/*, including branches created later.`,
|
||||
Long: `Add a protection rule for each existing branch, or with --pattern for every branch matching a
|
||||
glob. By default nobody can push directly and pull requests need one approving review.`,
|
||||
Example: `# Require two approvals and passing CI on main
|
||||
$ tea branch protect main --required-approvals 2 --status-check ci/build
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
|
||||
var visibilities = []string{"public", "limited", "private"}
|
||||
|
||||
// visibilityColors color the visibility of organizations and accounts.
|
||||
var visibilityColors = map[string]string{"public": "green", "limited": "yellow", "private": "red"}
|
||||
|
||||
// timeField shows an API timestamp relative to now on a TTY, and as RFC3339 for scripts.
|
||||
@@ -38,14 +37,6 @@ func timeField(label, raw string, d terminal.Display) terminal.Field {
|
||||
return terminal.Field{Label: label, Value: terminal.RelativeTime(now, t)}
|
||||
}
|
||||
|
||||
// countOf words a count, such as "1 member" or "2 members".
|
||||
func countOf(n int, singular, plural string) string {
|
||||
if n == 1 {
|
||||
return "1 " + singular
|
||||
}
|
||||
return strconv.Itoa(n) + " " + plural
|
||||
}
|
||||
|
||||
func (a *application) organizationCommand() *cobra.Command {
|
||||
group := &cobra.Command{Use: "org", Short: "Manage organizations", Long: `Work with Gitea organizations: list the ones you belong to, view, create, edit and delete
|
||||
them, and manage their members.
|
||||
@@ -104,7 +95,7 @@ $ tea org list --all`,
|
||||
}
|
||||
|
||||
func (a *application) organizationViewCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
return &cobra.Command{
|
||||
Use: "view <org>", Short: "View an organization", Args: argsExact(1),
|
||||
Example: `$ tea org view acme
|
||||
# print the description only
|
||||
@@ -131,7 +122,6 @@ $ tea org view acme --jq .description`,
|
||||
})
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func organizationView(org services.Organization, size services.OrganizationSize, address string) terminal.View {
|
||||
@@ -149,7 +139,11 @@ func organizationView(org services.Organization, size services.OrganizationSize,
|
||||
singular, plural string
|
||||
}{{"Members", size.Members, "member", "members"}, {"Teams", size.Teams, "team", "teams"}, {"Repositories", size.Repositories, "repository", "repositories"}} {
|
||||
if count.n != nil {
|
||||
counts = append(counts, countOf(*count.n, count.singular, count.plural))
|
||||
noun := count.plural
|
||||
if *count.n == 1 {
|
||||
noun = count.singular
|
||||
}
|
||||
counts = append(counts, strconv.Itoa(*count.n)+" "+noun)
|
||||
view.Fields = append(view.Fields, terminal.Field{Label: count.label, Value: strconv.Itoa(*count.n), PipedOnly: true})
|
||||
}
|
||||
}
|
||||
@@ -200,7 +194,6 @@ func organizationFlags(cmd *cobra.Command, create bool) func() services.Organiza
|
||||
}
|
||||
}
|
||||
|
||||
// organizationName rejects an empty organization argument.
|
||||
func organizationName(raw string) (string, error) {
|
||||
if name := strings.TrimSpace(raw); name != "" {
|
||||
return name, nil
|
||||
@@ -270,11 +263,7 @@ $ tea org edit acme --visibility private`,
|
||||
func (a *application) organizationDeleteCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "delete <org>", Short: "Delete an organization", Args: argsExact(1), ValidArgsFunction: a.completeOrgs(),
|
||||
Long: `Delete an organization with its teams. Gitea refuses while the organization owns
|
||||
repositories: transfer or delete them first.
|
||||
|
||||
The deletion cannot be undone, so a terminal asks you to type the organization's name; --yes
|
||||
skips the question.`,
|
||||
Long: "Delete an organization with its teams. Gitea refuses while the organization owns repositories.",
|
||||
Example: `$ tea org delete acme-old
|
||||
$ tea org delete acme-old --yes`,
|
||||
Annotations: map[string]string{"tea.text": "organization deletion does not return a resource", "tea.confirm": "true"},
|
||||
@@ -371,7 +360,6 @@ func (a *application) completeOrganizationMembers() cobra.CompletionFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// organizationVisibilityCommand publicizes or conceals an organization membership.
|
||||
func (a *application) organizationVisibilityCommand(public bool) *cobra.Command {
|
||||
verb, alias, short, state := "conceal", "private", "Hide a membership", "concealed"
|
||||
if public {
|
||||
|
||||
@@ -165,11 +165,9 @@ func (a *application) releaseDownloadCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "download [<tag>] [<asset>...]",
|
||||
Short: "Download release assets",
|
||||
Long: `Download assets of a release, by name or ID, or those matching --pattern; without either, every
|
||||
asset. --archive downloads the source code archive instead. Without a tag, the latest release is used.
|
||||
|
||||
Files are written to the current directory under their names, to --dir, or to --output; an existing
|
||||
file is replaced only with --clobber. --output - writes one asset to standard output.`,
|
||||
Long: `Download the assets of a release (default: the latest) by name or ID, those matching --pattern,
|
||||
or all of them; --archive downloads the source code instead. Existing files are replaced only with
|
||||
--clobber, and --output - writes one asset to standard output.`,
|
||||
Example: `# Download every asset of the latest release
|
||||
$ tea release download
|
||||
|
||||
@@ -285,7 +283,6 @@ func selectAssets(release services.Release, names, patterns []string) ([]service
|
||||
return selected, nil
|
||||
}
|
||||
|
||||
// downloadArchive downloads the source code of the tag as a zip or tar.gz file.
|
||||
func (a *application) downloadArchive(cmd *cobra.Command, service services.Releases, flags downloadFlags, tag, format string) error {
|
||||
_, repo, _ := strings.Cut(service.Repository, "/")
|
||||
name := repo + "-" + strings.ReplaceAll(tag, "/", "-") + "." + format
|
||||
@@ -311,7 +308,6 @@ func (a *application) downloadArchive(cmd *cobra.Command, service services.Relea
|
||||
return nil
|
||||
}
|
||||
|
||||
// countingReader counts the bytes read through it.
|
||||
type countingReader struct {
|
||||
reader io.Reader
|
||||
n int64
|
||||
|
||||
@@ -139,7 +139,6 @@ $ tea release view v1.0.0 --web`,
|
||||
return command
|
||||
}
|
||||
|
||||
// releaseView shows a release with its notes as the body.
|
||||
func (a *application) releaseView(item services.Release, latest int64) terminal.View {
|
||||
view := terminal.View{Title: cmp.Or(item.Title, item.Tag), Body: item.Body, Kind: "release", URL: item.URL}
|
||||
if item.Title != "" && item.Title != item.Tag {
|
||||
@@ -187,7 +186,6 @@ func (f *releaseFields) register(a *application, cmd *cobra.Command) {
|
||||
_ = cmd.RegisterFlagCompletionFunc("target", a.completeBranches())
|
||||
}
|
||||
|
||||
// options returns the release fields whose flags were passed.
|
||||
func (f *releaseFields) options(a *application, cmd *cobra.Command) (services.ReleaseOptions, error) {
|
||||
opts := services.ReleaseOptions{}
|
||||
changed := cmd.Flags().Changed
|
||||
|
||||
@@ -166,14 +166,12 @@ $ tea repo edit --default-merge-style squash --add-topic cli --add-topic go`,
|
||||
return services.Classify(err, "branch", strconv.Quote(defaultBranch), t.Repo)
|
||||
}
|
||||
}
|
||||
if options.Archived != nil && *options.Archived {
|
||||
if err := a.confirmAction(cmd, terminal.Confirmation{Prompt: "Archive " + t.Repo + "? It becomes read-only."}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// Gitea refuses topic changes on an archived repository, so archiving comes last.
|
||||
repo, archive := t.Repo, options.Archived != nil && *options.Archived
|
||||
if archive {
|
||||
if err := a.confirmAction(cmd, terminal.Confirmation{Prompt: "Archive " + t.Repo + "? It becomes read-only."}); err != nil {
|
||||
return err
|
||||
}
|
||||
options.Archived = nil
|
||||
}
|
||||
if options != (services.RepositoryEdit{}) {
|
||||
@@ -241,12 +239,9 @@ func (a *application) repoCloneCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "clone <repository> [<directory>] [-- <gitflags>...]",
|
||||
Short: "Clone a repository locally",
|
||||
Long: `Clone a repository with the configured Git protocol (git_protocol: https or ssh) and tea's
|
||||
credentials. Git flags can follow --.
|
||||
|
||||
A fork's parent is added as the "upstream" remote, which its default branch pulls from while pushes
|
||||
stay on the fork; tea commands in the clone then target the parent. A pull mirror's source is added
|
||||
as the "source" remote.`,
|
||||
Long: `Clone a repository with the configured Git protocol and tea's credentials. Git flags can
|
||||
follow --. A fork's parent is added as the "upstream" remote, and tea commands in the clone then
|
||||
target the parent.`,
|
||||
Example: `# Clone a repository into ./project
|
||||
$ tea repo clone alice/project
|
||||
|
||||
@@ -304,12 +299,11 @@ func (a *application) repoForkCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "fork [<repository>] [-- <gitflags>...]",
|
||||
Short: "Fork a repository",
|
||||
Long: `Fork a repository for your account, or into an organization with --org. When the account or
|
||||
organization already has a fork, tea reports it instead of failing.
|
||||
Long: `Fork a repository for your account, or into an organization with --org. An existing fork is
|
||||
reported instead of failing.
|
||||
|
||||
With --clone, the fork is cloned, and its parent is added as the "upstream" remote; Git flags can
|
||||
follow --. Inside a clone of the repository, --remote adds the fork as the "origin" remote (or
|
||||
--remote-name), renaming the current "origin" to "upstream".`,
|
||||
--clone clones the fork (Git flags can follow --). Inside a clone of the repository, --remote adds
|
||||
the fork as "origin" and renames the current "origin" to "upstream".`,
|
||||
Example: `# Fork the repository of the current clone and add the fork as origin
|
||||
$ tea repo fork --remote
|
||||
|
||||
@@ -502,18 +496,13 @@ func (a *application) inferredRepository(t target, verb string, refuseYes bool)
|
||||
if t.RepoSource == "--repo" {
|
||||
return "", nil
|
||||
}
|
||||
source := describeRepoSource(t.RepoSource)
|
||||
source := strings.Replace(t.RepoSource, "remote ", "git remote ", 1)
|
||||
if refuseYes && a.options.yes {
|
||||
return "", clierr.Wrap(clierr.Usage, fmt.Errorf("--yes requires an explicit repository, not one inferred from %s: tea repo %s %s --yes", source, verb, t.Repo))
|
||||
}
|
||||
return " (from " + source + ")", nil
|
||||
}
|
||||
|
||||
// describeRepoSource words a repository source for people: git remote upstream, TEA_REPO, ...
|
||||
func describeRepoSource(source string) string {
|
||||
return strings.Replace(source, "remote ", "git remote ", 1)
|
||||
}
|
||||
|
||||
// repoArchiveCommand builds repo archive, or repo unarchive.
|
||||
func (a *application) repoArchiveCommand(archive bool) *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
@@ -581,7 +570,7 @@ $ tea repo archive alice/old-project --yes`,
|
||||
}
|
||||
|
||||
func (a *application) repoRenameCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
return &cobra.Command{
|
||||
Use: "rename <new-name>",
|
||||
Short: "Rename a repository",
|
||||
Long: "Rename a repository; its owner stays the same. Gitea redirects the old name to the new one.",
|
||||
@@ -625,16 +614,13 @@ $ tea repo rename new-name -R alice/old-name`,
|
||||
return a.jsonResult(cmd, item)
|
||||
},
|
||||
}
|
||||
return command
|
||||
}
|
||||
|
||||
func (a *application) repoDeleteCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "delete [<repository>]",
|
||||
Short: "Delete a repository",
|
||||
Long: `Delete a repository with its issues, pull requests, releases and wiki. This cannot be undone.
|
||||
|
||||
Type the repository's name to confirm. With --yes, name the repository explicitly.`,
|
||||
Long: "Delete a repository with its issues, pull requests, releases and wiki. This cannot be undone.",
|
||||
Example: `# Delete a repository after typing its name
|
||||
$ tea repo delete alice/old-project
|
||||
|
||||
|
||||
@@ -61,10 +61,8 @@ func (a *application) repoSetDefaultCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "set-default [<repository>]",
|
||||
Short: "Set the default repository for this clone",
|
||||
Long: `Set the repository that tea commands use in the current Git clone, instead of the one found through
|
||||
its Git remotes. It is saved as tea.repository in the clone's Git configuration.
|
||||
|
||||
Without an argument, the repository that tea selects now is saved.`,
|
||||
Long: `Set the repository that tea commands use in the current Git clone instead of the one of its Git
|
||||
remotes (saved as tea.repository in the clone's Git configuration).`,
|
||||
Example: `# Make tea commands in this clone use the fork's parent
|
||||
$ tea repo set-default alice/project
|
||||
|
||||
@@ -280,7 +278,6 @@ $ tea repo view alice/project --web`,
|
||||
return view
|
||||
}
|
||||
|
||||
// repositoryView shows a repository with its README as the body.
|
||||
func (a *application) repositoryView(item services.Repository, readme string) terminal.View {
|
||||
badges := []terminal.Cell{{Text: "public", Color: "green"}}
|
||||
if item.Private {
|
||||
|
||||
@@ -36,11 +36,9 @@ func (a *application) repoCreateCommand() *cobra.Command {
|
||||
Short: "Create a repository",
|
||||
Long: `Create a repository for your account, or for an organization as ORG/NAME or with --org.
|
||||
|
||||
A new repository is empty unless --auto-init adds a first commit with a README and, optionally, a
|
||||
.gitignore and a license from the server's templates. --template copies another repository instead.
|
||||
|
||||
--source publishes an existing local Git repository: it adds the new repository as a remote of
|
||||
it (origin unless --remote names another), and --push pushes the current branch there.`,
|
||||
--auto-init adds a first commit with a README, .gitignore and license; --template copies another
|
||||
repository. --source adds the new repository as a remote of a local Git repository, and --push
|
||||
pushes its current branch there.`,
|
||||
Example: `# Create a private repository with a README and an MIT license
|
||||
$ tea repo create project --private --auto-init --license MIT
|
||||
|
||||
@@ -83,7 +81,7 @@ $ tea repo create project --source . --push`,
|
||||
return err
|
||||
}
|
||||
}
|
||||
prompted, err := a.requireInput(cmd, &opts.Name, "name", "Repository name", func(name string) error { return validateRepositoryName(name) })
|
||||
prompted, err := a.requireInput(cmd, &opts.Name, "name", "Repository name", validateRepositoryName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -130,11 +128,8 @@ $ tea repo create project --source . --push`,
|
||||
}
|
||||
var item services.Repository
|
||||
if template != "" {
|
||||
templateOpts.Name = opts.Name
|
||||
templateOpts.Owner = org
|
||||
templateOpts.Description = opts.Description
|
||||
templateOpts.Private = opts.Private
|
||||
templateOpts.DefaultBranch = opts.DefaultBranch
|
||||
templateOpts.Name, templateOpts.Owner, templateOpts.Description = opts.Name, org, opts.Description
|
||||
templateOpts.Private, templateOpts.DefaultBranch = opts.Private, opts.DefaultBranch
|
||||
item, err = service.Generate(cmd.Context(), target.Repo, templateOpts)
|
||||
} else {
|
||||
item, err = service.Create(cmd.Context(), org, opts)
|
||||
|
||||
@@ -44,12 +44,9 @@ func (a *application) repoMigrateCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "migrate [<clone-url>]",
|
||||
Short: "Import a repository from another server",
|
||||
Long: `Import a repository into Gitea from a Git URL, or from another forge with --service, which also
|
||||
copies its issues, labels, milestones, pull requests, releases or wiki on request. --mirror creates
|
||||
a pull mirror that Gitea updates from the source instead.
|
||||
|
||||
The repository is named after the last segment of the URL unless --name is given. Imports from a
|
||||
forge with --service need an access token for it.`,
|
||||
Long: `Import a repository from a Git URL, or from another forge with --service (which needs an access
|
||||
token and can also copy issues, pull requests, releases and more). --mirror creates a pull mirror
|
||||
instead. The name defaults to the last segment of the URL.`,
|
||||
Example: `# Import a public Git repository
|
||||
$ tea repo migrate https://github.com/go-gitea/tea.git
|
||||
|
||||
@@ -81,7 +78,7 @@ $ tea repo migrate https://github.com/acme/tool --service github --issues --pull
|
||||
if err := validateMigrationFlags(cmd, opts, passwordFile, tokenFile); err != nil {
|
||||
return err
|
||||
}
|
||||
validURL := func(raw string) error { return validateMigrationURL(raw) }
|
||||
validURL := validateMigrationURL
|
||||
if cmd.Flags().Changed("server-path") {
|
||||
validURL = nil
|
||||
}
|
||||
@@ -95,7 +92,7 @@ $ tea repo migrate https://github.com/acme/tool --service github --issues --pull
|
||||
}
|
||||
}
|
||||
opts.Name = cmp.Or(opts.Name, migrationName(opts.CloneURL))
|
||||
named, err := a.requireInput(cmd, &opts.Name, "name", "Repository name", func(name string) error { return validateRepositoryName(name) })
|
||||
named, err := a.requireInput(cmd, &opts.Name, "name", "Repository name", validateRepositoryName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -21,14 +21,11 @@ func (a *application) repositorySyncCommand() *cobra.Command {
|
||||
command := &cobra.Command{
|
||||
Use: "sync [<repository>]",
|
||||
Short: "Sync a branch with its remote or its fork's parent",
|
||||
Long: `Fast-forward a local branch to the branch of the same name on the repository's Git remote.
|
||||
Long: `Fast-forward a local branch (default: the repository's default branch) to the same branch on
|
||||
the repository's Git remote, without switching branches. Diverged branches are left unchanged.
|
||||
|
||||
The branch defaults to the repository's default branch. It is created when it is missing, and it is
|
||||
never checked out: the branch you are on stays checked out. When the branch is checked out, the
|
||||
working tree must be clean. Branches that have diverged from the remote are left unchanged.
|
||||
|
||||
Given a repository that has no remote in the current directory, sync updates it on the server
|
||||
instead: a fork's branch is fast-forwarded to its parent's, and a pull mirror fetches its source.`,
|
||||
Given a repository without a Git remote here, sync updates it on the server instead: a fork
|
||||
fast-forwards to its parent, and a pull mirror fetches its source.`,
|
||||
Example: `# Fast-forward the default branch from the repository's remote
|
||||
$ tea repo sync
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ func parseTeam(raw string) (teamRef, error) {
|
||||
return teamRef{}, clierr.Wrap(clierr.Usage, fmt.Errorf("invalid team %q: use ORG/TEAM, such as acme/developers, or a team ID", raw))
|
||||
}
|
||||
|
||||
// find looks the team up on the instance.
|
||||
func (r teamRef) find(ctx context.Context, service services.Teams) (services.Team, error) {
|
||||
if r.org != "" {
|
||||
return service.Find(ctx, r.org, r.name)
|
||||
@@ -63,7 +62,6 @@ func (a *application) team(cmd *cobra.Command, raw string) (target, services.Tea
|
||||
return t, service, team, err
|
||||
}
|
||||
|
||||
// teamURL is the page of a team on its instance.
|
||||
func teamURL(t target, team services.Team) string {
|
||||
return webURL(t, "org", team.Organization, "teams", strings.ToLower(team.Name))
|
||||
}
|
||||
@@ -284,7 +282,6 @@ func (f *teamFlags) unitPolicy(cmd *cobra.Command, create bool) (map[string]stri
|
||||
return policy, nil
|
||||
}
|
||||
|
||||
// options returns the supplied team fields.
|
||||
func (f *teamFlags) options(cmd *cobra.Command) services.TeamOptions {
|
||||
opts := services.TeamOptions{}
|
||||
for _, field := range []struct {
|
||||
@@ -436,10 +433,7 @@ func (a *application) teamDeleteCommand() *cobra.Command {
|
||||
var force bool
|
||||
cmd := &cobra.Command{
|
||||
Use: "delete <team>", Short: "Delete a team", Args: argsExact(1), ValidArgsFunction: a.completeTeams(),
|
||||
Long: `Delete a team. Its members lose the access the team gave them.
|
||||
|
||||
Deleting an organization's owner team takes away owner access, so it needs --force and, on a
|
||||
terminal, typing ORG/TEAM.`,
|
||||
Long: "Delete a team. Deleting an organization's owner team needs --force.",
|
||||
Example: `$ tea team delete acme/reviewers
|
||||
$ tea team delete 7 --yes`,
|
||||
Annotations: map[string]string{"tea.text": "team deletion does not return a resource", "tea.confirm": "true", "tea.arguments": teamArguments},
|
||||
@@ -610,7 +604,6 @@ its organization. Repositories are named alone, such as service, or as ORG/NAME.
|
||||
return group
|
||||
}
|
||||
|
||||
// teamRepoAccessCommand grants or revokes team access to repositories.
|
||||
func (a *application) teamRepoAccessCommand(grant bool) *cobra.Command {
|
||||
verb, short, example := "remove", "Revoke team access to repositories", "$ tea team repo remove acme/developers legacy"
|
||||
annotations := map[string]string{"tea.text": "team access changes do not return a resource", "tea.arguments": teamArguments, "tea.confirm": "true"}
|
||||
|
||||
Reference in new issue
Block a user