-
Notifications
You must be signed in to change notification settings - Fork 121
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cli, config): --func, --check, single contract compilation (#287)
* switch from `args` to the `meow` CLI framework * `tact.config.json` also defines flags to stop compilation after typechecking or generating FunC code * CLI flags override the ones in the `tact.config.json` Co-authored-by: Novus Nota <68142933+novusnota@users.noreply.github.com>
- Loading branch information
Showing
13 changed files
with
311 additions
and
66 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
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 |
---|---|---|
@@ -1,38 +1,144 @@ | ||
#!/usr/bin/env node | ||
const main = require("../dist/node"); | ||
const arg = require("arg"); | ||
|
||
// Resolve arguments | ||
const args = arg({ | ||
"--config": String, | ||
"--project": String, | ||
"--version": Boolean, | ||
}); | ||
|
||
if (args["--version"]) { | ||
console.log("1.2.0"); | ||
return; | ||
} | ||
|
||
if (!args["--config"]) { | ||
console.log("USAGE: tact --config <config_path> [--project <project_name]"); | ||
return; | ||
} | ||
|
||
// Perform compilation | ||
(async () => { | ||
try { | ||
const success = await main.run({ | ||
configPath: args["--config"], | ||
projectNames: args["--project"] ? args["--project"] : [], | ||
}); | ||
// https://nodejs.org/docs/v20.12.1/api/process.html#exit-codes | ||
if (!success) process.exit(30); | ||
} catch (e) { | ||
console.warn( | ||
"Internal compiler error. Please, report it to https://github.com/tact-lang/tact/issues.", | ||
|
||
// @ts-nocheck | ||
const pkg = require("../package.json"); | ||
const main = require("../dist/node.js"); | ||
const meowModule = import("meow"); | ||
|
||
meowModule.then( | ||
/** @param meow {import('meow/build/index')} */ | ||
(meow) => { | ||
const cli = meow.default( | ||
` | ||
Usage | ||
$ tact [...flags] (--config CONFIG | FILE) | ||
Flags | ||
-c, --config CONFIG Specify path to config file (tact.config.json) | ||
-p, --project ...names Build only the specified project name(s) from the config file | ||
--func Output intermediate FunC code and exit | ||
--check Perform syntax and type checking, then exit | ||
-v, --version Print Tact compiler version and exit | ||
-h, --help Display this text and exit | ||
Examples | ||
$ tact --version | ||
${pkg.version} | ||
Learn more about Tact: https://docs.tact-lang.org | ||
Join Telegram group: https://t.me/tactlang | ||
Follow X/Twitter account: https://twitter.com/tact_language`, | ||
{ | ||
importMeta: { | ||
url: new URL("file://" + __dirname + __filename).toString(), | ||
}, | ||
description: `Command-line utility for the Tact compiler:\n${pkg.description}`, | ||
flags: { | ||
config: { | ||
shortFlag: "c", | ||
type: "string", | ||
isRequired: (flags, _) => { | ||
// Require a config when the projects are specified AND version/help are not specified | ||
if ( | ||
flags.projects.length !== 0 && | ||
!flags.version && | ||
!flags.help | ||
) { | ||
return true; | ||
} | ||
// Don't require it otherwise | ||
return false; | ||
}, | ||
}, | ||
projects: { shortFlag: "p", type: "string", isMultiple: true }, | ||
func: { type: "boolean", default: false }, | ||
check: { type: "boolean", default: false }, | ||
version: { shortFlag: "v", type: "boolean" }, | ||
help: { shortFlag: "h", type: "boolean" }, | ||
}, | ||
allowUnknownFlags: false, | ||
}, | ||
); | ||
console.log(e); | ||
process.exit(30); | ||
} | ||
})(); | ||
|
||
// Helper function to write less in following checks | ||
const isEmptyConfigAndInput = () => { | ||
if (cli.flags.config === undefined && cli.input.length === 0) { | ||
return true; | ||
} | ||
return false; | ||
}; | ||
|
||
// Show help regardless of other flags | ||
if (cli.flags.help) { | ||
cli.showHelp(0); | ||
} | ||
|
||
// Show version regardless of other flags | ||
if (cli.flags.version) { | ||
cli.showVersion(); | ||
} | ||
|
||
// Disallow specifying both config or Tact source file at the same time | ||
if (cli.flags.config !== undefined && cli.input.length > 0) { | ||
console.log( | ||
"Error: Both config and Tact file can't be simultaneously specified, pick one!", | ||
); | ||
cli.showHelp(); | ||
} | ||
|
||
// Disallow specifying both --func and --check flags at the same time | ||
if (cli.flags.check && cli.flags.func) { | ||
console.log("Error: Flags --func and --check are mutually exclusive!"); | ||
cli.showHelp(); | ||
} | ||
|
||
// Disallow running --func and --check flags without a config or a file specified | ||
if (isEmptyConfigAndInput() && (cli.flags.check || cli.flags.func)) { | ||
console.log("Error: Either config or Tact file have to be specified!"); | ||
cli.showHelp(); | ||
} | ||
|
||
// Disallow specifying more than one Tact file | ||
if (cli.input.length > 1) { | ||
console.log( | ||
"Error: Only one Tact file can be specified at a time. If you want more, provide a config!", | ||
); | ||
cli.showHelp(); | ||
} | ||
|
||
// Show help when all flags and inputs are empty | ||
// Note, that version/help flags are already processed above and don't need to be mentioned here | ||
if ( | ||
isEmptyConfigAndInput() && | ||
!cli.flags.check && | ||
!cli.flags.func && | ||
cli.flags.projects.length === 0 | ||
) { | ||
cli.showHelp(0); | ||
} | ||
|
||
// Compilation mode | ||
const mode = cli.flags.check | ||
? "checkOnly" | ||
: cli.flags.func | ||
? "funcOnly" | ||
: undefined; | ||
|
||
// TODO: all flags on the cli should take precendence over flags in the config | ||
// Make a nice model for it in the src/node.ts instead of the current mess | ||
// Consider making overwrites right here or something. | ||
|
||
// Main command | ||
main | ||
.run({ | ||
fileName: cli.input.at(0), | ||
configPath: cli.flags.config, | ||
projectNames: cli.flags.projects ?? [], | ||
additionalCliOptions: { mode }, | ||
}) | ||
.then((success) => { | ||
// https://nodejs.org/docs/v20.12.1/api/process.html#exit-codes | ||
process.exit(success ? 0 : 30); | ||
}); | ||
}, | ||
); |
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
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
Oops, something went wrong.