diff --git a/.github/workflows/release-plz.yml b/.github/workflows/release-plz.yml index c9f20c24..631e5b0d 100644 --- a/.github/workflows/release-plz.yml +++ b/.github/workflows/release-plz.yml @@ -15,9 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 + submodules: recursive token: ${{ secrets.MY_GITHUB_TOKEN }} - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3e516a70..cbbe741e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: [ main ] + branches: [main] pull_request: jobs: @@ -15,7 +15,9 @@ jobs: steps: - name: Checkout Sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 + with: + submodules: recursive - name: Get MSRV run: | @@ -45,7 +47,9 @@ jobs: steps: - name: Checkout Sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 + with: + submodules: recursive - name: "Install stable Rust toolchain" uses: actions-rs/toolchain@v1 @@ -69,7 +73,9 @@ jobs: steps: - name: Checkout Sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 + with: + submodules: recursive - name: Check Formatting run: cargo fmt -- --check @@ -86,7 +92,9 @@ jobs: steps: - name: Checkout Sources - uses: actions/checkout@v2 + uses: actions/checkout@v4 + with: + submodules: recursive - name: Install Audit Tool run: cargo install cargo-audit diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..20e41d75 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cargo-near/src/commands/new/new-project-template"] + path = cargo-near/src/commands/new/new-project-template + url = https://github.com/near/cargo-near-new-project-template diff --git a/Cargo.lock b/Cargo.lock index 8bbf3cf9..8a845403 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5378,9 +5378,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] diff --git a/README.md b/README.md index 4199e424..20eb493f 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,12 @@ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as below, without any additional terms or conditions. +Note, fetching the git repository of cargo-near, don't forget to pull the submodules after cloning: + +```console +git submodule update --init +``` + ## License Licensed under either of diff --git a/cargo-near/src/commands/mod.rs b/cargo-near/src/commands/mod.rs index 691ffca3..6594afde 100644 --- a/cargo-near/src/commands/mod.rs +++ b/cargo-near/src/commands/mod.rs @@ -4,6 +4,7 @@ pub mod abi_command; pub mod build_command; pub mod create_dev_account; pub mod deploy; +pub mod new; #[derive(Debug, EnumDiscriminants, Clone, interactive_clap::InteractiveClap)] #[interactive_clap(context = near_cli_rs::GlobalContext)] @@ -12,6 +13,11 @@ pub mod deploy; #[non_exhaustive] /// What are you up to? (select one of the options with the up-down arrows on your keyboard and press Enter) pub enum NearCommand { + #[strum_discriminants(strum( + message = "new - Initializes a new project to create a contract" + ))] + /// Initializes a new project to create a contract + New(self::new::New), #[strum_discriminants(strum( message = "build - Build a NEAR contract and optionally embed ABI" ))] diff --git a/cargo-near/src/commands/new/mod.rs b/cargo-near/src/commands/new/mod.rs new file mode 100644 index 00000000..af02511f --- /dev/null +++ b/cargo-near/src/commands/new/mod.rs @@ -0,0 +1,103 @@ +use color_eyre::eyre::{ContextCompat, WrapErr}; + +#[derive(Debug, Clone, interactive_clap::InteractiveClap)] +#[interactive_clap(input_context = near_cli_rs::GlobalContext)] +#[interactive_clap(output_context = NewContext)] +pub struct New { + /// Enter a new project name (path to the project) to create a contract: + pub project_dir: near_cli_rs::types::path_buf::PathBuf, +} + +#[derive(Debug, Clone)] +pub struct NewContext; + +impl NewContext { + pub fn from_previous_context( + _previous_context: near_cli_rs::GlobalContext, + scope: &::InteractiveClapContextScope, + ) -> color_eyre::eyre::Result { + let project_dir: &std::path::Path = scope.project_dir.as_ref(); + let project_name = project_dir + .file_name() + .wrap_err("Could not extract project name from project path")? + .to_str() + .wrap_err("Project name has to be a valid UTF-8 string")?; + + for new_project_file in NEW_PROJECT_FILES { + let new_file_path = project_dir.join(new_project_file.file_path); + std::fs::create_dir_all(new_file_path.parent().wrap_err_with(|| { + format!("Impossible to get parent for `{}`", new_file_path.display()) + })?)?; + std::fs::write( + &new_file_path, + new_project_file + .content + .replace("cargo-near-new-project-name", project_name), + ) + .wrap_err_with(|| format!("Failed to write to file: {}", new_file_path.display()))?; + } + + std::process::Command::new("git") + .arg("init") + .current_dir(project_dir) + .output() + .wrap_err("Failed to execute process: `git init`")?; + + println!("New project is created at '{}'\n", project_dir.display()); + println!("Now you can build, deploy, and finish CI setup for automatic deployment:"); + println!("1. `cargo near build`"); + println!("2. `cargo test`"); + println!("3. `cargo near deploy`"); + println!("4. Configure `NEAR_CONTRACT_STAGING_*` and `NEAR_CONTRACT_PRODUCTION_*` variables and secrets on GitHub to enable automatic deployment to staging and production. See more details in `.github/workflow/*` files."); + + Ok(Self) + } +} + +struct NewProjectFile { + file_path: &'static str, + content: &'static str, +} + +const NEW_PROJECT_FILES: &[NewProjectFile] = &[ + NewProjectFile { + file_path: ".github/workflows/deploy-production.yml", + content: include_str!("new-project-template/.github/workflows/deploy-production.yml"), + }, + NewProjectFile { + file_path: ".github/workflows/deploy-staging.yml", + content: include_str!("new-project-template/.github/workflows/deploy-staging.yml"), + }, + NewProjectFile { + file_path: ".github/workflows/test.yml", + content: include_str!("new-project-template/.github/workflows/test.yml"), + }, + NewProjectFile { + file_path: ".github/workflows/undeploy-staging.yml", + content: include_str!("new-project-template/.github/workflows/undeploy-staging.yml"), + }, + NewProjectFile { + file_path: "src/lib.rs", + content: include_str!("new-project-template/src/lib.rs"), + }, + NewProjectFile { + file_path: "tests/test_basics.rs", + content: include_str!("new-project-template/tests/test_basics.rs"), + }, + NewProjectFile { + file_path: ".gitignore", + content: include_str!("new-project-template/.gitignore"), + }, + NewProjectFile { + file_path: "Cargo.toml", + content: include_str!("new-project-template/Cargo.toml"), + }, + NewProjectFile { + file_path: "README.md", + content: include_str!("new-project-template/README.md"), + }, + NewProjectFile { + file_path: "rust-toolchain.toml", + content: include_str!("new-project-template/rust-toolchain.toml"), + }, +]; diff --git a/cargo-near/src/commands/new/new-project-template b/cargo-near/src/commands/new/new-project-template new file mode 160000 index 00000000..9d53496b --- /dev/null +++ b/cargo-near/src/commands/new/new-project-template @@ -0,0 +1 @@ +Subproject commit 9d53496b4d2bd207d5e815e350a7c28696592068 diff --git a/cargo-near/src/util/mod.rs b/cargo-near/src/util/mod.rs index 5c9ec441..c425eced 100644 --- a/cargo-near/src/util/mod.rs +++ b/cargo-near/src/util/mod.rs @@ -213,12 +213,12 @@ pub(crate) fn compile_project( let dylib_files = compile_artifact .filenames .iter() - .cloned() .filter(|f| { f.extension() .map(|e| e == artifact_extension) .unwrap_or(false) }) + .cloned() .collect(); let mut dylib_files_iter = Vec::into_iter(dylib_files); match (dylib_files_iter.next(), dylib_files_iter.next()) { diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 45554663..de023253 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -74,8 +74,7 @@ macro_rules! invoke_cargo_near { }; cargo_near::commands::build_command::build::run(args)?; }, - Some(cargo_near::commands::CliNearCommand::CreateDevAccount(_)) => todo!(), - Some(cargo_near::commands::CliNearCommand::Deploy(_)) => todo!(), + Some(_) => todo!(), None => () }