-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f57ae28
commit 5ec5ff6
Showing
3 changed files
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/bin/bash | ||
source "$(dirname "${BASH_SOURCE}")/lib/init.sh" | ||
|
||
echo "===== Verifying CLI Conventions =====" | ||
|
||
# ensure we have the latest compiled binaries | ||
"${OS_ROOT}/hack/build-go.sh" tools/checkcli | ||
|
||
# Find binary | ||
checkcli="$(os::build::find-binary checkcli)" | ||
|
||
if [[ -z "$checkcli" ]]; then | ||
{ | ||
echo "It looks as if you don't have a compiled checkcli binary" | ||
echo | ||
echo "If you are running from a clone of the git repo, please run" | ||
echo "'./hack/build-go.sh tools/checkcli'." | ||
} >&2 | ||
exit 1 | ||
fi | ||
|
||
if ! output=`$checkcli 2>&1` | ||
then | ||
echo "FAILURE: CLI is not following one or more required conventions:" | ||
echo "$output" | ||
exit 1 | ||
else | ||
echo "SUCCESS: CLI is following all tested conventions." | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
|
||
"github.com/openshift/origin/pkg/cmd/openshift" | ||
"github.com/openshift/origin/pkg/cmd/templates" | ||
) | ||
|
||
var ( | ||
skip = []string{ | ||
"openshift kube", // TODO enable when we upstream all these conventions | ||
"openshift start kubernetes", // TODO enable when we upstream all these conventions | ||
"openshift cli create quota", // TODO has examples starting with '//', enable when we upstream all these conventions | ||
"openshift cli adm", // already checked in 'openshift admin' | ||
"openshift ex", // we will only care about experimental when they get promoted | ||
"openshift cli types", | ||
} | ||
) | ||
|
||
func main() { | ||
errors := []error{} | ||
|
||
cmd := openshift.NewCommandOpenShift("openshift") | ||
errors = append(errors, recursiveCheckCmd(cmd)...) | ||
|
||
if len(errors) > 0 { | ||
for i, err := range errors { | ||
fmt.Fprintf(os.Stderr, "%d. %s\n\n", i+1, err) | ||
} | ||
os.Exit(1) | ||
} | ||
|
||
fmt.Fprintln(os.Stdout, "Congrats, CLI looks good!") | ||
} | ||
|
||
func recursiveCheckCmd(cmd *cobra.Command) []error { | ||
cmdPath := cmd.CommandPath() | ||
|
||
if skipped(cmdPath) { | ||
fmt.Fprintf(os.Stdout, "-----+ skipping command %s\n", cmdPath) | ||
return []error{} | ||
} | ||
|
||
errors := []error{} | ||
|
||
if cmd.HasSubCommands() { | ||
for _, subCmd := range cmd.Commands() { | ||
errors = append(errors, recursiveCheckCmd(subCmd)...) | ||
} | ||
} | ||
|
||
fmt.Fprintf(os.Stdout, "-----+ checking command %s\n", cmdPath) | ||
|
||
checks := []func(cmd *cobra.Command) error{ | ||
checkLongDesc, | ||
checkExamples, | ||
} | ||
|
||
for _, check := range checks { | ||
if err := check(cmd); err != nil { | ||
errors = append(errors, err) | ||
} | ||
} | ||
|
||
return errors | ||
} | ||
|
||
func skipped(cmdPath string) bool { | ||
for _, skipCmdPath := range skip { | ||
if cmdPath == skipCmdPath { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
|
||
func checkLongDesc(cmd *cobra.Command) error { | ||
cmdPath := cmd.CommandPath() | ||
long := cmd.Long | ||
if len(long) > 0 { | ||
if strings.Trim(long, " \t\n") != long { | ||
return fmt.Errorf(`command %q: long description is not normalized | ||
↳ make sure you are calling templates.LongDesc (from pkg/cmd/templates) before assigning cmd.Long`, cmdPath) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func checkExamples(cmd *cobra.Command) error { | ||
cmdPath := cmd.CommandPath() | ||
examples := cmd.Example | ||
if len(examples) > 0 { | ||
for _, line := range strings.Split(examples, "\n") { | ||
if !strings.HasPrefix(line, templates.Indentation) { | ||
return fmt.Errorf(`command %q: examples are not normalized | ||
↳ make sure you are calling templates.Examples (from pkg/cmd/templates) before assigning cmd.Example`, cmdPath) | ||
} | ||
if trimmed := strings.TrimSpace(line); strings.HasPrefix(trimmed, "//") { | ||
return fmt.Errorf(`command %q: we use # to start comments in examples instead of //`, cmdPath) | ||
} | ||
} | ||
} | ||
return nil | ||
} |