1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package client
4
5import "slices"
6
7// Contract features this client relies on, as listed by
8// ServerService.GetVersion. A server without one still works for everything
9// else: the CLI warns instead of failing.
10const (
11 // FeatureRepoUpdate is RepoService.UpdateRepo (`ermite repo edit`).
12 FeatureRepoUpdate = "repo.update"
13 // FeatureEventsResume is EventService.Watch with resume_after, which
14 // `ermite watch` uses to continue after a reconnection.
15 FeatureEventsResume = "events.resume"
16 // FeatureMergeRequests is MergeRequestService (`ermite mr`).
17 FeatureMergeRequests = "merge_requests"
18 // FeatureMergeDeleteBranch is MergeMergeRequest with delete_source_branch
19 // (`ermite mr merge --delete-branch`).
20 FeatureMergeDeleteBranch = "merge_requests.delete_branch"
21 // FeatureIssues is IssueService, RepoSettings.issues and the issue:write
22 // scope (`ermite issue`, `ermite repo edit --issues`).
23 FeatureIssues = "issues"
24 // FeatureSigningKey is ServerService.GetSigningKey (`ermite signing-key`).
25 FeatureSigningKey = "signing_key"
26 // FeatureSession is SessionService (`ermite web login`, `web logout`).
27 FeatureSession = "session"
28 // FeaturePasskeys is SessionService.ListPasskeys and RemovePasskey
29 // (`ermite web passkey`). A server lists it only when passkeys are
30 // available (https public URL with a DNS host name).
31 FeaturePasskeys = "passkeys"
32 // FeatureTokenBranchPrefixes is Token.branch_prefixes and
33 // CreateTokenRequest.branch_prefixes (`ermite token create --branch-prefix`).
34 // A server without it ignores the field and would create an unlimited
35 // token: `token create --branch-prefix` reads the features first and
36 // refuses when it is missing (the main guard), and also checks the token it
37 // gets back (a backstop).
38 FeatureTokenBranchPrefixes = "token.branch_prefixes"
39 // FeatureCIRuns is RunService (`ermite run`), FeatureCIRunners its runner
40 // calls (`ermite runner`).
41 FeatureCIRuns = "ci.runs"
42 FeatureCIRunners = "ci.runners"
43 // FeatureCISecrets is SecretService, VariableService and EnvironmentService
44 // (`ermite secret`, `variable`, `environment`).
45 FeatureCISecrets = "ci.secrets"
46 // FeatureCIDispatch is RunService.DispatchWorkflow (`ermite workflow run`).
47 FeatureCIDispatch = "ci.dispatch"
48 // FeatureCIWorkflows is RunService.ListWorkflows, DisableWorkflow and
49 // EnableWorkflow (`ermite workflow list|disable|enable`).
50 FeatureCIWorkflows = "ci.workflows"
51 // FeatureCIArtifacts is ArtifactService (`ermite run artifacts`,
52 // `run download`).
53 FeatureCIArtifacts = "ci.artifacts"
54 // FeatureCommitSignatures is TrustedKeyService and Commit.verification
55 // (`ermite signing-key trust`).
56 FeatureCommitSignatures = "commit_signatures"
57 // FeatureMergeability is MergeRequest.mergeability and the
58 // merge_request_mergeability event.
59 FeatureMergeability = "merge_requests.mergeability"
60 // FeatureAutoMerge is MergeRequestService.EnableAutoMerge and
61 // CancelAutoMerge, RepoSettings.allow_auto_merge and the auto-merge events
62 // (`ermite mr merge --auto`).
63 FeatureAutoMerge = "merge_requests.auto_merge"
64)
65
66// UsedFeatures lists the features the CLI uses, in the order they are reported.
67func UsedFeatures() []string {
68 return []string{FeatureRepoUpdate, FeatureEventsResume, FeatureMergeRequests, FeatureMergeDeleteBranch, FeatureIssues, FeatureMergeability, FeatureSigningKey, FeatureSession, FeatureTokenBranchPrefixes, FeatureCIRuns, FeatureCIRunners, FeatureCISecrets, FeatureCIDispatch, FeatureCIWorkflows, FeatureCIArtifacts, FeaturePasskeys, FeatureCommitSignatures, FeatureAutoMerge}
69}
70
71// MissingFeatures returns the features the CLI uses that have is lacking.
72func MissingFeatures(have []string) []string {
73 var missing []string
74 for _, f := range UsedFeatures() {
75 if !slices.Contains(have, f) {
76 missing = append(missing, f)
77 }
78 }
79 return missing
80}