Skip to content

Commit 1e0be17

Browse files
committed
feat: implement configuration system
1 parent ce0d7f9 commit 1e0be17

File tree

8 files changed

+687
-91
lines changed

8 files changed

+687
-91
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ thiserror = "2.0.12"
1515
serde = { version = "1.0", features = ["derive"] }
1616
serde_yaml = "0.9.34-deprecated"
1717
dirs = "4.0" # For easily getting the home directory
18-
18+
toml = "0.9.1"
1919
sbpf-assembler = { workspace = true }
2020

2121
[workspace]
@@ -32,3 +32,4 @@ anyhow = "1.0.86"
3232
codespan-reporting = "0.12.0"
3333

3434
sbpf-assembler = { path = "crates/assembler" }
35+

README.md

Lines changed: 143 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
## Table of Contents
22

3-
- [sbpf](#sbpf)
4-
- [Dependencies](#dependencies)
5-
- [Installation](#installation)
6-
- [Usage](#usage)
7-
- [Command Details](#command-details)
8-
- [Examples](#examples)
9-
- [Advanced Usage](#advanced-usage)
10-
- [Contributing](#contributing)
3+
- [sbpf](#sbpf)
4+
- [Dependencies](#dependencies)
5+
- [Installation](#installation)
6+
- [Usage](#usage)
7+
- [Configuration-System](#configuration-system)
8+
- [Command Details](#command-details)
9+
- [Examples](#examples)
10+
- [Advanced Usage](#advanced-usage)
11+
- [Contributing](#contributing)
1112

1213
# sbpf
1314

@@ -27,29 +28,83 @@ cargo install --git https://github.com/blueshift-gg/sbpf.git
2728

2829
To view all the commands you can run, type `sbpf help`. Here are the available commands:
2930

30-
- `init`: Create a new project scaffold.
31-
- `build`: Compile into a Solana program executable.
32-
- `deploy`: Build and deploy the program.
33-
- `test`: Test the deployed program.
34-
- `e2e`: Build, deploy, and test a program.
35-
- `clean`: Clean up build and deploy artifacts.
36-
- `help`: Print this message or the help of the given subcommand(s).
31+
- `init`: Create a new project scaffold.
32+
- `build`: Compile into a Solana program executable.
33+
- `deploy`: Build and deploy the program.
34+
- `test`: Test the deployed program.
35+
- `e2e`: Build, deploy, and test a program.
36+
- `clean`: Clean up build and deploy artifacts.
37+
- `config`: Manage project configuration files.
38+
- `help`: Print this message or the help of the given subcommand(s).
3739

40+
Options:
41+
42+
- `-h`, --help Print help
43+
- `-V`, --version Print version
44+
45+
Usage: sbpf `<COMMAND>`
46+
47+
### Configuration System
48+
49+
sbpf now supports project-aware configuration through `sbpf.toml` files. This eliminates the need to repeatedly specify build settings, deployment targets, and other options.
50+
51+
#### Quick Start with Configuration
52+
53+
```bash
54+
# Create a new project (automatically includes sbpf.toml)
55+
sbpf init my-solana-program
56+
57+
# Or add configuration to an existing project
58+
sbpf config init
59+
60+
# View current configuration
61+
sbpf config show
62+
63+
# Modify settings
64+
sbpf config set deploy.cluster mainnet
65+
sbpf config set scripts.test "cargo test --verbose"
3866
```
39-
Usage: sbpf <COMMAND>
4067

41-
Commands:
42-
init Create a new project scaffold
43-
build Compile into a Solana program executable
44-
deploy Build and deploy the program
45-
test Test deployed program
46-
e2e Build, deploy and test a program
47-
clean Clean up build and deploy artifacts
48-
help Print this message or the help of the given subcommand(s)
68+
#### Configuration File Format
4969

50-
Options:
51-
-h, --help Print help
52-
-V, --version Print version
70+
The `sbpf.toml` file supports the following sections:
71+
72+
```toml
73+
[project]
74+
name = "sbpf"
75+
version = "0.1.0"
76+
77+
[scripts]
78+
test = "cargo test"
79+
80+
[deploy]
81+
cluster = "localhost"
82+
wallet = "~/.config/solana/id.json"
83+
```
84+
85+
#### Scripts System
86+
87+
Define custom commands in your configuration that can be run with `sbpf script <name>`:
88+
89+
```toml
90+
[scripts]
91+
# Override built-in commands
92+
test = "cargo test --verbose"
93+
build = "echo 'Custom build' && sbpf build"
94+
95+
# Custom scripts
96+
lint = "cargo clippy -- -D warnings"
97+
format = "cargo fmt"
98+
deploy-staging = "sbpf deploy --cluster devnet"
99+
audit = "cargo audit"
100+
```
101+
102+
**Usage:**
103+
104+
```bash
105+
sbpf script lint # Run custom lint script
106+
sbpf script deploy-staging # Run staging deployment
107+
sbpf script audit # Run security audit
53108
```
54109

55110
### Command Details
@@ -73,27 +128,83 @@ Options:
73128
-V, --version Print version information
74129
```
75130

76-
##### Examples
131+
#### Configuration Management
77132

78-
###### Create a new project with Rust tests (default)
133+
Manage project configuration without manually editing TOML files:
134+
135+
```sh
136+
sbpf config --help
137+
Initialize or manage configuration
138+
139+
Usage: sbpf config <COMMAND>
140+
141+
Commands:
142+
show Show current configuration
143+
init Initialize default configuration
144+
set Set a configuration value
145+
help Print this message or the help of the given subcommand(s)
146+
```
147+
148+
### Examples
149+
150+
**Create a new project with Rust tests (includes sbpf.toml):**
79151

80152
```sh
81153
sbpf init my-project
82154
```
83155

84-
###### Create a new project with TypeScript tests
156+
**Create a new project with TypeScript tests:**
85157

86158
```sh
87159
sbpf init my-project --ts-tests
88160
```
89161

90-
After initializing the project, you can navigate into the project directory and use other commands to build, deploy, and test your program.
162+
**Add configuration to existing project:**
163+
164+
```sh
165+
sbpf config init
166+
```
167+
168+
**View current settings:**
169+
170+
```sh
171+
sbpf config show
172+
```
173+
174+
**Modify settings:**
175+
176+
```sh
177+
sbpf config set deploy.cluster mainnet
178+
```
179+
180+
**Build with configuration:**
181+
182+
```sh
183+
# Uses settings from sbpf.toml automatically
184+
sbpf build
185+
sbpf deploy
186+
sbpf test
187+
```
188+
189+
**Custom build pipeline:**
190+
191+
```bash
192+
# Configure custom scripts
193+
sbpf config set scripts.build "echo 'Building...' && sbpf build"
194+
sbpf config set scripts.test "cargo test --verbose"
195+
sbpf config set scripts.deploy-all "sbpf build && sbpf deploy"
196+
197+
# Use custom pipeline
198+
sbpf script build
199+
sbpf script test
200+
sbpf script deploy-all
201+
```
91202

92203
### Advanced Usage
93204

94205
You can override the default linker with a [custom linker file](https://github.com/deanmlittle/sbpf-asm-noop/blob/master/src/noop/noop.ld) by including it in the src directory with the same name as your program. For example:
95206

96-
```
207+
```bash
97208
src/example/example.s
98209
src/example/example.ld
99210
```

src/commands/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,4 @@ pub fn build() -> Result<()> {
8080
}
8181

8282
Ok(())
83-
}
83+
}

src/commands/deploy.rs

Lines changed: 63 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,33 @@ use std::path::Path;
33
use std::process::Command;
44

55
use anyhow::{Error, Result};
6+
use crate::config::SbpfConfig;
7+
8+
fn deploy_program(program_name: &str, url: &str, config: &SbpfConfig) -> Result<(), Error> {
9+
10+
let program_id_file = if let Some(custom_id) = &config.deploy.program_id {
11+
format!("./deploy/{}-keypair.json", custom_id)
12+
} else {
13+
format!("./deploy/{}-keypair.json", program_name)
14+
};
615

7-
fn deploy_program(program_name: &str, url: &str) -> Result<(), Error> {
8-
let program_id_file = format!("./deploy/{}-keypair.json", program_name);
916
let program_file = format!("./deploy/{}.so", program_name);
1017

1118
if Path::new(&program_file).exists() {
12-
println!("🔄 Deploying \"{}\"", program_name);
19+
println!("🔄 Deploying \"{}\" to {}", program_name, url);
20+
21+
let mut cmd = Command::new("solana");
22+
cmd.arg("program")
23+
.arg("deploy")
24+
.arg(&program_file)
25+
.arg("--program-id")
26+
.arg(&program_id_file)
27+
.arg("--keypair")
28+
.arg(&config.deploy.wallet)
29+
.arg("-u")
30+
.arg(url);
1331

14-
let status = Command::new("solana")
15-
.arg("program")
16-
.arg("deploy")
17-
.arg(&program_file)
18-
.arg("--program-id")
19-
.arg(&program_id_file)
20-
.arg("-u")
21-
.arg(url)
22-
.status()?;
32+
let status = cmd.status()?;
2333

2434
if !status.success() {
2535
eprintln!("Failed to deploy program for {}", program_name);
@@ -41,15 +51,15 @@ fn deploy_program(program_name: &str, url: &str) -> Result<(), Error> {
4151
Ok(())
4252
}
4353

44-
fn deploy_all_programs(url: &str) -> Result<(), Error> {
54+
fn deploy_all_programs(url: &str, config: &SbpfConfig) -> Result<(), Error> {
4555
let deploy_path = Path::new("deploy");
4656

4757
for entry in deploy_path.read_dir()? {
4858
let entry = entry?;
4959
let path = entry.path();
5060
if path.is_file() && path.extension().and_then(|ext| ext.to_str()) == Some("so") {
5161
if let Some(filename) = path.file_stem().and_then(|name| name.to_str()) {
52-
deploy_program(filename, url)?;
62+
deploy_program(filename, url, config)?;
5363
}
5464
}
5565
}
@@ -58,11 +68,46 @@ fn deploy_all_programs(url: &str) -> Result<(), Error> {
5868
}
5969

6070
pub fn deploy(name: Option<String>, url: Option<String>) -> Result<(), Error> {
61-
let url = url.unwrap_or_else(|| "localhost".to_string());
71+
72+
let config = match SbpfConfig::load() {
73+
Ok(config) => {
74+
if url.is_none() {
75+
println!("📋 Using deployment configuration from sbpf.toml");
76+
}
77+
config
78+
}
79+
Err(_) => {
80+
81+
let current_dir = std::env::current_dir()?;
82+
let project_name = current_dir
83+
.file_name()
84+
.and_then(|name| name.to_str())
85+
.unwrap_or("sbpf-project");
86+
87+
println!("📋 No sbpf.toml found, using default deployment settings");
88+
println!(" 💡 Run 'sbpf config init' to create a configuration file");
89+
SbpfConfig::default_for_project(project_name)
90+
}
91+
};
92+
93+
94+
let deployment_url = match url {
95+
Some(override_url) => {
96+
println!("🌐 Detected command-line cluster: {} (Now overriding config: {})", override_url, config.deploy.cluster);
97+
override_url
98+
}
99+
None => {
100+
let resolved_url = config.resolve_cluster_url();
101+
println!("🌐 Using cluster '{}' → {}", config.deploy.cluster, resolved_url);
102+
resolved_url
103+
}
104+
};
62105

63106
if let Some(program_name) = name {
64-
deploy_program(&program_name, &url)
107+
108+
deploy_program(&program_name, &deployment_url, &config)
65109
} else {
66-
deploy_all_programs(&url)
110+
111+
deploy_all_programs(&deployment_url, &config)
67112
}
68-
}
113+
}

0 commit comments

Comments
 (0)