Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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
14 changes: 12 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,17 +67,23 @@ jobs:
cargo build --target $TARGET --profile $RUST_PROFILE --bins
mv $OUT_DIR/${{ env.RUST_PROFILE }}/simplex simplex

- name: Download nextest, elementsd and electrs
- name: Download nextest, simfmt, elementsd and electrs
env:
NEXTEST_VERSION: "0.9.137"
ELEMENTSD_VERSION: "23.3.1"
SIMFMT_VERSION: "0.0.2"
ELEMENTSD_TARGET: ${{ matrix.elementsd_target }}
ELECTRS_TARGET: ${{ matrix.electrs_target }}
NEXTEST_TARGET: ${{ matrix.nextest_target }}
SIMFMT_TARGET: ${{ matrix.target }}
run: |
#!/usr/bin/env bash
set -eo pipefail

ELEMENTSD_FILENAME="elements-${ELEMENTSD_VERSION}-${ELEMENTSD_TARGET}.tar.gz"
ELECTRS_FILENAME="electrs_${ELECTRS_TARGET}_esplora_027e38d3ebc2f85b28ae76f8f3448438ee4fc7b1_liquid.zip"
NEXTEST_FILENAME="cargo-nextest-${NEXTEST_VERSION}-${NEXTEST_TARGET}.tar.gz"
SIMFMT_FILENAME="simfmt-v${SIMFMT_VERSION}-${SIMFMT_TARGET}.tar.gz"

curl -Ls "https://github.com/ElementsProject/elements/releases/download/elements-${ELEMENTSD_VERSION}/${ELEMENTSD_FILENAME}" -o ${ELEMENTSD_FILENAME}
tar -xzf ${ELEMENTSD_FILENAME} && rm ${ELEMENTSD_FILENAME}
Expand All @@ -90,6 +96,9 @@ jobs:
curl -Ls "https://github.com/nextest-rs/nextest/releases/download/cargo-nextest-${NEXTEST_VERSION}/${NEXTEST_FILENAME}" -o ${NEXTEST_FILENAME}
tar -xzf ${NEXTEST_FILENAME} && rm ${NEXTEST_FILENAME}
mv cargo-nextest smplx-nextest

curl -fLsS "https://github.com/BlockstreamResearch/simfmt/releases/download/v${SIMFMT_VERSION}/${SIMFMT_FILENAME}" -o "${SIMFMT_FILENAME}"
tar -xzf "${SIMFMT_FILENAME}" && rm "${SIMFMT_FILENAME}"

- name: Sign elementsd binary
run: |
Expand All @@ -106,6 +115,7 @@ jobs:
elementsd
electrs
smplx-nextest
simfmt

- name: Record attestation URL
env:
Expand All @@ -116,7 +126,7 @@ jobs:
- name: Archive binaries
env:
ARCHIVE: simplex-${{ github.event.inputs.tag || github.ref_name }}-${{ matrix.archive }}
run: tar czf ${ARCHIVE} simplex elementsd electrs smplx-nextest
run: tar czf ${ARCHIVE} simplex elementsd electrs smplx-nextest simfmt

