Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: New command to initialize a new smart contract project #117

Merged
merged 10 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI

on:
push:
branches: [ main ]
branches: [main]
pull_request:

jobs:
Expand All @@ -15,7 +15,9 @@ jobs:

steps:
- name: Checkout Sources
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: recursive

- name: Get MSRV
run: |
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -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
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions cargo-near/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -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"
))]
Expand Down
103 changes: 103 additions & 0 deletions cargo-near/src/commands/new/mod.rs
Original file line number Diff line number Diff line change
@@ -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: &<New as interactive_clap::ToInteractiveClapContextScope>::InteractiveClapContextScope,
) -> color_eyre::eyre::Result<Self> {
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"),
},
];
1 change: 1 addition & 0 deletions cargo-near/src/commands/new/new-project-template
Submodule new-project-template added at 9d5349
Loading