From 71c33f25b2c3c8e0279215cd6cc72a3542fd0d88 Mon Sep 17 00:00:00 2001 From: Altynbek Orumbayev Date: Fri, 23 Aug 2024 19:09:24 +0200 Subject: [PATCH 1/2] feat: adding ability to execute with extra args (backwards compatible) --- .github/workflows/check-python.yaml | 2 +- .../README.md | 6 ++-- .../pyproject.toml | 1 + .../smart_contracts/__main__.py | 18 ++++++++--- .../README.md | 6 ++-- .../pyproject.toml | 1 + .../smart_contracts/__main__.py | 14 +++++++-- .../smart_contracts/index.ts | 31 +++++++++++++------ .../README.md | 6 ++-- .../pyproject.toml | 1 + .../smart_contracts/__main__.py | 18 ++++++++--- .../README.md | 6 ++-- .../pyproject.toml | 1 + .../smart_contracts/__main__.py | 14 +++++++-- .../smart_contracts/index.ts | 31 +++++++++++++------ examples/production_python/README.md | 6 ++-- examples/production_python/pyproject.toml | 1 + .../smart_contracts/__main__.py | 18 ++++++++--- examples/starter_python/README.md | 6 ++-- examples/starter_python/pyproject.toml | 1 + .../smart_contracts/__main__.py | 18 ++++++++--- template_content/README.md.jinja | 6 ++-- template_content/pyproject.toml.jinja | 1 + .../smart_contracts/__main__.py.jinja | 18 ++++++++--- ...= 'typescript' %}index.ts{% endif %}.jinja | 31 +++++++++++++------ tests/test_generators.py | 13 ++++++-- 26 files changed, 200 insertions(+), 75 deletions(-) diff --git a/.github/workflows/check-python.yaml b/.github/workflows/check-python.yaml index cc493db..722c9af 100644 --- a/.github/workflows/check-python.yaml +++ b/.github/workflows/check-python.yaml @@ -14,7 +14,7 @@ jobs: run: pipx install poetry - name: Install algokit - run: pipx install algokit + run: pipx install https://github.com/algorandfoundation/algokit-cli/releases/download/v2.3.0-beta.1/algokit-2.3.0b1-py3-none-any.whl - name: Run algokit localnet run: algokit localnet start diff --git a/examples/generators/production_python_smart_contract_python/README.md b/examples/generators/production_python_smart_contract_python/README.md index a1878d1..b41dabd 100644 --- a/examples/generators/production_python_smart_contract_python/README.md +++ b/examples/generators/production_python_smart_contract_python/README.md @@ -35,8 +35,10 @@ Run the following commands within the project folder: #### Terminal Directly manage and interact with your project using AlgoKit commands: -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. +1. **Build Contracts**: `algokit project run build` compiles all smart contracts. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project run build -- hello_world` will only build the `hello_world` contract. +2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project deploy localnet -- hello_world` will only deploy the `hello_world` contract. #### VS Code For a seamless experience with breakpoint debugging and other features: diff --git a/examples/generators/production_python_smart_contract_python/pyproject.toml b/examples/generators/production_python_smart_contract_python/pyproject.toml index 720fa10..2b718d1 100644 --- a/examples/generators/production_python_smart_contract_python/pyproject.toml +++ b/examples/generators/production_python_smart_contract_python/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "Algorand smart contracts" authors = ["None "] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.12" diff --git a/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py b/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py index 120fdfe..4e15bf3 100644 --- a/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py +++ b/examples/generators/production_python_smart_contract_python/smart_contracts/__main__.py @@ -24,15 +24,21 @@ root_path = Path(__file__).parent -def main(action: str) -> None: +def main(action: str, contract_name: str | None = None) -> None: artifact_path = root_path / "artifacts" + + # Filter contracts if a specific contract name is provided + filtered_contracts = [ + c for c in contracts if contract_name is None or c.name == contract_name + ] + match action: case "build": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") build(artifact_path / contract.name, contract.path) case "deploy": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name app_spec_file_name = next( @@ -49,7 +55,7 @@ def main(action: str) -> None: if contract.deploy: deploy(app_spec_path, contract.deploy) case "all": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") app_spec_path = build(artifact_path / contract.name, contract.path) if contract.deploy: @@ -58,7 +64,9 @@ def main(action: str) -> None: if __name__ == "__main__": - if len(sys.argv) > 1: + if len(sys.argv) > 2: + main(sys.argv[1], sys.argv[2]) + elif len(sys.argv) > 1: main(sys.argv[1]) else: main("all") diff --git a/examples/generators/production_python_smart_contract_typescript/README.md b/examples/generators/production_python_smart_contract_typescript/README.md index c73ea33..28c68bb 100644 --- a/examples/generators/production_python_smart_contract_typescript/README.md +++ b/examples/generators/production_python_smart_contract_typescript/README.md @@ -35,8 +35,10 @@ Run the following commands within the project folder: #### Terminal Directly manage and interact with your project using AlgoKit commands: -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. +1. **Build Contracts**: `algokit project run build` compiles all smart contracts. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project run build -- hello_world` will only build the `hello_world` contract. +2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project deploy localnet -- hello_world` will only deploy the `hello_world` contract. #### VS Code For a seamless experience with breakpoint debugging and other features: diff --git a/examples/generators/production_python_smart_contract_typescript/pyproject.toml b/examples/generators/production_python_smart_contract_typescript/pyproject.toml index ce0288e..3231b7d 100644 --- a/examples/generators/production_python_smart_contract_typescript/pyproject.toml +++ b/examples/generators/production_python_smart_contract_typescript/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "Algorand smart contracts" authors = ["None "] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.12" diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py b/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py index 6cf51e4..62fadcd 100644 --- a/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py +++ b/examples/generators/production_python_smart_contract_typescript/smart_contracts/__main__.py @@ -18,17 +18,25 @@ root_path = Path(__file__).parent -def main(action: str) -> None: +def main(action: str, contract_name: str | None = None) -> None: artifact_path = root_path / "artifacts" + + # Filter contracts if a specific contract name is provided + filtered_contracts = [ + c for c in contracts if contract_name is None or c.name == contract_name + ] + match action: case "build": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") build(artifact_path / contract.name, contract.path) if __name__ == "__main__": - if len(sys.argv) > 1: + if len(sys.argv) > 2: + main(sys.argv[1], sys.argv[2]) + elif len(sys.argv) > 1: main(sys.argv[1]) else: main("build") diff --git a/examples/generators/production_python_smart_contract_typescript/smart_contracts/index.ts b/examples/generators/production_python_smart_contract_typescript/smart_contracts/index.ts index af40ab4..6955e33 100644 --- a/examples/generators/production_python_smart_contract_typescript/smart_contracts/index.ts +++ b/examples/generators/production_python_smart_contract_typescript/smart_contracts/index.ts @@ -20,28 +20,41 @@ async function importDeployerIfExists(dir: string) { const deployerPath = path.resolve(dir, 'deploy-config') if (fs.existsSync(deployerPath + '.ts') || fs.existsSync(deployerPath + '.js')) { const deployer = await import(deployerPath) - return deployer.deploy + return { ...deployer, name: path.basename(dir) } } + return null } // get a list of all deployers from the subdirectories async function getDeployers() { - const directories = fs.readdirSync(baseDir, { withFileTypes: true }) - .filter(dirent => dirent.isDirectory()) - .map(dirent => path.resolve(baseDir, dirent.name)) + const directories = fs + .readdirSync(baseDir, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => path.resolve(baseDir, dirent.name)) - return Promise.all(directories.map(importDeployerIfExists)) + const deployers = await Promise.all(directories.map(importDeployerIfExists)) + return deployers.filter((deployer) => deployer !== null) // Filter out null values } // execute all the deployers (async () => { - const contractDeployers = (await getDeployers()).filter(Boolean) + const contractName = process.argv.length > 2 ? process.argv[2] : undefined + const contractDeployers = await getDeployers() + + const filteredDeployers = contractName + ? contractDeployers.filter(deployer => deployer.name === contractName) + : contractDeployers + + if (contractName && filteredDeployers.length === 0) { + console.warn(`No deployer found for contract name: ${contractName}`) + return + } - for (const deployer of contractDeployers) { + for (const deployer of filteredDeployers) { try { - await deployer() + await deployer.deploy() } catch (e) { - console.error(e) + console.error(`Error deploying ${deployer.name}:`, e) } } })() diff --git a/examples/generators/starter_python_smart_contract_python/README.md b/examples/generators/starter_python_smart_contract_python/README.md index 25fe33c..fb1bc17 100644 --- a/examples/generators/starter_python_smart_contract_python/README.md +++ b/examples/generators/starter_python_smart_contract_python/README.md @@ -35,8 +35,10 @@ Run the following commands within the project folder: #### Terminal Directly manage and interact with your project using AlgoKit commands: -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. +1. **Build Contracts**: `algokit project run build` compiles all smart contracts. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project run build -- hello_world` will only build the `hello_world` contract. +2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project deploy localnet -- hello_world` will only deploy the `hello_world` contract. #### VS Code For a seamless experience with breakpoint debugging and other features: diff --git a/examples/generators/starter_python_smart_contract_python/pyproject.toml b/examples/generators/starter_python_smart_contract_python/pyproject.toml index eb5d076..7ab3fc2 100644 --- a/examples/generators/starter_python_smart_contract_python/pyproject.toml +++ b/examples/generators/starter_python_smart_contract_python/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "Algorand smart contracts" authors = ["None "] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.12" diff --git a/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py b/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py index 120fdfe..4e15bf3 100644 --- a/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py +++ b/examples/generators/starter_python_smart_contract_python/smart_contracts/__main__.py @@ -24,15 +24,21 @@ root_path = Path(__file__).parent -def main(action: str) -> None: +def main(action: str, contract_name: str | None = None) -> None: artifact_path = root_path / "artifacts" + + # Filter contracts if a specific contract name is provided + filtered_contracts = [ + c for c in contracts if contract_name is None or c.name == contract_name + ] + match action: case "build": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") build(artifact_path / contract.name, contract.path) case "deploy": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name app_spec_file_name = next( @@ -49,7 +55,7 @@ def main(action: str) -> None: if contract.deploy: deploy(app_spec_path, contract.deploy) case "all": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") app_spec_path = build(artifact_path / contract.name, contract.path) if contract.deploy: @@ -58,7 +64,9 @@ def main(action: str) -> None: if __name__ == "__main__": - if len(sys.argv) > 1: + if len(sys.argv) > 2: + main(sys.argv[1], sys.argv[2]) + elif len(sys.argv) > 1: main(sys.argv[1]) else: main("all") diff --git a/examples/generators/starter_python_smart_contract_typescript/README.md b/examples/generators/starter_python_smart_contract_typescript/README.md index edffbe4..81c6bf4 100644 --- a/examples/generators/starter_python_smart_contract_typescript/README.md +++ b/examples/generators/starter_python_smart_contract_typescript/README.md @@ -35,8 +35,10 @@ Run the following commands within the project folder: #### Terminal Directly manage and interact with your project using AlgoKit commands: -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. +1. **Build Contracts**: `algokit project run build` compiles all smart contracts. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project run build -- hello_world` will only build the `hello_world` contract. +2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project deploy localnet -- hello_world` will only deploy the `hello_world` contract. #### VS Code For a seamless experience with breakpoint debugging and other features: diff --git a/examples/generators/starter_python_smart_contract_typescript/pyproject.toml b/examples/generators/starter_python_smart_contract_typescript/pyproject.toml index 5633426..8255303 100644 --- a/examples/generators/starter_python_smart_contract_typescript/pyproject.toml +++ b/examples/generators/starter_python_smart_contract_typescript/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "Algorand smart contracts" authors = ["None "] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.12" diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py index 6cf51e4..62fadcd 100644 --- a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py +++ b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/__main__.py @@ -18,17 +18,25 @@ root_path = Path(__file__).parent -def main(action: str) -> None: +def main(action: str, contract_name: str | None = None) -> None: artifact_path = root_path / "artifacts" + + # Filter contracts if a specific contract name is provided + filtered_contracts = [ + c for c in contracts if contract_name is None or c.name == contract_name + ] + match action: case "build": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") build(artifact_path / contract.name, contract.path) if __name__ == "__main__": - if len(sys.argv) > 1: + if len(sys.argv) > 2: + main(sys.argv[1], sys.argv[2]) + elif len(sys.argv) > 1: main(sys.argv[1]) else: main("build") diff --git a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/index.ts b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/index.ts index af40ab4..6955e33 100644 --- a/examples/generators/starter_python_smart_contract_typescript/smart_contracts/index.ts +++ b/examples/generators/starter_python_smart_contract_typescript/smart_contracts/index.ts @@ -20,28 +20,41 @@ async function importDeployerIfExists(dir: string) { const deployerPath = path.resolve(dir, 'deploy-config') if (fs.existsSync(deployerPath + '.ts') || fs.existsSync(deployerPath + '.js')) { const deployer = await import(deployerPath) - return deployer.deploy + return { ...deployer, name: path.basename(dir) } } + return null } // get a list of all deployers from the subdirectories async function getDeployers() { - const directories = fs.readdirSync(baseDir, { withFileTypes: true }) - .filter(dirent => dirent.isDirectory()) - .map(dirent => path.resolve(baseDir, dirent.name)) + const directories = fs + .readdirSync(baseDir, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => path.resolve(baseDir, dirent.name)) - return Promise.all(directories.map(importDeployerIfExists)) + const deployers = await Promise.all(directories.map(importDeployerIfExists)) + return deployers.filter((deployer) => deployer !== null) // Filter out null values } // execute all the deployers (async () => { - const contractDeployers = (await getDeployers()).filter(Boolean) + const contractName = process.argv.length > 2 ? process.argv[2] : undefined + const contractDeployers = await getDeployers() + + const filteredDeployers = contractName + ? contractDeployers.filter(deployer => deployer.name === contractName) + : contractDeployers + + if (contractName && filteredDeployers.length === 0) { + console.warn(`No deployer found for contract name: ${contractName}`) + return + } - for (const deployer of contractDeployers) { + for (const deployer of filteredDeployers) { try { - await deployer() + await deployer.deploy() } catch (e) { - console.error(e) + console.error(`Error deploying ${deployer.name}:`, e) } } })() diff --git a/examples/production_python/README.md b/examples/production_python/README.md index db71a01..d2c173e 100644 --- a/examples/production_python/README.md +++ b/examples/production_python/README.md @@ -35,8 +35,10 @@ Run the following commands within the project folder: #### Terminal Directly manage and interact with your project using AlgoKit commands: -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. +1. **Build Contracts**: `algokit project run build` compiles all smart contracts. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project run build -- hello_world` will only build the `hello_world` contract. +2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project deploy localnet -- hello_world` will only deploy the `hello_world` contract. #### VS Code For a seamless experience with breakpoint debugging and other features: diff --git a/examples/production_python/pyproject.toml b/examples/production_python/pyproject.toml index de08a8f..8b8cd87 100644 --- a/examples/production_python/pyproject.toml +++ b/examples/production_python/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "Algorand smart contracts" authors = ["None "] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.12" diff --git a/examples/production_python/smart_contracts/__main__.py b/examples/production_python/smart_contracts/__main__.py index 120fdfe..4e15bf3 100644 --- a/examples/production_python/smart_contracts/__main__.py +++ b/examples/production_python/smart_contracts/__main__.py @@ -24,15 +24,21 @@ root_path = Path(__file__).parent -def main(action: str) -> None: +def main(action: str, contract_name: str | None = None) -> None: artifact_path = root_path / "artifacts" + + # Filter contracts if a specific contract name is provided + filtered_contracts = [ + c for c in contracts if contract_name is None or c.name == contract_name + ] + match action: case "build": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") build(artifact_path / contract.name, contract.path) case "deploy": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name app_spec_file_name = next( @@ -49,7 +55,7 @@ def main(action: str) -> None: if contract.deploy: deploy(app_spec_path, contract.deploy) case "all": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") app_spec_path = build(artifact_path / contract.name, contract.path) if contract.deploy: @@ -58,7 +64,9 @@ def main(action: str) -> None: if __name__ == "__main__": - if len(sys.argv) > 1: + if len(sys.argv) > 2: + main(sys.argv[1], sys.argv[2]) + elif len(sys.argv) > 1: main(sys.argv[1]) else: main("all") diff --git a/examples/starter_python/README.md b/examples/starter_python/README.md index d0f66e1..7733b5e 100644 --- a/examples/starter_python/README.md +++ b/examples/starter_python/README.md @@ -35,8 +35,10 @@ Run the following commands within the project folder: #### Terminal Directly manage and interact with your project using AlgoKit commands: -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. +1. **Build Contracts**: `algokit project run build` compiles all smart contracts. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project run build -- hello_world` will only build the `hello_world` contract. +2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project deploy localnet -- hello_world` will only deploy the `hello_world` contract. #### VS Code For a seamless experience with breakpoint debugging and other features: diff --git a/examples/starter_python/pyproject.toml b/examples/starter_python/pyproject.toml index f419d42..b087982 100644 --- a/examples/starter_python/pyproject.toml +++ b/examples/starter_python/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "Algorand smart contracts" authors = ["None "] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.12" diff --git a/examples/starter_python/smart_contracts/__main__.py b/examples/starter_python/smart_contracts/__main__.py index 120fdfe..4e15bf3 100644 --- a/examples/starter_python/smart_contracts/__main__.py +++ b/examples/starter_python/smart_contracts/__main__.py @@ -24,15 +24,21 @@ root_path = Path(__file__).parent -def main(action: str) -> None: +def main(action: str, contract_name: str | None = None) -> None: artifact_path = root_path / "artifacts" + + # Filter contracts if a specific contract name is provided + filtered_contracts = [ + c for c in contracts if contract_name is None or c.name == contract_name + ] + match action: case "build": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") build(artifact_path / contract.name, contract.path) case "deploy": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name app_spec_file_name = next( @@ -49,7 +55,7 @@ def main(action: str) -> None: if contract.deploy: deploy(app_spec_path, contract.deploy) case "all": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") app_spec_path = build(artifact_path / contract.name, contract.path) if contract.deploy: @@ -58,7 +64,9 @@ def main(action: str) -> None: if __name__ == "__main__": - if len(sys.argv) > 1: + if len(sys.argv) > 2: + main(sys.argv[1], sys.argv[2]) + elif len(sys.argv) > 1: main(sys.argv[1]) else: main("all") diff --git a/template_content/README.md.jinja b/template_content/README.md.jinja index c8e5266..99b904c 100644 --- a/template_content/README.md.jinja +++ b/template_content/README.md.jinja @@ -35,8 +35,10 @@ Run the following commands within the project folder: #### Terminal Directly manage and interact with your project using AlgoKit commands: -1. **Build Contracts**: `algokit project run build` compiles all smart contracts. -2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. +1. **Build Contracts**: `algokit project run build` compiles all smart contracts. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project run build -- hello_world` will only build the `hello_world` contract. +2. **Deploy**: Use `algokit project deploy localnet` to deploy contracts to the local network. You can also specify a specific contract by passing the name of the contract folder as an extra argument. +For example: `algokit project deploy localnet -- hello_world` will only deploy the `hello_world` contract. #### VS Code For a seamless experience with breakpoint debugging and other features: diff --git a/template_content/pyproject.toml.jinja b/template_content/pyproject.toml.jinja index 9f4ef02..9aefc86 100644 --- a/template_content/pyproject.toml.jinja +++ b/template_content/pyproject.toml.jinja @@ -4,6 +4,7 @@ version = "0.1.0" description = "Algorand smart contracts" authors = ["{{ author_name }} <{{ author_email }}>"] readme = "README.md" +package-mode = false [tool.poetry.dependencies] python = "^3.12" diff --git a/template_content/smart_contracts/__main__.py.jinja b/template_content/smart_contracts/__main__.py.jinja index c0b8577..01b25b7 100644 --- a/template_content/smart_contracts/__main__.py.jinja +++ b/template_content/smart_contracts/__main__.py.jinja @@ -26,16 +26,22 @@ load_dotenv() root_path = Path(__file__).parent -def main(action: str) -> None: +def main(action: str, contract_name: str | None = None) -> None: artifact_path = root_path / "artifacts" + + # Filter contracts if a specific contract name is provided + filtered_contracts = [ + c for c in contracts if contract_name is None or c.name == contract_name + ] + match action: case "build": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") build(artifact_path / contract.name, contract.path) {%- if deployment_language == 'python' %} case "deploy": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Deploying app {contract.name}") output_dir = artifact_path / contract.name app_spec_file_name = next( @@ -52,7 +58,7 @@ def main(action: str) -> None: if contract.deploy: deploy(app_spec_path, contract.deploy) case "all": - for contract in contracts: + for contract in filtered_contracts: logger.info(f"Building app at {contract.path}") app_spec_path = build(artifact_path / contract.name, contract.path) if contract.deploy: @@ -62,7 +68,9 @@ def main(action: str) -> None: if __name__ == "__main__": - if len(sys.argv) > 1: + if len(sys.argv) > 2: + main(sys.argv[1], sys.argv[2]) + elif len(sys.argv) > 1: main(sys.argv[1]) else: main("{{ 'all' if deployment_language == 'python' else 'build' }}") diff --git a/template_content/smart_contracts/{% if deployment_language == 'typescript' %}index.ts{% endif %}.jinja b/template_content/smart_contracts/{% if deployment_language == 'typescript' %}index.ts{% endif %}.jinja index af40ab4..6955e33 100644 --- a/template_content/smart_contracts/{% if deployment_language == 'typescript' %}index.ts{% endif %}.jinja +++ b/template_content/smart_contracts/{% if deployment_language == 'typescript' %}index.ts{% endif %}.jinja @@ -20,28 +20,41 @@ async function importDeployerIfExists(dir: string) { const deployerPath = path.resolve(dir, 'deploy-config') if (fs.existsSync(deployerPath + '.ts') || fs.existsSync(deployerPath + '.js')) { const deployer = await import(deployerPath) - return deployer.deploy + return { ...deployer, name: path.basename(dir) } } + return null } // get a list of all deployers from the subdirectories async function getDeployers() { - const directories = fs.readdirSync(baseDir, { withFileTypes: true }) - .filter(dirent => dirent.isDirectory()) - .map(dirent => path.resolve(baseDir, dirent.name)) + const directories = fs + .readdirSync(baseDir, { withFileTypes: true }) + .filter((dirent) => dirent.isDirectory()) + .map((dirent) => path.resolve(baseDir, dirent.name)) - return Promise.all(directories.map(importDeployerIfExists)) + const deployers = await Promise.all(directories.map(importDeployerIfExists)) + return deployers.filter((deployer) => deployer !== null) // Filter out null values } // execute all the deployers (async () => { - const contractDeployers = (await getDeployers()).filter(Boolean) + const contractName = process.argv.length > 2 ? process.argv[2] : undefined + const contractDeployers = await getDeployers() + + const filteredDeployers = contractName + ? contractDeployers.filter(deployer => deployer.name === contractName) + : contractDeployers + + if (contractName && filteredDeployers.length === 0) { + console.warn(`No deployer found for contract name: ${contractName}`) + return + } - for (const deployer of contractDeployers) { + for (const deployer of filteredDeployers) { try { - await deployer() + await deployer.deploy() } catch (e) { - console.error(e) + console.error(`Error deploying ${deployer.name}:`, e) } } })() diff --git a/tests/test_generators.py b/tests/test_generators.py index d3314e3..c638b3f 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -20,9 +20,18 @@ } config_path = Path(__file__).parent.parent / "pyproject.toml" BUILD_ARGS = ["algokit", "project", "run", "build"] +BUILD_SINGLE_CONTRACT_ARGS = ["algokit", "project", "run", "build", "--", "hello_world"] TEST_ARGS = ["algokit", "project", "run", "test"] LINT_ARGS = ["algokit", "project", "run", "lint"] DEPLOY_ARGS = ["algokit", "project", "deploy", "localnet"] +DEPLOY_SINGLE_CONTRACT_ARGS = [ + "algokit", + "project", + "deploy", + "localnet", + "--", + "hello_world", +] def _load_copier_yaml(path: Path) -> dict[str, str | bool | dict]: @@ -124,11 +133,11 @@ def check_codebase(working_dir: Path, test_name: str) -> subprocess.CompletedPro content = src_path_pattern.sub("_src_path: ", content) copier_answers.write_text(content, "utf-8") - check_args = [BUILD_ARGS] + check_args = [BUILD_ARGS, BUILD_SINGLE_CONTRACT_ARGS] processed_questions = _load_copier_yaml(copier_answers) if processed_questions["preset_name"] == "production": - check_args += [LINT_ARGS, TEST_ARGS, DEPLOY_ARGS] + check_args += [LINT_ARGS, TEST_ARGS, DEPLOY_SINGLE_CONTRACT_ARGS, DEPLOY_ARGS] for check_arg in check_args: result = subprocess.run( From b91ad0b105a088ed415e8268bbf0c9647e7a8853 Mon Sep 17 00:00:00 2001 From: Altynbek Orumbayev Date: Fri, 23 Aug 2024 20:05:05 +0200 Subject: [PATCH 2/2] cI: reverting algokit version --- .github/workflows/check-python.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/check-python.yaml b/.github/workflows/check-python.yaml index 722c9af..cc493db 100644 --- a/.github/workflows/check-python.yaml +++ b/.github/workflows/check-python.yaml @@ -14,7 +14,7 @@ jobs: run: pipx install poetry - name: Install algokit - run: pipx install https://github.com/algorandfoundation/algokit-cli/releases/download/v2.3.0-beta.1/algokit-2.3.0b1-py3-none-any.whl + run: pipx install algokit - name: Run algokit localnet run: algokit localnet start