Skip to content

Commit

Permalink
cli: Replace docopt with urfave/cli. (#48)
Browse files Browse the repository at this point in the history
* cli: Replace docopt with urfave/cli.

Fixes issue 25.

* docs: Add subheadings to Readme.

* nit: Rearrange imports.

* nit: Compress if.
  • Loading branch information
varungandhi-src authored Jun 10, 2022
1 parent 55c9bab commit 5e84217
Show file tree
Hide file tree
Showing 9 changed files with 274 additions and 150 deletions.
1 change: 0 additions & 1 deletion Readme.md

This file was deleted.

103 changes: 103 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# SCIP Code Intelligence Protocol

SCIP (pronounciation: "skip") is a language-agnostic protocol
for indexing source code,
which can be used to power code navigation functionality
such as Go to definition, Find references, and Find implementations.

This repository includes:

- A [protobuf schema for SCIP](./scip.proto).
- Rich Go bindings for SCIP: This includes many utility functions
to help build tooling on top of SCIP.
- Auto-generated bindings for TypeScript, Rust and Haskell.
- The [`scip` CLI](#scip-cli-reference) makes SCIP indexes
a breeze to work with.

If you're interested in better understanding the motivation behind SCIP,
check out the [announcement blog post](https://about.sourcegraph.com/blog/announcing-scip).

If you're interested in writing a new indexer that emits SCIP,
check out our documentation on
[how to write an indexer](https://docs.sourcegraph.com/code_intelligence/explanations/writing_an_indexer).

## Contributing

We welcome questions, suggestions as well as code and docs contributions.

For submitting contributions, check out [Development.md](./Development.md)
to better understand project structure and common workflows.

Contributors should abide by the [Sourcegraph Code of Conduct](https://handbook.sourcegraph.com/company-info-and-process/communication/code_of_conduct/).

## SCIP CLI reference

```
NAME:
scip - SCIP Code Intelligence Protocol CLI
USAGE:
scip [global options] command [command options] [arguments...]
DESCRIPTION:
For more details, see the project README at:
https://github.com/sourcegraph/scip
COMMANDS:
convert Convert a SCIP index to an LSIF index
snapshot Generate snapshot files for golden testing
stats Output useful statistics about a SCIP index
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--help, -h show help (default: false)
--version, -v Print the current version and exit. (default: false)
```

### `scip convert`

```
NAME:
scip convert - Convert a SCIP index to an LSIF index
USAGE:
scip convert [command options] [arguments...]
OPTIONS:
--from value Path to SCIP index file (default: index.scip)
--to value Output path for LSIF index (default: dump.lsif)
```

### `scip snapshot`

```
NAME:
scip snapshot - Generate snapshot files for golden testing
USAGE:
scip snapshot [command options] [arguments...]
DESCRIPTION:
The snapshot subcommand generates snapshot files which
can be use for inspecting the output of an index in a
visual way. Occurrences are marked with caret signs (^)
and symbol information.
OPTIONS:
--from value Path to SCIP index file (default: index.scip)
--to value Path to output directory for snapshot files (default: scip-snapshot)
```

### `scip stats`

```
NAME:
scip stats - Output useful statistics about a SCIP index
USAGE:
scip stats [command options] [arguments...]
OPTIONS:
--from value Path to SCIP index file (default: index.scip)
```
66 changes: 0 additions & 66 deletions cmd/Readme.md

This file was deleted.

34 changes: 31 additions & 3 deletions cmd/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,48 @@ import (
"os"
"strings"

"github.com/urfave/cli/v2"

"github.com/sourcegraph/sourcegraph/lib/codeintel/lsif/protocol/reader"
"github.com/sourcegraph/sourcegraph/lib/errors"

"github.com/sourcegraph/scip/bindings/go/scip"
)

func convertMain(parsedArgs map[string]interface{}) error {
scipIndex, err := readFromOption(parsedArgs["--from"].(string))
type convertFlags struct {
from string
to string
}

func convertCommand() cli.Command {
var convertFlags convertFlags
convert := cli.Command{
Name: "convert",
Usage: "Convert a SCIP index to an LSIF index",
Flags: []cli.Flag{
fromFlag(&convertFlags.from),
&cli.StringFlag{
Name: "to",
Usage: "Output path for LSIF index",
Destination: &convertFlags.to,
DefaultText: "dump.lsif",
},
},
Action: func(c *cli.Context) error {
return convertMain(convertFlags)
},
}
return convert
}

func convertMain(flags convertFlags) error {
scipIndex, err := readFromOption(flags.from)
if err != nil {
return err
}

var lsifWriter io.Writer
toPath := parsedArgs["--to"].(string)
toPath := flags.to
if toPath == "-" {
lsifWriter = os.Stdout
} else if !strings.HasSuffix(toPath, ".lsif") {
Expand Down
86 changes: 43 additions & 43 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -1,59 +1,59 @@
package main

import (
_ "embed"
"fmt"
"log"
"os"
"regexp"

"github.com/docopt/docopt-go"
"github.com/urfave/cli/v2"
)

//go:embed Readme.md
var readme string

func helpText() string {
usageRegexp := regexp.MustCompile("(?s)<!-- begin usage -->\n\n```\n(.*)\n```\n\n<!-- end usage -->")
usageText := usageRegexp.FindStringSubmatch(readme)[1]
return fmt.Sprintf(helpTextTemplate, usageText)
func main() {
app := scipApp()
if err := app.Run(os.Args); err != nil {
log.Fatal(err)
}
}

const helpTextTemplate string = `Semantic Code Intelligence Protocol CLI.
%s
For more details, see the project README: https://github.com/sourcegraph/scip
`
func commands() []*cli.Command {
convert := convertCommand()
snapshot := snapshotCommand()
stats := statsCommand()
return []*cli.Command{&convert, &snapshot, &stats}
}

func bailIfError(err error) {
if err != nil {
os.Stderr.WriteString(err.Error())
os.Exit(1)
func scipApp() cli.App {
var versionFlag bool
app := cli.App{
Name: "scip",
Usage: "SCIP Code Intelligence Protocol CLI",
Description: "For more details, see the project README at:\n\n\thttps://github.com/sourcegraph/scip",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "version",
Usage: "Print the current version and exit.",
Destination: &versionFlag,
Aliases: []string{"v"},
},
},
Action: func(c *cli.Context) error {
if versionFlag {
fmt.Println("0.1.0")
os.Exit(0)
}
// FIXME: What is the right way to print help text and error here?
return nil
},
Commands: commands(),
}
return app
}

func main() {
parsedArgs, err := docopt.ParseDoc(helpText())
bailIfError(err)
// --help is handled by docopt
if parsedArgs["--version"].(bool) {
fmt.Println("0.1.0")
os.Exit(0)
}
if parsedArgs["convert"].(bool) {
bailIfError(convertMain(parsedArgs))
os.Exit(0)
}
if parsedArgs["stats"].(bool) {
bailIfError(statsMain(parsedArgs))
os.Exit(0)
}
if parsedArgs["snapshot"].(bool) {
bailIfError(snapshotMain(parsedArgs))
os.Exit(0)
func fromFlag(storage *string) *cli.StringFlag {
return &cli.StringFlag{
Name: "from",
Usage: "Path to SCIP index file",
Destination: storage,
DefaultText: "index.scip",
}
// Normally, this should be impossible as docopt should properly handle
// incorrect arguments, but might as well exit nicely. 🤷🏽
os.Stderr.WriteString(helpText())
os.Exit(1)
}
Loading

0 comments on commit 5e84217

Please sign in to comment.