Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
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.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ members = ["crates/publish_lib", "crates/cli"]
resolver = "2"

[workspace.package]
version = "0.12.0"
version = "0.13.0"
edition = "2024"
authors = ["The Tari Development Community"]
repository = "https://github.com/tari-project/tari-cli"
license = "BSD-3-Clause"

[workspace.dependencies]
tari_ootle_publish_lib = { path = "crates/publish_lib", version = "0.12" }
tari_ootle_publish_lib = { path = "crates/publish_lib", version = "0.13" }

tokio = { version = "1.41.1", features = ["full"] }
serde = { version = "1.0.215", features = ["derive"] }
Expand Down
43 changes: 42 additions & 1 deletion crates/cli/src/cli/commands/template/init_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ pub struct InitMetadataArgs {
#[arg(default_value = ".")]
pub path: PathBuf,

/// Template description (written to [package].description).
#[arg(long)]
pub description: Option<String>,

/// Comma-separated tags (e.g. "token,fungible,defi").
#[arg(long, value_delimiter = ',')]
pub tags: Vec<String>,
Expand Down Expand Up @@ -79,6 +83,7 @@ pub async fn handle(args: InitMetadataArgs) -> anyhow::Result<()> {
}

struct TemplateMetadataInput {
description: Option<String>,
tags: Vec<String>,
category: Option<String>,
documentation: Option<String>,
Expand All @@ -87,8 +92,22 @@ struct TemplateMetadataInput {
}

fn resolve_metadata(args: &InitMetadataArgs) -> anyhow::Result<TemplateMetadataInput> {
// Check if [package].description already exists
let cargo_toml_path = args.path.join("Cargo.toml");
let has_description = if cargo_toml_path.exists() {
let content = std::fs::read_to_string(&cargo_toml_path)?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This line performs a redundant synchronous file read. The handle function (the caller) has already read the contents of Cargo.toml into cargo_toml_content at line 65. Additionally, using std::fs in an async context blocks the executor thread, which should be avoided. Consider passing the already-read content or a parsed DocumentMut to this function.

let doc = content.parse::<toml_edit::DocumentMut>()?;
doc.get("package")
.and_then(|p| p.get("description"))
.and_then(|d| d.as_str())
.is_some_and(|s| !s.is_empty())
} else {
false
};

if args.non_interactive {
return Ok(TemplateMetadataInput {
description: args.description.clone(),
tags: args.tags.clone(),
category: args.category.clone(),
documentation: args.documentation.clone(),
Expand All @@ -97,6 +116,18 @@ fn resolve_metadata(args: &InitMetadataArgs) -> anyhow::Result<TemplateMetadataI
});
}

// Prompt for description if not already in [package]
let description = if has_description {
None
} else {
let desc: String = Input::new()
.with_prompt("Description")
.default(args.description.clone().unwrap_or_default())
.allow_empty(true)
.interact_text()?;
if desc.is_empty() { None } else { Some(desc) }
};

// Interactive prompts, using CLI args as defaults
let tags_default = args.tags.join(", ");
let tags_input: String = Input::new()
Expand Down Expand Up @@ -143,6 +174,7 @@ fn resolve_metadata(args: &InitMetadataArgs) -> anyhow::Result<TemplateMetadataI
let logo_url = if logo_url.is_empty() { None } else { Some(logo_url) };

Ok(TemplateMetadataInput {
description,
tags,
category,
documentation,
Expand Down Expand Up @@ -177,12 +209,17 @@ fn add_template_metadata(cargo_toml_content: &str, metadata: &TemplateMetadataIn
.parse::<toml_edit::DocumentMut>()
.context("parsing Cargo.toml")?;

// Navigate to [package.metadata.tari-template]
let package = doc
.get_mut("package")
.and_then(|p| p.as_table_mut())
.ok_or_else(|| anyhow!("missing [package] section"))?;

// Write description to [package].description
if let Some(ref description) = metadata.description {
package.insert("description", toml_edit::value(description.as_str()));
}

// Navigate to [package.metadata.tari-template]
let pkg_metadata = package
.entry("metadata")
.or_insert_with(|| toml_edit::Item::Table(toml_edit::Table::new()))
Expand Down Expand Up @@ -239,6 +276,7 @@ pub async fn auto_init(crate_dir: &Path) -> anyhow::Result<()> {
.context("reading Cargo.toml")?;

let empty_metadata = TemplateMetadataInput {
description: None,
tags: vec![],
category: None,
documentation: None,
Expand Down Expand Up @@ -324,6 +362,7 @@ name = "my-template"
version = "0.1.0"
"#;
let metadata = TemplateMetadataInput {
description: None,
tags: vec!["token".to_string(), "defi".to_string()],
category: Some("token".to_string()),
documentation: None,
Expand All @@ -349,6 +388,7 @@ tags = ["old"]
category = "old-category"
"#;
let metadata = TemplateMetadataInput {
description: None,
tags: vec!["new".to_string()],
category: Some("new-category".to_string()),
documentation: None,
Expand All @@ -367,6 +407,7 @@ name = "my-template"
version = "0.1.0"
"#;
let metadata = TemplateMetadataInput {
description: None,
tags: vec![],
category: None,
documentation: None,
Expand Down
5 changes: 3 additions & 2 deletions crates/cli/src/cli/commands/wizard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ async fn step_project_config(_crate_dir: &PathBuf) -> anyhow::Result<()> {
// Ask for wallet daemon URL
let url: String = Input::new()
.with_prompt("Wallet daemon JSON-RPC URL")
.default("http://127.0.0.1:9000/json_rpc".to_string())
.default("http://127.0.0.1:5100/json_rpc".to_string())
.interact_text()?;

if url != "http://127.0.0.1:9000/json_rpc" {
if url != "http://127.0.0.1:5100/json_rpc" {
crate::cli::commands::config::handle(ConfigCommand::Set {
key: "network.wallet-daemon-jrpc-address".to_string(),
value: url,
Expand Down Expand Up @@ -189,6 +189,7 @@ async fn step_metadata(crate_dir: &Path) -> anyhow::Result<()> {

let args = init_metadata::InitMetadataArgs {
path: crate_dir.to_path_buf(),
description: None,
tags: vec![],
category: None,
documentation: None,
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/project/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl ProjectConfig {
impl Default for ProjectConfig {
fn default() -> Self {
Self {
network: NetworkConfig::new(Url::parse("http://127.0.0.1:9000/json_rpc").unwrap()),
network: NetworkConfig::new(Url::parse("http://127.0.0.1:5100/json_rpc").unwrap()),
default_account: None,
metadata_server_url: None,
template_address: None,
Expand Down
14 changes: 11 additions & 3 deletions docs/03-reference/cli-commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,19 @@ tari publish [OPTIONS] [PATH]
| `--publish-metadata` | Flag | `false` | Auto-submit metadata to server after publishing |
| `--metadata-server-url` | URL | Config or `localhost:3000` | Metadata server URL (with `--publish-metadata`) |

After publishing:
- The template address is saved to `tari.config.toml` (so `tari metadata publish` can omit `--template-address`)
- If metadata is detected and `--publish-metadata` is not set, you will be prompted to publish it
- If a template address already exists in config (republishing), a warning is shown

### Example

```bash
# Build and publish
tari publish -a myaccount -y

# Publish and auto-submit metadata
tari publish -a myaccount --publish-metadata --metadata-server-url http://community.example.com
tari publish -a myaccount --publish-metadata
```

---
Expand All @@ -137,6 +142,7 @@ tari template init [OPTIONS] [PATH]
| Argument / Option | Type | Default | Description |
|-------------------|------|---------|-------------|
| `[PATH]` | Path | `.` | Path to template crate directory |
| `--description` | String | *prompted if missing* | Template description (written to `[package].description`) |
| `--tags` | String (comma-separated) | *prompted* | Tags (e.g. "token,fungible,defi") |
| `--category` | String | *prompted* | Template category |
| `--documentation` | String | *prompted* | Documentation URL |
Expand All @@ -150,6 +156,8 @@ Adds `tari_ootle_template_build` to `[build-dependencies]`, creates `build.rs`,

Inspects a template metadata CBOR file. Alias: `template inspect-metadata`.

If the built metadata doesn't match `Cargo.toml`, you will be prompted to rebuild.

```bash
tari template inspect [OPTIONS] [PATH]
```
Expand Down Expand Up @@ -179,13 +187,13 @@ Alias for [`template inspect`](#template-inspect).
Publishes template metadata to a community metadata server.

```bash
tari metadata publish [OPTIONS] -t <TEMPLATE_ADDRESS>
tari metadata publish [OPTIONS] [-t <TEMPLATE_ADDRESS>]
```

| Argument / Option | Type | Default | Description |
|-------------------|------|---------|-------------|
| `[PATH]` | Path | `.` | Path to template crate directory |
| `-t, --template-address` | Address | **required** | Template address (e.g. `template_bce07f...` or raw hex) |
| `-t, --template-address` | Address | From config | Template address. If omitted, uses the address saved by `tari publish` |
| `--metadata-server-url` | URL | Config or `localhost:3000` | Metadata server URL |
| `--max-retries` | u32 | `6` | Max retry attempts for 404 (template not yet synced) |
| `--signed` | Flag | `false` | Use author-signed submission via wallet daemon |
Expand Down
10 changes: 6 additions & 4 deletions docs/03-reference/configuration-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ tari -e "wallet_daemon_url=http://localhost:12008/json_rpc" publish
# tari.config.toml

[network]
wallet-daemon-jrpc-address = "http://127.0.0.1:9000/json_rpc"
wallet-daemon-jrpc-address = "http://127.0.0.1:5100/json_rpc"

# Optional
# default_account = "myaccount"
# default-account = "myaccount"
# metadata-server-url = "http://localhost:3000"
# template-address = "template_abc123..."
Comment on lines +102 to +104
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The configuration keys in the documentation are inconsistent with the code. The ProjectConfig struct in crates/cli/src/project/config.rs uses underscores for field names (e.g., default_account, metadata_server_url, template_address), and there is no rename_all attribute to convert them to kebab-case. Using hyphens in the configuration file will cause these settings to be ignored by the parser.

Suggested change
# default-account = "myaccount"
# metadata-server-url = "http://localhost:3000"
# template-address = "template_abc123..."
# default_account = "myaccount"
# metadata_server_url = "http://localhost:3000"
# template_address = "template_abc123..."

```

### Fields
Expand All @@ -109,14 +110,15 @@ wallet-daemon-jrpc-address = "http://127.0.0.1:9000/json_rpc"

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `wallet-daemon-jrpc-address` | URL | `http://127.0.0.1:9000/json_rpc` | Wallet daemon JSON-RPC endpoint |
| `wallet-daemon-jrpc-address` | URL | `http://127.0.0.1:5100/json_rpc` | Wallet daemon JSON-RPC endpoint |

#### Top-level optional fields

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `default_account` | String | None | Default wallet account |
| `default-account` | String | None | Default wallet account |
| `metadata-server-url` | URL | None | Metadata server URL |
| `template-address` | Address | None | Template address (saved automatically by `tari publish`) |
Comment on lines +119 to +121
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

These table entries should use underscores to match the field names in the ProjectConfig struct, ensuring that users who copy-paste from the documentation have a working configuration.

Suggested change
| `default-account` | String | None | Default wallet account |
| `metadata-server-url` | URL | None | Metadata server URL |
| `template-address` | Address | None | Template address (saved automatically by `tari publish`) |
| `default_account` | String | None | Default wallet account |
| `metadata_server_url` | URL | None | Metadata server URL |
| `template_address` | Address | None | Template address (saved automatically by `tari publish`) |


### Managing Project Configuration

Expand Down
Loading