diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index 1c11739..04e37b5 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -1,6 +1,9 @@ name: Build svg2gcode-cli -on: [push, pull_request] +on: + push: + branches: [main] + pull_request: env: CARGO_TERM_COLOR: always @@ -9,8 +12,14 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: Swatinem/rust-cache@v2 - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - name: Fmt + run: cargo fmt --check -p svg2gcode-cli + - name: Clippy + run: cargo clippy -p svg2gcode-cli -- -D warnings - name: Build run: cargo build -p svg2gcode-cli diff --git a/.github/workflows/lib.yml b/.github/workflows/lib.yml index b109f8e..e09da87 100644 --- a/.github/workflows/lib.yml +++ b/.github/workflows/lib.yml @@ -1,6 +1,9 @@ name: Build, test, and publish coverage for svg2gcode -on: [push, pull_request] +on: + push: + branches: [main] + pull_request: env: CARGO_TERM_COLOR: always @@ -9,15 +12,26 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy - uses: Swatinem/rust-cache@v2 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y libcairo2-dev + - name: Fmt + run: cargo fmt --check -p svg2gcode + - name: Clippy + run: cargo clippy -p svg2gcode -- -D warnings - name: Build run: cargo build -p svg2gcode + - name: Test + run: cargo test -p svg2gcode coverage: runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 - uses: Swatinem/rust-cache@v2 @@ -27,6 +41,8 @@ jobs: with: toolchain: nightly components: llvm-tools-preview + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y libcairo2-dev - run: cargo install grcov - run: cargo build -p svg2gcode env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7fd0c5d..c3c888a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,26 +4,69 @@ on: types: [created] jobs: - release: - name: release ${{ matrix.targets.name }} - runs-on: ubuntu-latest + build: + name: Build ${{ matrix.name }} + runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: - targets: - [ - { name: Windows, triple: x86_64-pc-windows-gnu, version: stable }, - { name: Linux, triple: x86_64-unknown-linux-musl, version: stable }, - # Fix for https://github.com/rust-build/rust-build.action/issues/88 - { name: macOS, triple: x86_64-apple-darwin, version: '1.73.0' } - ] + # https://docs.github.com/en/actions/reference/runners/github-hosted-runners#standard-github-hosted-runners-for-public-repositories + include: + - name: Linux x64 + runner: ubuntu-latest + target: x86_64-unknown-linux-musl + artifact: svg2gcode-linux-x86_64 + - name: Linux arm64 + runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-musl + artifact: svg2gcode-linux-aarch64 + - name: macOS x64 + runner: macos-15-intel + target: x86_64-apple-darwin + artifact: svg2gcode-macos-x86_64 + - name: macOS arm64 + runner: macos-latest + target: aarch64-apple-darwin + artifact: svg2gcode-macos-aarch64 + - name: Windows x64 + runner: windows-latest + target: x86_64-pc-windows-msvc + artifact: svg2gcode-windows-x86_64.exe + - name: Windows arm64 + runner: windows-11-arm + target: aarch64-pc-windows-msvc + artifact: svg2gcode-windows-aarch64.exe + steps: + - uses: actions/checkout@v5 + - uses: dtolnay/rust-toolchain@stable + with: + targets: ${{ matrix.target }} + - uses: Swatinem/rust-cache@v2 + - name: Install musl tools + if: contains(matrix.target, 'musl') + run: sudo apt-get install -y musl-tools + - name: Build + run: cargo build --release --target ${{ matrix.target }} -p svg2gcode-cli + - name: Copy cli build + run: cp target/${{ matrix.target }}/release/svg2gcode${{ runner.os == 'Windows' && '.exe' || '' }} ${{ matrix.artifact }} + - uses: actions/upload-artifact@v6 + with: + name: ${{ matrix.artifact }} + path: ${{ matrix.artifact }} + + release: + name: Upload release assets + needs: build + runs-on: ubuntu-latest + permissions: + contents: write steps: - - uses: actions/checkout@v4 - - name: Compile and release - uses: rust-build/rust-build.action@v1.4.5 + - uses: actions/download-artifact@v7 + with: + path: artifacts + merge-multiple: true + - name: Upload to release env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RUSTTARGET: ${{ matrix.targets.triple }} - TOOLCHAIN_VERSION: ${{ matrix.targets.version }} - EXTRA_FILES: "README.md LICENSE" - SRC_DIR: "cli/" + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + run: gh release upload ${{ github.event.release.tag_name }} artifacts/* diff --git a/.github/workflows/web-deploy.yml b/.github/workflows/web-deploy.yml index 166291a..6758fac 100644 --- a/.github/workflows/web-deploy.yml +++ b/.github/workflows/web-deploy.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: 'true' - uses: dtolnay/rust-toolchain@stable @@ -29,7 +29,7 @@ jobs: trunk build --release --public-url svg2gcode - name: Publish to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 + uses: peaceiris/actions-gh-pages@v4 if: github.ref == 'refs/heads/main' with: github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index 4b9629f..162c960 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -1,5 +1,8 @@ name: Check svg2gcode-web -on: [push, pull_request] +on: + push: + branches: [main] + pull_request: env: CARGO_TERM_COLOR: always @@ -7,8 +10,15 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - uses: Swatinem/rust-cache@v2 - uses: dtolnay/rust-toolchain@stable - - name: Build - run: cargo check -p svg2gcode-web + with: + targets: wasm32-unknown-unknown + components: rustfmt, clippy + - name: Fmt + run: cargo fmt --check -p svg2gcode-web + - name: Clippy + run: cargo clippy -p svg2gcode-web --target wasm32-unknown-unknown -- -D warnings + - name: Check + run: cargo check -p svg2gcode-web --target wasm32-unknown-unknown diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 82ebbfa..1617285 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -12,8 +12,7 @@ svg2gcode = { path = "../lib", version = "0.3.2", features = ["serde"] } env_logger = "0.11" log.workspace = true g-code.workspace = true -# Latest version of clap supporting Rust 1.73, needed for the macOS release in CI -clap = { version = "^4.0,<=4.4.18", features = ["derive"] } +clap = { version = "4", features = ["derive"] } codespan-reporting = "0.11" roxmltree.workspace = true serde_json.workspace = true diff --git a/cli/src/main.rs b/cli/src/main.rs index b03dac1..3e36205 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -87,7 +87,7 @@ struct Opt { /// Workaround for parsers that don't accept comments on the same line newline_before_comment: Option, #[arg(long)] - /// When printing a node name , print a extra attribute + /// When printing a node name , print a extra attribute /// /// Useful to print the label of layer on SVG generated by Inkscape extra_attribute_name: Option, @@ -165,7 +165,7 @@ fn main() -> io::Result<()> { settings.postprocess.newline_before_comment = newline_before_comment; } - settings.conversion.extra_attribute_name = opt.extra_attribute_name ; + settings.conversion.extra_attribute_name = opt.extra_attribute_name; if let Version::Unknown(ref unknown) = settings.version { error!( diff --git a/lib/src/arc.rs b/lib/src/arc.rs index 65f5199..888151b 100644 --- a/lib/src/arc.rs +++ b/lib/src/arc.rs @@ -195,6 +195,7 @@ impl Transformed for SvgArc { /// /// The code is Rust-ified with only one or two changes, but I plan to understand the math here and /// merge changes upstream to lyon-geom. + #[allow(non_snake_case)] fn transformed(&self, transform: &Transform) -> Self { let from = transform.transform_point(self.from); let to = transform.transform_point(self.to); diff --git a/lib/src/converter/mod.rs b/lib/src/converter/mod.rs index ff36bf7..54e96e9 100644 --- a/lib/src/converter/mod.rs +++ b/lib/src/converter/mod.rs @@ -47,7 +47,7 @@ impl Default for ConversionConfig { feedrate: 300.0, dpi: 96.0, origin: zero_origin(), - extra_attribute_name : None, + extra_attribute_name: None, } } } @@ -83,7 +83,7 @@ impl<'a, T: Turtle> ConversionVisitor<'a, T> { comment += name; comment += " > "; }); - comment += &node_name(node,&self._config.extra_attribute_name); + comment += &node_name(node, &self._config.extra_attribute_name); self.terrarium.turtle.comment(comment); } @@ -174,20 +174,20 @@ pub fn svg2program<'a, 'input: 'a>( conversion_visitor.terrarium.turtle.inner.program } -fn node_name(node: &Node , attr_to_print : &Option ) -> String { +fn node_name(node: &Node, attr_to_print: &Option) -> String { let mut name = node.tag_name().name().to_string(); if let Some(id) = node.attribute("id") { name += "#"; name += id; - if let Some(extra_attr_to_print) = attr_to_print { - for a_attr in node.attributes() { - if a_attr.name() == extra_attr_to_print { - name += " ( "; - name += a_attr.value() ; - name += " ) "; - } - } - } + if let Some(extra_attr_to_print) = attr_to_print { + for a_attr in node.attributes() { + if a_attr.name() == extra_attr_to_print { + name += " ( "; + name += a_attr.value(); + name += " ) "; + } + } + } } name } diff --git a/lib/src/converter/visit.rs b/lib/src/converter/visit.rs index eedfd81..7fd22b2 100644 --- a/lib/src/converter/visit.rs +++ b/lib/src/converter/visit.rs @@ -38,7 +38,7 @@ fn should_render_node(node: Node) -> bool { node.is_element() && !node .attribute("style") - .map_or(false, |style| style.contains("display:none")) + .is_some_and( |style| style.contains("display:none")) // - Defs are not rendered // - Markers are not directly rendered // - Symbols are not directly rendered @@ -370,7 +370,8 @@ impl<'a, T: Turtle> XmlVisitor for ConversionVisitor<'a, T> { } } - self.name_stack.push(node_name(&node,&self._config.extra_attribute_name)); + self.name_stack + .push(node_name(&node, &self._config.extra_attribute_name)); } fn visit_exit(&mut self, node: Node) { diff --git a/web/src/forms/mod.rs b/web/src/forms/mod.rs index 1636713..7c1b6b1 100644 --- a/web/src/forms/mod.rs +++ b/web/src/forms/mod.rs @@ -37,7 +37,7 @@ pub fn settings_form() -> Html { || form_state .origin .iter() - .all(|opt| opt.as_ref().map_or(false, |r| r.is_err())) + .all(|opt| opt.as_ref().is_some_and(|r| r.is_err())) || form_state .tool_on_sequence .as_ref() @@ -343,7 +343,7 @@ pub fn import_export_modal() -> Html { button={html_nested!(