- name: Upload build artifacts
uses: actions/upload-artifact@v6
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ Simplex CLI provides the following commands:
- `simplex regtest` - Spins up local Electrs + Elements nodes.
- `simplex test` - Runs Simplex tests. Provide a `--fuzz` flag to run Simplex fuzz tests.
- `simplex clean` - Cleans up generated artifacts and installed dependencies.
- `simplex fmt` - Formats project files according to the specified `simfmt.toml` or default [configuration](https://github.com/BlockstreamResearch/simfmt/blob/master/simfmt.toml).

To view the available options, run the help command:

Expand Down
48 changes: 37 additions & 11 deletions crates/build/src/resolver.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(feature = "full")]
use std::collections::BTreeSet;
use std::fs;
use std::hash::{DefaultHasher, Hash as _, Hasher as _};
use std::path::{Component, Path, PathBuf};
Expand Down Expand Up @@ -29,21 +31,14 @@ impl ArtifactsResolver {
#[cfg(feature = "full")]
pub fn resolve_files_to_build(
root_dir: &Path,
src_dir: &String,
simfs: &[String],
src_dir: &impl AsRef<str>,
simfs: &[impl AsRef<str>],
) -> Result<Vec<PathBuf>, BuildError> {
let base = root_dir.join(src_dir);
let files = Self::resolve_simf_files(root_dir, src_dir, simfs)?;

let mut paths = Vec::new();

let walker = globwalk::GlobWalkerBuilder::from_patterns(base, simfs)
.follow_links(true)
.file_type(FileType::FILE)
.build()?
.filter_map(Result::ok);

for img in walker {
let path = img.path().to_path_buf().canonicalize()?;
for path in files {
let content = std::fs::read_to_string(&path)?;

match parse::Program::parse_from_str(&content) {
Expand All @@ -56,6 +51,37 @@ impl ArtifactsResolver {
Ok(paths)
}

/// Resolves every source file matched by `simfs` beneath `src_dir` relative
/// to `project_root`.
///
/// Returned paths are canonicalized, sorted, and deduplicated. Unlike
/// [`Self::resolve_files_to_build`], this does not require a source file to
/// contain a `main` function.
///
/// # Errors
/// Returns a [`BuildError`] if a glob cannot be constructed or a matching
/// path cannot be canonicalized.
#[cfg(feature = "full")]
pub fn resolve_simf_files(
project_root: impl AsRef<Path>,
src_dir: impl AsRef<str>,
simfs: &[impl AsRef<str>],
) -> Result<BTreeSet<PathBuf>, BuildError> {
let base = project_root.as_ref().join(src_dir.as_ref());
let walker = globwalk::GlobWalkerBuilder::from_patterns(base, simfs)
.follow_links(true)
.file_type(FileType::FILE)
.build()?
.filter_map(Result::ok);
let mut paths = BTreeSet::new();

for img in walker {
paths.insert(img.path().to_path_buf().canonicalize()?);
}

Ok(paths)
}

pub fn resolve_local_dir(root_dir: &Path, path: &impl AsRef<Path>) -> Result<PathBuf, BuildError> {
// `join` keeps `path` as is when it is already absolute
let path_outer = root_dir.join(path);
Expand Down
12 changes: 12 additions & 0 deletions crates/cli/src/cli.rs
Comment thread
ikripaka marked this conversation as resolved.
Resolved
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use smplx_build::DependencyConfig;
use crate::commands::Command;
use crate::commands::build::Build;
use crate::commands::clean::Clean;
use crate::commands::fmt::Format;
use crate::commands::init::Init;
use crate::commands::install::Install;
use crate::commands::regtest::Regtest;
Expand Down Expand Up @@ -93,6 +94,17 @@ impl Cli {

Ok(Clean::run(&root_dir, &loaded_config.build, flags)?)
}
Command::Fmt { opts } => {
Comment thread
Arvolear marked this conversation as resolved.
Resolved
use std::io::Write;

let exit_status = Format::run(opts)?;

// Flush buffered standard output before exiting.
std::io::stdout().flush()?;

// Exit with the formatter's success or failure status.
std::process::exit(exit_status);
Comment thread
ikripaka marked this conversation as resolved.
Resolved
}
}
}
}
34 changes: 34 additions & 0 deletions crates/cli/src/commands/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ pub enum Command {
#[command(flatten)]
flags: CleanFlags,
},
/// Formats the configured Simplex source files using simfmt
Fmt {
#[command(flatten)]
opts: FormatOpts,
},
}

#[allow(clippy::struct_excessive_bools)]
Expand Down Expand Up @@ -83,3 +88,32 @@ pub struct CleanFlags {
#[arg(long = "all")]
pub remove_all: bool,
}

#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Args)]
pub struct FormatOpts {
/// Path to the file.
#[arg(value_hint = clap::ValueHint::FilePath, value_name = "PATH", num_args(1..))]
pub files: Vec<std::path::PathBuf>,

/// Run simfmt in check mode
Comment thread
ikripaka marked this conversation as resolved.
Resolved
#[arg(long = "check")]
pub check: bool,

/// No output printed to stdout
#[arg(short = 'q', long = "quiet")]
pub quiet: bool,

/// Use verbose output
#[arg(short = 'v', long = "verbose")]
pub verbose: bool,

/// List files with differences instead of showing the diff
#[arg(long = "short")]
pub short: bool,

/// Options passed to simfmt
// `raw = true` makes the `--` separator explicit.
#[arg(id = "simfmt_options", raw = true)]
pub simfmt_options: Vec<String>,
}
24 changes: 24 additions & 0 deletions crates/cli/src/commands/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ pub enum CommandError {
#[error(transparent)]
Install(#[from] InstallError),

#[error(transparent)]
Fmt(#[from] FmtError),

#[error("IO error: {0}")]
Io(#[from] std::io::Error),

Expand All @@ -36,6 +39,27 @@ pub enum CommandError {
TestProcessTerminated,
}

#[derive(thiserror::Error, Debug)]
pub enum FmtError {
#[error("Quiet mode and verbose mode are not compatible")]
ConflictingVerbosity,

#[error("Invalid --message-format value: {0}. Allowed values are: short|human")]
InvalidMessageFormat(String),

#[error("no files matched the configured simf_files patterns under '{}'", .0.display())]
NoFiles(PathBuf),

#[error("Failed to determine the simplex executable path: {0}")]
CurrentExecutable(std::io::Error),

#[error("could not run simfmt at '{}': {source}", binary.display())]
RunSimfmt { binary: PathBuf, source: std::io::Error },

#[error(transparent)]
Config(#[from] crate::config::error::ConfigError),
}

#[derive(thiserror::Error, Debug)]
pub enum InitError {
#[error("Failed to open file '{1}': {0}")]
Expand Down
Loading
Loading