cli: autocomplete output filenames for contract compile cmd

It's enough to specify the input file only to get the standard output:
```
$ neo-go contract compile -i ./1-print/1-print.go
$ neo-go contract compile -i ./1-print/
```

Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
This commit is contained in:
Anna Shaleva 2023-05-12 13:49:31 +03:00
parent 3dbb733324
commit a2449ae8ae
3 changed files with 58 additions and 4 deletions

View file

@ -237,7 +237,8 @@ func TestContractInitAndCompile(t *testing.T) {
e.RunWithError(t, "neo-go", "contract", "init", "--name", ctrPath)
})
srcPath := filepath.Join(ctrPath, "main.go")
ctrRootPath := filepath.Join(ctrPath, "main")
srcPath := ctrRootPath + ".go"
cfgPath := filepath.Join(ctrPath, "neo-go.yml")
nefPath := filepath.Join(tmpDir, "testcontract.nef")
manifestPath := filepath.Join(tmpDir, "testcontract.manifest.json")
@ -288,6 +289,19 @@ func TestContractInitAndCompile(t *testing.T) {
e.Run(t, append(cmd, "--verbose")...)
e.CheckNextLine(t, "^[0-9a-hA-H]+$")
})
t.Run("autocomplete outputs", func(t *testing.T) {
cfg, err := os.ReadFile(cfgPath)
require.NoError(t, err)
require.NoError(t, os.WriteFile(filepath.Join(ctrPath, "main.yml"), cfg, os.ModePerm))
e.Run(t, "neo-go", "contract", "compile", "--in", srcPath)
defaultNefPath := ctrRootPath + ".nef"
defaultManifestPath := ctrRootPath + ".manifest.json"
defaultBindingsPath := ctrRootPath + ".bindings.yml"
require.FileExists(t, defaultNefPath)
require.FileExists(t, defaultManifestPath)
require.FileExists(t, defaultBindingsPath)
})
}
// Checks that error is returned if GAS available for test-invoke exceeds

View file

@ -126,11 +126,18 @@ func NewCommands() []cli.Command {
Name: "compile",
Usage: "compile a smart contract to a .nef file",
UsageText: "neo-go contract compile -i path [-o nef] [-v] [-d] [-m manifest] [-c yaml] [--bindings file] [--no-standards] [--no-events] [--no-permissions]",
Description: `Compiles given smart contract to a .nef file and emits other associated
information (manifest, bindings configuration, debug information files) if
asked to. If none of --out, --manifest, --config, --bindings flags are specified,
then the output filenames for these flags will be guessed using the contract
name or path provided via --in option by trimming/adding corresponding suffixes
to the common part of the path. In the latter case the configuration filepath
will be guessed from the --in option using the same rule."`,
Action: contractCompile,
Flags: []cli.Flag{
cli.StringFlag{
Name: "in, i",
Usage: "Input file for the smart contract to be compiled",
Usage: "Input file for the smart contract to be compiled (*.go file or directory)",
},
cli.StringFlag{
Name: "out, o",
@ -400,13 +407,38 @@ func contractCompile(ctx *cli.Context) error {
manifestFile := ctx.String("manifest")
confFile := ctx.String("config")
debugFile := ctx.String("debug")
out := ctx.String("out")
bindings := ctx.String("bindings")
if len(confFile) == 0 && (len(manifestFile) != 0 || len(debugFile) != 0 || len(bindings) != 0) {
return cli.NewExitError(errNoConfFile, 1)
}
autocomplete := len(manifestFile) == 0 &&
len(confFile) == 0 &&
len(out) == 0 &&
len(bindings) == 0
if autocomplete {
var root string
fileInfo, err := os.Stat(src)
if err != nil {
return cli.NewExitError(fmt.Errorf("failed to stat source file or directory: %w", err), 1)
}
if fileInfo.IsDir() {
base := filepath.Base(fileInfo.Name())
if base == string(filepath.Separator) {
base = "contract"
}
root = filepath.Join(src, base)
} else {
root = strings.TrimSuffix(src, ".go")
}
manifestFile = root + ".manifest.json"
confFile = root + ".yml"
out = root + ".nef"
bindings = root + ".bindings.yml"
}
o := &compiler.Options{
Outfile: ctx.String("out"),
Outfile: out,
DebugInfo: debugFile,
ManifestFile: manifestFile,

View file

@ -80,6 +80,14 @@ $ go mod tidy
By default, the filename will be the name of your .go file with the .nef
extension, the file will be located in the same directory with your Go contract.
Along with the compiled contract and if the contract configuration file
`contract.yml` exist, the following files will be generated:
* smart-contract manifest file (`contract.manifest.json`) that is needed to deploy
the contract to the network
* bindings configuration file (`contract.bindings.yml`) that is needed to generate
code-based or RPC contract bindings
All of them will be located in the same directory with your Go contract.
If you want another location for your compiled contract:
```