From 6c9ea02ab7e5e1f119040a66c5b5ffbef97bbcb2 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 18 Jan 2023 16:16:18 +0100 Subject: [PATCH 1/4] feat: update node logic --- src/nile/cli.py | 38 ++++++++++++++-------------- src/nile/core/node.py | 29 ++++++++++++++++------ tests/commands/test_node.py | 49 ++++++++++++++++++++++++------------- 3 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/nile/cli.py b/src/nile/cli.py index 457c53bd..8128ee5b 100644 --- a/src/nile/cli.py +++ b/src/nile/cli.py @@ -12,6 +12,7 @@ from nile.core.clean import clean as clean_command from nile.core.compile import compile as compile_command from nile.core.init import init as init_command +from nile.core.node import get_help_message from nile.core.node import node as node_command from nile.core.plugins import load_plugins from nile.core.run import run as run_command @@ -352,28 +353,27 @@ def clean(ctx): clean_command() -@cli.command() -@click.option("--host", default="127.0.0.1") -@click.option("--port", default=5050) -@click.option("--seed", type=int) -@click.option("--lite_mode", is_flag=True) -@enable_stack_trace -def node(ctx, host, port, seed, lite_mode): - """Start StarkNet local network. - - $ nile node - Start StarkNet local network at port 5050 +class NodeCommand(click.Command): + """Command wrapper to override the default help message.""" - $ nile node --host HOST --port 5001 - Start StarkNet network on address HOST listening at port 5001 + def format_help(self, ctx, formatter): + """Help message override.""" + click.echo(get_help_message()) - $ nile node --seed SEED - Start StarkNet local network with seed SEED - $ nile node --lite_mode - Start StarkNet network on lite-mode - """ - node_command(host, port, seed, lite_mode) +@cli.command( + context_settings=dict( + ignore_unknown_options=True, + ), + cls=NodeCommand, +) +@click.option("--host", default="127.0.0.1") +@click.option("--port", default=5050) +@click.argument("node_args", nargs=-1, type=click.UNPROCESSED) +@enable_stack_trace +def node(ctx, host, port, node_args): + """Start StarkNet local network.""" + node_command(host, port, node_args) @cli.command() diff --git a/src/nile/core/node.py b/src/nile/core/node.py index baf4d4b3..dca93794 100644 --- a/src/nile/core/node.py +++ b/src/nile/core/node.py @@ -6,7 +6,7 @@ from nile.common import DEFAULT_GATEWAYS, write_node_json -def node(host="127.0.0.1", port=5050, seed=None, lite_mode=False): +def node(host="127.0.0.1", port=5050, node_args=None): """Start StarkNet local network.""" try: # Save host and port information to be used by other commands @@ -19,13 +19,8 @@ def node(host="127.0.0.1", port=5050, seed=None, lite_mode=False): write_node_json(network, gateway_url) command = ["starknet-devnet", "--host", host, "--port", str(port)] - - if seed is not None: - command.append("--seed") - command.append(str(seed)) - - if lite_mode: - command.append("--lite-mode") + if node_args is not None: + command += list(node_args) # Start network subprocess.check_call(command) @@ -35,3 +30,21 @@ def node(host="127.0.0.1", port=5050, seed=None, lite_mode=False): "\n\n😰 Could not find starknet-devnet, is it installed? Try with:\n" " pip install starknet-devnet" ) + + +def get_help_message(): + """Retrieve and parse the help message from starknet-devnet.""" + base = """ +Start StarkNet local network. + +$ nile node + Start StarkNet local network at port 5050 + +Options: + """ + + raw_message = subprocess.check_output(["starknet-devnet", "--help"]).decode("utf-8") + options_index = raw_message.find("optional arguments:") + options = raw_message[options_index + 19 :] + + return base + options diff --git a/tests/commands/test_node.py b/tests/commands/test_node.py index f05c5787..99c5c80e 100644 --- a/tests/commands/test_node.py +++ b/tests/commands/test_node.py @@ -5,12 +5,12 @@ import pytest -from nile.core.node import node +from nile.core.node import get_help_message, node HOST = "127.0.0.1" PORT = "5050" SEED = "123" -LITE = "--lite-mode" +HELP_OUTPUT = b"optional arguments:\n options" @pytest.fixture(autouse=True) @@ -19,29 +19,44 @@ def tmp_working_dir(monkeypatch, tmp_path): return tmp_path +@pytest.mark.parametrize("host", [HOST]) +@pytest.mark.parametrize("port", [PORT]) @pytest.mark.parametrize( - "args", + "node_args", [ - ({}), - ({"seed": SEED}), - ({"lite_mode": LITE}), - ({"host": HOST, "port": PORT}), - ({"host": HOST, "port": PORT, "seed": SEED, "lite_mode": LITE}), + None, + ("--seed", SEED), + ("--lite-mode"), + ("--fork-network", "alpha-mainnet"), + ("--fork-block", 4), ], ) @patch("nile.core.node.subprocess.check_call") -def test_node_call(mock_subprocess, args): - node(**args) - - command = ["starknet-devnet", "--host", HOST, "--port", PORT] - if "seed" in args: - command.append("--seed") - command.append(SEED) - if "lite_mode" in args: - command.append(LITE) +def test_node_call(mock_subprocess, host, port, node_args): + node(host, port, node_args) + + command = ["starknet-devnet", "--host", host, "--port", port] + if node_args is not None: + command += list(node_args) mock_subprocess.assert_called_once_with(command) +@patch("nile.core.node.subprocess.check_output", return_value=HELP_OUTPUT) +def test_node_help_message(mock_subprocess): + base = """ +Start StarkNet local network. + +$ nile node + Start StarkNet local network at port 5050 + +Options: + """ + + help_message = get_help_message() + + assert help_message == base + "\n options" + + @patch("nile.core.node.subprocess.check_call") def test_node_error(mock_subprocess, caplog): logging.getLogger().setLevel(logging.INFO) From cfd8ab814ff19a30a3190c6ae74400f357761f63 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Wed, 18 Jan 2023 16:38:34 +0100 Subject: [PATCH 2/4] feat: update docs --- docs/modules/ROOT/pages/cli.adoc | 14 ++++++++------ docs/modules/ROOT/pages/index.adoc | 3 +++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/modules/ROOT/pages/cli.adoc b/docs/modules/ROOT/pages/cli.adoc index 2f484dc4..288c130e 100644 --- a/docs/modules/ROOT/pages/cli.adoc +++ b/docs/modules/ROOT/pages/cli.adoc @@ -2,6 +2,7 @@ :cairo-lang: link:https://github.com/starkware-libs/cairo-lang[cairo-lang] :imports: link:https://starknet.io/docs/how_cairo_works/imports.html?highlight=cairo%20path#import-search-paths[Import search paths] :status: link:#status[status] +:devnet-doc: link:https://shard-labs.github.io/starknet-devnet/docs/guide/run[starknet-devnet documentation] = CLI Reference @@ -287,6 +288,9 @@ Scaffold a simple Nile project. Run a local {starknet-devnet} node. +NOTE: Accepts all the options that the starknet-devnet node accepts by default. Check the {devnet-doc} for a full +list of them. + ===== Options - `*--host*` @@ -297,12 +301,10 @@ Defaults to 127.0.0.1 (use the address the program outputs on start). - `*--port*` + Specify the port to listen at. Defaults to 5050. -- `*--seed*` -+ -Specify the seed for randomness of accounts to be deployed. -- `*--lite-mode*` -+ -Applies all lite-mode optimizations by disabling features such as block hash and deploy hash calculation. + +===== Starknet Devnet Options + +- _This command exposes all the functionalities provided within the starknet-devnet node, like forking mainnet, or specifying the contract class to be used for predeployed accounts. Check the {devnet-doc} for a full description of the arguments._ === `compile` diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc index e330f868..fa439970 100644 --- a/docs/modules/ROOT/pages/index.adoc +++ b/docs/modules/ROOT/pages/index.adoc @@ -1,4 +1,5 @@ :pyenv: link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.4.0b/src/openzeppelin/access/ownable/library.cairo[pyenv] +:devnet-doc: link:https://shard-labs.github.io/starknet-devnet/docs/guide/run[starknet-devnet documentation] = Overview @@ -117,6 +118,8 @@ Use `nile node` to run a local devnet node for development. nile node ---- +NOTE: This command exposes all the functionalities provided within the starknet-devnet node, like forking mainnet, or specifying the contract class to be used for predeployed accounts. Check the {devnet-doc} for a full description of the arguments. + ==== Deploying an account . Add an environment variable with the account's private key to the `.env` file. From 0a4bba6ac253b48721f4a017382c232655e20672 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Thu, 19 Jan 2023 15:16:21 +0100 Subject: [PATCH 3/4] feat: apply updates from review --- docs/modules/ROOT/pages/cli.adoc | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/docs/modules/ROOT/pages/cli.adoc b/docs/modules/ROOT/pages/cli.adoc index 288c130e..93559554 100644 --- a/docs/modules/ROOT/pages/cli.adoc +++ b/docs/modules/ROOT/pages/cli.adoc @@ -288,21 +288,7 @@ Scaffold a simple Nile project. Run a local {starknet-devnet} node. -NOTE: Accepts all the options that the starknet-devnet node accepts by default. Check the {devnet-doc} for a full -list of them. - -===== Options - -- `*--host*` -+ -Specify the address to listen at. -+ -Defaults to 127.0.0.1 (use the address the program outputs on start). -- `*--port*` -+ -Specify the port to listen at. Defaults to 5050. - -===== Starknet Devnet Options +===== StarkNet Devnet Options - _This command exposes all the functionalities provided within the starknet-devnet node, like forking mainnet, or specifying the contract class to be used for predeployed accounts. Check the {devnet-doc} for a full description of the arguments._ From e3abdf3ffbcd3126b096e23ff8892d20f2f64167 Mon Sep 17 00:00:00 2001 From: Eric Nordelo Date: Thu, 19 Jan 2023 19:22:33 +0100 Subject: [PATCH 4/4] feat: add -h option --- src/nile/cli.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/nile/cli.py b/src/nile/cli.py index 8128ee5b..9fc36439 100644 --- a/src/nile/cli.py +++ b/src/nile/cli.py @@ -32,6 +32,7 @@ logging.basicConfig(level=logging.DEBUG, format="%(message)s") logging.getLogger("asyncio").setLevel(logging.WARNING) +CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) NETWORKS = ("localhost", "integration", "goerli", "goerli2", "mainnet") @@ -105,7 +106,7 @@ def _validate_network(_ctx, _param, value): raise click.BadParameter(f"'{value}'. Use one of {NETWORKS}") -@click.group() +@click.group(context_settings=CONTEXT_SETTINGS) @click.option("--stack_trace/--no_stack_trace", default=False) @click.pass_context def cli(ctx, stack_trace):