-
Notifications
You must be signed in to change notification settings - Fork 0
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
Showing
14 changed files
with
630 additions
and
3 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,104 @@ | ||
# Swaga CLI Tool | ||
|
||
Swaga is a simple CLI tool to list, view, and convert Swagger API endpoints. It helps you explore the API structure from a Swagger/OpenAPI specification file and convert API requests into common formats like `curl`, `fetch`. | ||
|
||
## Features | ||
|
||
- **List**: Display all API endpoints from a Swagger file in a structured table format. | ||
- **View**: View detailed information about a specific API endpoint. | ||
- **Convert**: Convert an API endpoint into `curl`, `fetch` request formats. | ||
|
||
## Installation | ||
|
||
You can install `swaga` by cloning the repository and building the binary: | ||
|
||
```bash | ||
git clone https://github.com/idsulik/swama | ||
cd swama | ||
go build -o swaga | ||
``` | ||
|
||
Ensure that the binary is placed in a directory included in your `PATH`. | ||
|
||
## Usage | ||
|
||
Swaga provides several commands for interacting with your Swagger/OpenAPI file: | ||
|
||
### General Usage | ||
|
||
```bash | ||
swaga [command] | ||
``` | ||
|
||
### Available Commands | ||
|
||
- **`completion`**: Generate the autocompletion script for your shell. | ||
- **`convert`**: Convert an API endpoint to different request formats (e.g., `curl`, `fetch`). | ||
- **`list`**: Lists all API endpoints in a structured table format. | ||
- **`view`**: View details about a specific API endpoint. | ||
- **`help`**: Show help for commands. | ||
|
||
### Global Flags | ||
|
||
- **`-f, --file`**: Path to the Swagger JSON/YAML file. If omitted, `swaga` will attempt to locate the Swagger file in the current directory. | ||
- **`-h, --help`**: Display help for the `swaga` CLI. | ||
|
||
### Examples | ||
|
||
#### List all endpoints | ||
|
||
```bash | ||
swaga list -f ./swagger.json | ||
``` | ||
|
||
This command lists all API endpoints defined in the `swagger.json` file. | ||
|
||
#### View details of a specific endpoint | ||
|
||
```bash | ||
swaga view -f ./swagger.json --endpoint /api/users | ||
``` | ||
|
||
This command will display detailed information about the `/api/users` endpoint. | ||
|
||
#### Convert an endpoint to a `curl` command | ||
|
||
```bash | ||
swaga convert -f ./swagger.json --endpoint /api/users --type curl | ||
``` | ||
|
||
This command converts the `/api/users` endpoint to a `curl` command. | ||
|
||
#### Generate shell autocompletion | ||
|
||
You can generate autocompletion scripts for your shell (e.g., bash, zsh, fish): | ||
|
||
```bash | ||
swaga completion bash > /etc/bash_completion.d/swaga | ||
``` | ||
|
||
## More Information | ||
|
||
For more details on each command, use the `--help` flag with the command: | ||
|
||
```bash | ||
swaga [command] --help | ||
``` | ||
|
||
For example: | ||
|
||
```bash | ||
swaga list --help | ||
``` | ||
|
||
## Contributing | ||
|
||
Feel free to contribute to this project by submitting issues or pull requests at the official [GitHub repository](https://github.com/idsulik/swama). | ||
|
||
## License | ||
|
||
This project is licensed under the MIT License. See the `LICENSE` file for more details. | ||
|
||
--- | ||
|
||
Swaga simplifies exploring and interacting with your Swagger-defined API, making it easier to understand and test API endpoints quickly. |
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,9 @@ | ||
package cmd | ||
|
||
// GlobalConfig holds the global flags like swaggerPath. | ||
type GlobalConfig struct { | ||
SwaggerPath string | ||
} | ||
|
||
// Initialize the global config instance | ||
var config GlobalConfig |
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,48 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/spf13/cobra" | ||
"swama/pkg/converter" | ||
"swama/pkg/openapi" | ||
) | ||
|
||
var convertCmd = &cobra.Command{ | ||
Use: "convert", | ||
Short: "Convert an endpoint to curl or fetch", | ||
Args: cobra.ExactArgs(2), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
ctx := cmd.Context() | ||
parts := strings.Split(args[0], " ") | ||
var method, endpoint string | ||
if len(parts) == 1 { | ||
method = "GET" | ||
endpoint = parts[0] | ||
} else { | ||
method = parts[0] | ||
endpoint = strings.Join(parts[1:], " ") | ||
} | ||
convertType := args[1] | ||
|
||
swagger, err := openapi.ParseSwaggerFile(ctx, config.SwaggerPath) | ||
if err != nil { | ||
return fmt.Errorf("error parsing Swagger file: %w", err) | ||
} | ||
|
||
converter, err := converter.NewConverter(convertType) | ||
if err != nil { | ||
return fmt.Errorf("error creating converter: %w", err) | ||
} | ||
|
||
value, err := converter.ConvertEndpoint(swagger, method, endpoint) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error converting endpoint: %w", err) | ||
} | ||
|
||
fmt.Println(value) | ||
return nil | ||
}, | ||
} |
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,134 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
"maps" | ||
"os" | ||
"regexp" | ||
"slices" | ||
|
||
"github.com/olekukonko/tablewriter" | ||
"github.com/spf13/cobra" | ||
"swama/pkg/openapi" | ||
) | ||
|
||
type ListConfig struct { | ||
method string | ||
endpoint string | ||
tag string | ||
group string | ||
} | ||
|
||
const ( | ||
GroupByTag = "tag" | ||
GroupByMethod = "method" | ||
GroupByNone = "none" | ||
) | ||
|
||
// Command-specific flags for the list command | ||
var listConfig = ListConfig{} | ||
|
||
// listCmd represents the list command | ||
var listCmd = &cobra.Command{ | ||
Use: "list", | ||
Short: "Lists all API endpoints from a Swagger file", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
ctx := cmd.Context() | ||
swagger, err := openapi.ParseSwaggerFile(ctx, config.SwaggerPath) | ||
if err != nil { | ||
return fmt.Errorf("error parsing Swagger file: %w", err) | ||
} | ||
|
||
type groupItem struct { | ||
method string | ||
path string | ||
summary string | ||
tags string | ||
} | ||
groupedEndpoints := make(map[string][]groupItem) | ||
for _, path := range swagger.Paths.InMatchingOrder() { | ||
for method, operation := range swagger.Paths.Find(path).Operations() { | ||
if listConfig.endpoint != "" { | ||
if matched, _ := regexp.MatchString(fmt.Sprintf("^%s$", listConfig.endpoint), path); !matched { | ||
continue | ||
} | ||
} | ||
|
||
if listConfig.method != "" && method != listConfig.method { | ||
continue | ||
} | ||
|
||
if listConfig.tag != "" && !slices.Contains(operation.Tags, listConfig.tag) { | ||
continue | ||
} | ||
|
||
tags := "" | ||
if len(operation.Tags) > 0 { | ||
tags = fmt.Sprintf("%v", operation.Tags) | ||
} | ||
|
||
if listConfig.group != "" { | ||
keys := make([]string, 0) | ||
if listConfig.group == GroupByTag { | ||
for _, tag := range operation.Tags { | ||
description := swagger.Tags.Get(tag).Description | ||
keys = append(keys, fmt.Sprintf("%s (%s)", tag, description)) | ||
} | ||
} else if listConfig.group == GroupByMethod { | ||
keys = append(keys, method) | ||
} else { | ||
keys = append(keys, "none") | ||
} | ||
|
||
for _, key := range keys { | ||
if _, ok := groupedEndpoints[key]; !ok { | ||
groupedEndpoints[key] = make([]groupItem, 0) | ||
} | ||
groupedEndpoints[key] = append( | ||
groupedEndpoints[key], | ||
groupItem{ | ||
method: method, | ||
path: path, | ||
summary: operation.Summary, | ||
tags: tags, | ||
}, | ||
) | ||
} | ||
continue | ||
} | ||
} | ||
} | ||
|
||
// Sort and print the grouped endpoints | ||
sortedKeys := slices.Sorted(maps.Keys(groupedEndpoints)) | ||
var table *tablewriter.Table | ||
fmt.Println() | ||
for _, key := range sortedKeys { | ||
if key != GroupByNone { | ||
fmt.Printf("%s\n", key) | ||
} | ||
|
||
table = tablewriter.NewWriter(os.Stdout) | ||
table.SetHeader([]string{"Method", "Path", "Summary", "Tags"}) | ||
values := groupedEndpoints[key] | ||
for _, value := range values { | ||
table.Append([]string{value.method, value.path, value.summary, value.tags}) | ||
} | ||
|
||
table.Render() | ||
|
||
if key != GroupByNone { | ||
fmt.Println() | ||
} | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
|
||
func init() { | ||
listCmd.Flags().StringVarP(&listConfig.endpoint, "endpoint", "e", "", "Filter by endpoint, supports wildcard") | ||
listCmd.Flags().StringVarP(&listConfig.method, "method", "m", "", "Filter by method") | ||
listCmd.Flags().StringVarP(&listConfig.tag, "tag", "t", "", "Filter by tag") | ||
listCmd.Flags().StringVarP(&listConfig.group, "group", "g", GroupByTag, "Group output by tag, method") | ||
} |
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,38 @@ | ||
package cmd | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/spf13/cobra" | ||
"swama/pkg/openapi" | ||
) | ||
|
||
// rootCmd represents the base command | ||
var rootCmd = &cobra.Command{ | ||
Use: "swaga", | ||
Short: "CLI tool for Swagger/OpenAPI operations", | ||
Long: `A simple CLI tool to list, view and convert Swagger endpoints.`, | ||
PersistentPreRun: func(cmd *cobra.Command, args []string) { | ||
if config.SwaggerPath == "" { | ||
config.SwaggerPath = openapi.LocateSwaggerFile() | ||
} | ||
}, | ||
} | ||
|
||
func Execute(ctx context.Context) error { | ||
return rootCmd.ExecuteContext(ctx) | ||
} | ||
|
||
func init() { | ||
rootCmd.PersistentFlags().StringVarP( | ||
&config.SwaggerPath, | ||
"file", | ||
"f", | ||
"", | ||
"Path to the Swagger JSON/YAML file. If not provided, the tool will try to locate it.", | ||
) | ||
rootCmd.AddCommand(listCmd) | ||
rootCmd.AddCommand(viewCmd) | ||
rootCmd.AddCommand(convertCmd) | ||
rootCmd.SetHelpCommand(nil) | ||
} |
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,32 @@ | ||
package cmd | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/spf13/cobra" | ||
"swama/pkg/openapi" | ||
) | ||
|
||
var viewCmd = &cobra.Command{ | ||
Use: "view", | ||
Short: "View details of a specific endpoint", | ||
Args: cobra.ExactArgs(1), | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
endpoint := args[0] | ||
|
||
ctx := cmd.Context() | ||
swagger, err := openapi.ParseSwaggerFile(ctx, config.SwaggerPath) | ||
if err != nil { | ||
return fmt.Errorf("error parsing Swagger file: %w", err) | ||
} | ||
|
||
details, err := openapi.ViewEndpointDetails(swagger, endpoint) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Println(details) | ||
return nil | ||
}, | ||
} |
Oops, something went wrong.