diff --git a/.github/workflows/CICD.yml b/.github/workflows/CICD.yml index be48d18..65ea2a9 100644 --- a/.github/workflows/CICD.yml +++ b/.github/workflows/CICD.yml @@ -8,7 +8,7 @@ name: CICD on: push: branches: - - 'main' + - main tags: - '*' pull_request: @@ -18,6 +18,9 @@ on: permissions: contents: read +env: + CARGO_TERM_COLOR: always + jobs: test: @@ -75,101 +78,179 @@ jobs: args: -- -D warnings linux: - runs-on: ubuntu-latest + runs-on: ${{ matrix.platform.runner }} strategy: - matrix: - target: [x86_64, x86, armv7, s390x, ppc64le] + matrix: + platform: + - runner: ubuntu-latest + target: x86_64 + - runner: ubuntu-latest + target: x86 + # skipping until ring update/fix compile issue: include/ring-core/asm_base.h:73:2: error: #error "ARM assembler must define __ARM_ARCH" + # - runner: ubuntu-latest + # target: aarch64 + - runner: ubuntu-latest + target: armv7 + - runner: ubuntu-latest + target: s390x + - runner: ubuntu-latest + target: ppc64le steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: 3.x - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.target }} - args: --release --out dist --find-interpreter + target: ${{ matrix.platform.target }} + args: --release --out dist sccache: 'true' manylinux: auto - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 + with: + name: wheels-linux-${{ matrix.platform.target }} + path: dist + + musllinux: + runs-on: ${{ matrix.platform.runner }} + strategy: + matrix: + platform: + - runner: ubuntu-latest + target: x86_64 + - runner: ubuntu-latest + target: x86 + # skipping until ring update/fix compile issue: include/ring-core/asm_base.h:73:2: error: #error "ARM assembler must define __ARM_ARCH" + # - runner: ubuntu-latest + # target: aarch64 + - runner: ubuntu-latest + target: armv7 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - name: Build wheels + uses: PyO3/maturin-action@v1 + with: + target: ${{ matrix.platform.target }} + args: --release --out dist + sccache: 'true' + manylinux: musllinux_1_2 + - name: Upload wheels + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-musllinux-${{ matrix.platform.target }} path: dist windows: - runs-on: windows-latest + runs-on: ${{ matrix.platform.runner }} strategy: matrix: - target: [x64, x86] + platform: + - runner: windows-latest + target: x64 + - runner: windows-latest + target: x86 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' - architecture: ${{ matrix.target }} + python-version: 3.x + architecture: ${{ matrix.platform.target }} - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.target }} - args: --release --out dist --find-interpreter + target: ${{ matrix.platform.target }} + args: --release --out dist sccache: 'true' - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-windows-${{ matrix.platform.target }} path: dist macos: - runs-on: macos-latest + runs-on: ${{ matrix.platform.runner }} strategy: matrix: - target: [x86_64, aarch64] + platform: + - runner: macos-12 + target: x86_64 + - runner: macos-14 + target: aarch64 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: 3.x - name: Build wheels uses: PyO3/maturin-action@v1 with: - target: ${{ matrix.target }} - args: --release --out dist --find-interpreter + target: ${{ matrix.platform.target }} + args: --release --out dist sccache: 'true' - name: Upload wheels - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-macos-${{ matrix.platform.target }} path: dist sdist: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Build sdist uses: PyO3/maturin-action@v1 with: command: sdist args: --out dist - name: Upload sdist - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: wheels + name: wheels-sdist path: dist release: - name: Release + name: Release (PyPI) runs-on: ubuntu-latest - if: "startsWith(github.ref, 'refs/tags/')" - needs: [linux, windows, macos, sdist] + if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }} + needs: [linux, musllinux, windows, macos, sdist] + permissions: + # Use to sign the release artifacts + id-token: write + # Used to upload release artifacts + contents: write + # Used to generate artifact attestation + attestations: write steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 + - name: Generate artifact attestation + uses: actions/attest-build-provenance@v1 with: - name: wheels + subject-path: 'wheels-*/*' - name: Publish to PyPI + if: "startsWith(github.ref, 'refs/tags/')" uses: PyO3/maturin-action@v1 env: MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} with: command: upload - args: --non-interactive --skip-existing * + args: --non-interactive --skip-existing wheels-*/* + + publish: + name: Publish (crates.io) + if: startsWith(github.ref, 'refs/tags/') + needs: [release] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - name: Publish + run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index ef41f55..35ce42e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v5.2.0 (2024-10-03) + +* Publish Rust crate binary via crates.io [#202](https://github.com/gerardcl/renfe-cli/issues/202) + ## v5.1.0 (2024-10-02) * Enable Renfe Cercanías GTFS dataset [#200](https://github.com/gerardcl/renfe-cli/issues/200) diff --git a/Cargo.lock b/Cargo.lock index b1fc40d..70de2da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -925,7 +925,7 @@ dependencies = [ [[package]] name = "renfe-cli" -version = "5.1.0" +version = "5.2.0" dependencies = [ "chrono", "getopts", diff --git a/Cargo.toml b/Cargo.toml index 1962417..a1a015a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,19 +1,21 @@ [package] name = "renfe-cli" -version = "5.1.0" +version = "5.2.0" edition = "2021" +authors = ["Gerard C.L. "] license = "BSD-3-Clause" description = "CLI for searching Renfe train timetables in the Spanish country" readme = "README.md" homepage = "https://github.com/gerardcl/renfe-cli" repository = "https://github.com/gerardcl/renfe-cli" -keywords = ["cli", "timetables", "schedules", "trains", "renfe", "spain"] +keywords = ["cli", "timetables", "trains", "renfe", "spain"] categories = ["command-line-utilities"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] name = "renfe_cli" -crate-type = ["cdylib"] +# https://doc.rust-lang.org/reference/linkage.html +crate-type = ["cdylib", "lib"] [dependencies] pyo3 = { version = "0.22", features = ["abi3-py37"] } diff --git a/README.md b/README.md index e20a3c1..7107b05 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,15 @@ # Renfe Timetables CLI -Get faster Renfe trains timetables in your terminal, with Python3.7+ support. +Get faster Renfe trains timetables in your terminal, with Python3.8+ support. No longer need to open the browser! Just keep using your terminal 😀 It supports both [Horarios de alta velocidad, larga distancia y media distancia](https://data.renfe.com/dataset/horarios-de-alta-velocidad-larga-distancia-y-media-distancia) (default option, as in the web) and [Renfe Cercanías](https://data.renfe.com/dataset/horarios-cercanias) GTFS datasets. `renfe-cli` is written in [Rust](https://www.rust-lang.org/) (since v4.0.0) and published to [pypi.org](https://pypi.org/project/renfe-cli/) as a Python package (CLI and library). +It is provided as a Python package due to historical reasons, but was ported to Rust to showcase Rust's interoperability and performance improvements that can offer to the Python ecosystem. Nevertheless, one can optionally use the built [renfe-cli](https://crates.io/crates/renfe-cli) crate that is publised to crates.io. + See the [changelog](https://github.com/gerardcl/renfe-cli/blob/master/CHANGELOG.md). **NOTE** since I am more often using Rodalies trains I have created [rodalies-cli](https://github.com/gerardcl/rodalies-cli). I hope you like it too! @@ -17,12 +19,22 @@ See the [changelog](https://github.com/gerardcl/renfe-cli/blob/master/CHANGELOG. ## Installation +### Python package + Install Python CLI package [renfe-cli](https://pypi.org/project/renfe-cli/) ```bash pip install renfe-cli --upgrade ``` +### Rust crate (optional) + +Install the Rust crate [renfe-cli](https://crates.io/crates/renfe-cli) + +```bash +cargo install renfe-cli +``` + ## Usage (CLI) The CLI uses the official and latest Renfe's GTFS dataset, from [Horarios de alta velocidad, larga distancia y media distancia](https://data.renfe.com/dataset/horarios-de-alta-velocidad-larga-distancia-y-media-distancia), by default. Optionally, one can enable searching over [Renfe Cercanías GTFS dataset](https://data.renfe.com/dataset/horarios-cercanias) (expect longer load time in this case). diff --git a/pyproject.toml b/pyproject.toml index 7c33e87..3a4c383 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "maturin" [project] name = "renfe-cli" -requires-python = ">=3.7" +requires-python = ">=3.8" authors = [ {name = "Gerard Castillo Lasheras", email = "gerardcl@gmail.com"}, ] diff --git a/src/lib.rs b/src/lib.rs index 81fc71b..0eba183 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,10 @@ +pub mod cli; +pub mod renfe; + use pyo3::prelude::*; -mod renfe; -use renfe::{Renfe, Schedule, Station}; -mod cli; use cli::main; +use renfe::{Renfe, Schedule, Station}; /// A Python module implemented in Rust. The name of this function must match /// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..a7d9305 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,10 @@ +use renfe_cli::cli; + +fn main() -> Result<(), pyo3::PyErr> { + // Initialize the Python interpreter required + pyo3::prepare_freethreaded_python(); + + cli::main()?; + + Ok(()) +} diff --git a/src/renfe.rs b/src/renfe.rs index f153fa6..2627076 100644 --- a/src/renfe.rs +++ b/src/renfe.rs @@ -1,8 +1,7 @@ -use std::io::Read; - use chrono::{Datelike, NaiveDate, NaiveTime, TimeDelta, Timelike}; use gtfs_structures::Gtfs; use pyo3::{exceptions::PyValueError, pyclass, pymethods, PyResult}; +use std::io::Read; #[pyclass] pub struct Renfe {