-
Notifications
You must be signed in to change notification settings - Fork 12
Add lets self doc command #311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| package cli | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| cmdpkg "github.com/lets-cli/lets/internal/cmd" | ||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| func TestAllowsMissingConfig(t *testing.T) { | ||
| t.Run("help", func(t *testing.T) { | ||
| command := &cobra.Command{Use: "help"} | ||
| if !allowsMissingConfig(command) { | ||
| t.Fatal("expected help to allow missing config") | ||
| } | ||
| }) | ||
|
|
||
| t.Run("completion", func(t *testing.T) { | ||
| root := cmdpkg.CreateRootCommand("v0.0.0-test", "") | ||
| cmdpkg.InitCompletionCmd(root, nil) | ||
|
|
||
| command, _, err := root.Find([]string{"completion"}) | ||
| if err != nil { | ||
| t.Fatalf("unexpected error: %v", err) | ||
| } | ||
|
|
||
| if !allowsMissingConfig(command) { | ||
| t.Fatal("expected completion to allow missing config") | ||
| } | ||
| }) | ||
|
|
||
| t.Run("self subcommand", func(t *testing.T) { | ||
| root := cmdpkg.CreateRootCommand("v0.0.0-test", "") | ||
| cmdpkg.InitSelfCmd(root, "v0.0.0-test") | ||
|
|
||
| command, _, err := root.Find([]string{"self", "doc"}) | ||
| if err != nil { | ||
| t.Fatalf("unexpected error: %v", err) | ||
| } | ||
|
|
||
| if !allowsMissingConfig(command) { | ||
| t.Fatal("expected lets self doc to allow missing config") | ||
| } | ||
| }) | ||
|
|
||
| t.Run("top level doc does not match self", func(t *testing.T) { | ||
| root := cmdpkg.CreateRootCommand("v0.0.0-test", "") | ||
| root.AddCommand(&cobra.Command{Use: "doc"}) | ||
|
|
||
| command, _, err := root.Find([]string{"doc"}) | ||
| if err != nil { | ||
| t.Fatalf("unexpected error: %v", err) | ||
| } | ||
|
|
||
| if allowsMissingConfig(command) { | ||
| t.Fatal("expected top-level doc to require config") | ||
| } | ||
| }) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package cmd | ||
|
|
||
| import ( | ||
| "fmt" | ||
|
|
||
| "github.com/spf13/cobra" | ||
| ) | ||
|
|
||
| const letsDocsURL = "https://lets-cli.org/docs/config" | ||
|
|
||
| func initDocCommand(openURL func(string) error) *cobra.Command { | ||
| docCmd := &cobra.Command{ | ||
| Use: "doc", | ||
| Aliases: []string{"docs"}, | ||
| Short: "Open lets documentation in browser", | ||
| Args: cobra.NoArgs, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| if err := openURL(letsDocsURL); err != nil { | ||
| return fmt.Errorf("can not open documentation: %w", err) | ||
| } | ||
|
|
||
| fmt.Fprintf(cmd.OutOrStdout(), "Opening %s\n", letsDocsURL) | ||
|
|
||
| return nil | ||
| }, | ||
| } | ||
|
|
||
| return docCmd | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| package util | ||
|
|
||
| import ( | ||
| "fmt" | ||
| "os/exec" | ||
| "runtime" | ||
| ) | ||
|
|
||
| func browserCommand(goos string, url string) (*exec.Cmd, error) { | ||
| switch goos { | ||
| case "darwin": | ||
| return exec.Command("open", url), nil | ||
| case "linux": | ||
| return exec.Command("xdg-open", url), nil | ||
| default: | ||
| return nil, fmt.Errorf("unsupported platform %q", goos) | ||
| } | ||
| } | ||
|
|
||
| func OpenURL(url string) error { | ||
| cmd, err := browserCommand(runtime.GOOS, url) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if err := cmd.Start(); err != nil { | ||
| return fmt.Errorf("start %s: %w", cmd.Path, err) | ||
| } | ||
|
|
||
| if cmd.Process != nil { | ||
| _ = cmd.Process.Release() | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| package util | ||
|
|
||
| import ( | ||
| "reflect" | ||
| "strings" | ||
| "testing" | ||
| ) | ||
|
|
||
| func TestBrowserCommand(t *testing.T) { | ||
| t.Run("darwin", func(t *testing.T) { | ||
| cmd, err := browserCommand("darwin", "https://lets-cli.org") | ||
| if err != nil { | ||
| t.Fatalf("unexpected error: %v", err) | ||
| } | ||
|
|
||
| if cmd.Args[0] != "open" { | ||
| t.Fatalf("expected open, got %q", cmd.Args[0]) | ||
| } | ||
|
|
||
| expectedArgs := []string{"open", "https://lets-cli.org"} | ||
| if !reflect.DeepEqual(cmd.Args, expectedArgs) { | ||
| t.Fatalf("expected args %v, got %v", expectedArgs, cmd.Args) | ||
| } | ||
| }) | ||
kindermax marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| t.Run("linux", func(t *testing.T) { | ||
| cmd, err := browserCommand("linux", "https://lets-cli.org") | ||
| if err != nil { | ||
| t.Fatalf("unexpected error: %v", err) | ||
| } | ||
|
|
||
| if cmd.Args[0] != "xdg-open" { | ||
| t.Fatalf("expected xdg-open, got %q", cmd.Args[0]) | ||
| } | ||
|
|
||
| expectedArgs := []string{"xdg-open", "https://lets-cli.org"} | ||
| if !reflect.DeepEqual(cmd.Args, expectedArgs) { | ||
| t.Fatalf("expected args %v, got %v", expectedArgs, cmd.Args) | ||
| } | ||
| }) | ||
|
|
||
| t.Run("unsupported", func(t *testing.T) { | ||
| _, err := browserCommand("windows", "https://lets-cli.org") | ||
| if err == nil { | ||
| t.Fatal("expected unsupported platform error") | ||
| } | ||
| if !strings.Contains(err.Error(), "windows") { | ||
| t.Fatalf("expected error to mention platform %q, got %q", "windows", err.Error()) | ||
| } | ||
| }) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,22 @@ setup() { | |
| } | ||
|
|
||
| NOT_EXISTED_LETS_FILE="lets-not-existed.yaml" | ||
| TEMP_FAKE_BIN_DIR="" | ||
| TEMP_OPENED_URL_FILE="" | ||
|
|
||
| teardown() { | ||
| if [[ -n "${TEMP_FAKE_BIN_DIR}" ]]; then | ||
| rm -rf "${TEMP_FAKE_BIN_DIR}" | ||
| fi | ||
|
|
||
| if [[ -n "${TEMP_OPENED_URL_FILE}" ]]; then | ||
| rm -f "${TEMP_OPENED_URL_FILE}" | ||
| fi | ||
|
|
||
| TEMP_FAKE_BIN_DIR="" | ||
| TEMP_OPENED_URL_FILE="" | ||
| cleanup | ||
| } | ||
|
|
||
| @test "no_lets_file: should not create .lets dir" { | ||
| LETS_CONFIG=${NOT_EXISTED_LETS_FILE} run lets | ||
|
|
@@ -49,4 +65,40 @@ NOT_EXISTED_LETS_FILE="lets-not-existed.yaml" | |
| LETS_CONFIG=${NOT_EXISTED_LETS_FILE} run lets -h | ||
| assert_success | ||
| assert_line --index 0 "A CLI task runner" | ||
| } | ||
| } | ||
|
|
||
| @test "no_lets_file: lets self doc opens docs without config" { | ||
| TEMP_FAKE_BIN_DIR="$(mktemp -d)" | ||
| TEMP_OPENED_URL_FILE="$(mktemp)" | ||
| rm -f "${TEMP_OPENED_URL_FILE}" | ||
|
|
||
| cat > "${TEMP_FAKE_BIN_DIR}/xdg-open" <<'EOF' | ||
| #!/usr/bin/env bash | ||
| printf "%s" "$1" > "${LETS_TEST_OPENED_URL_FILE}" | ||
| EOF | ||
| chmod +x "${TEMP_FAKE_BIN_DIR}/xdg-open" | ||
|
|
||
| cat > "${TEMP_FAKE_BIN_DIR}/open" <<'EOF' | ||
| #!/usr/bin/env bash | ||
| printf "%s" "$1" > "${LETS_TEST_OPENED_URL_FILE}" | ||
| EOF | ||
| chmod +x "${TEMP_FAKE_BIN_DIR}/open" | ||
|
|
||
| PATH="${TEMP_FAKE_BIN_DIR}:${PATH}" \ | ||
| LETS_CONFIG=${NOT_EXISTED_LETS_FILE} \ | ||
| LETS_TEST_OPENED_URL_FILE="${TEMP_OPENED_URL_FILE}" \ | ||
| run lets self doc | ||
|
|
||
| assert_success | ||
|
|
||
| for _ in $(seq 1 20); do | ||
| if [[ -f "${TEMP_OPENED_URL_FILE}" ]]; then | ||
| break | ||
| fi | ||
| sleep 0.1 | ||
| done | ||
|
|
||
| run cat "${TEMP_OPENED_URL_FILE}" | ||
| assert_success | ||
| assert_output "https://lets-cli.org/docs/config" | ||
| } | ||
|
Comment on lines
+70
to
+104
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The test fakes only To make the test portable, create a fake for both launchers: cat > "${fake_bin_dir}/xdg-open" <<'EOF'
#!/usr/bin/env bash
printf "%s" "$1" > "${LETS_TEST_OPENED_URL_FILE}"
EOF
chmod +x "${fake_bin_dir}/xdg-open"
# macOS uses `open`
cat > "${fake_bin_dir}/open" <<'EOF'
#!/usr/bin/env bash
printf "%s" "$1" > "${LETS_TEST_OPENED_URL_FILE}"
EOF
chmod +x "${fake_bin_dir}/open"Alternatively, add a platform guard and |
||
Uh oh!
There was an error while loading. Please reload this page.