Browse Source

Merge pull request #109 from rust3ds/fix/build-doctests

Set up reusable CI workflow and add building doctests
pull/119/head
Meziu 2 years ago committed by GitHub
parent
commit
7e74e2d5de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .github/CODEOWNERS
  2. 46
      .github/actions/setup/action.yml
  3. 56
      .github/workflows/ci.yml
  4. 52
      ctru-rs/src/services/fs.rs

1
.github/CODEOWNERS

@ -0,0 +1 @@
* @rust3ds/active

46
.github/actions/setup/action.yml

@ -0,0 +1,46 @@
name: Setup
description: Set up CI environment for Rust + 3DS development
inputs:
toolchain:
description: The Rust toolchain to use for the steps
required: true
default: nightly
runs:
using: composite
steps:
# https://github.com/nektos/act/issues/917#issuecomment-1074421318
- if: ${{ env.ACT }}
shell: bash
name: Hack container for local development
run: |
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
- name: Setup default Rust toolchain
# Use this helper action so we get matcher support
# https://github.com/actions-rust-lang/setup-rust-toolchain/pull/15
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: clippy, rustfmt, rust-src
toolchain: ${{ inputs.toolchain }}
- name: Install build tools for host
shell: bash
run: sudo apt-get update && sudo apt-get install -y build-essential
- name: Install cargo-3ds
uses: actions-rs/cargo@v1
with:
command: install
# TODO: this should probably just be a released version from crates.io
# once cargo-3ds gets published somewhere...
args: >-
--git https://github.com/rust3ds/cargo-3ds
--rev 78a652fdfb01e2614a792d1a56b10c980ee1dae9
- name: Set PATH to include devkitARM
shell: bash
# For some reason devkitARM/bin is not part of the default PATH in the container
run: echo "${DEVKITARM}/bin" >> $GITHUB_PATH

56
.github/workflows/ci.yml

@ -12,6 +12,8 @@ on:
env: env:
# https://blog.rust-lang.org/2022/06/22/sparse-registry-testing.html # https://blog.rust-lang.org/2022/06/22/sparse-registry-testing.html
CARGO_UNSTABLE_SPARSE_REGISTRY: "true" CARGO_UNSTABLE_SPARSE_REGISTRY: "true"
# actions-rust-lang/setup-rust-toolchain sets some default RUSTFLAGS
RUSTFLAGS: ""
jobs: jobs:
lint: lint:
@ -22,41 +24,24 @@ jobs:
- nightly-2023-01-13 - nightly-2023-01-13
# Check for breakage on latest nightly # Check for breakage on latest nightly
- nightly - nightly
# But if latest nightly fails, allow the workflow to continue # But if latest nightly fails, allow the workflow to continue
continue-on-error: ${{ matrix.toolchain == 'nightly' }} continue-on-error: ${{ matrix.toolchain == 'nightly' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
container: devkitpro/devkitarm container: devkitpro/devkitarm
steps: steps:
# https://github.com/nektos/act/issues/917#issuecomment-1074421318
- if: ${{ env.ACT }}
name: Hack container for local development
run: |
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
- name: Checkout branch - name: Checkout branch
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Setup default Rust toolchain - uses: ./.github/actions/setup
uses: actions-rs/toolchain@v1
with: with:
components: clippy, rustfmt, rust-src
profile: minimal
toolchain: ${{ matrix.toolchain }} toolchain: ${{ matrix.toolchain }}
default: true
- name: Install build tools for host - name: Hide duplicate warnings from lint job
run: sudo apt-get update && sudo apt-get install -y build-essential if: ${{ matrix.toolchain == 'nightly' }}
run: |
- name: Install cargo-3ds echo "::remove-matcher owner=clippy::"
uses: actions-rs/cargo@v1 echo "::remove-matcher owner=rustfmt::"
with:
command: install
# TODO: this should probably just be a released version from crates.io
# once cargo-3ds gets published somewhere...
args: >-
--git https://github.com/rust3ds/cargo-3ds
--rev 7b70b6b26c4740b9a10ab85b832ee73c41142bbb
- name: Check formatting - name: Check formatting
run: cargo fmt --all --verbose -- --check run: cargo fmt --all --verbose -- --check
@ -68,5 +53,28 @@ jobs:
# feature, but https://github.com/actions/runner/issues/2341 means we # feature, but https://github.com/actions/runner/issues/2341 means we
# can't have both that *and* colored output. # can't have both that *and* colored output.
doctests:
strategy:
matrix:
toolchain:
- nightly-2023-01-13
- nightly
continue-on-error: ${{ matrix.toolchain == 'nightly' }}
runs-on: ubuntu-latest
container: devkitpro/devkitarm
steps:
- name: Checkout branch
uses: actions/checkout@v2
- uses: ./.github/actions/setup
with:
toolchain: ${{ matrix.toolchain }}
- name: Hide duplicated warnings from lint job
run: echo "::remove-matcher owner=clippy::"
- name: Build doc tests
run: cargo 3ds test --doc --verbose
# TODO: it would be nice to actually build 3dsx for examples/tests, etc. # TODO: it would be nice to actually build 3dsx for examples/tests, etc.
# and run it somehow, but exactly how remains to be seen. # and run it somehow, but exactly how remains to be seen.

52
ctru-rs/src/services/fs.rs

@ -103,7 +103,7 @@ pub struct Fs(());
/// ```no_run /// ```no_run
/// use ctru::services::fs::Fs; /// use ctru::services::fs::Fs;
/// ///
/// let fs = Fs::init().unwrap(); /// let mut fs = Fs::init().unwrap();
/// let sdmc_archive = fs.sdmc().unwrap(); /// let sdmc_archive = fs.sdmc().unwrap();
/// ``` /// ```
pub struct Archive { pub struct Archive {
@ -123,47 +123,65 @@ pub struct Archive {
/// Create a new file and write bytes to it: /// Create a new file and write bytes to it:
/// ///
/// ```no_run /// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use std::io::prelude::*; /// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File}; /// use ctru::services::fs::{Fs, File};
/// ///
/// let fs = Fs::init()?; /// let mut fs = Fs::init()?;
/// let sdmc = fs.sdmc()?; /// let mut sdmc = fs.sdmc()?;
/// ///
/// let mut file = File::create(&sdmc, "/foo.txt")?; /// let mut file = File::create(&mut sdmc, "/foo.txt")?;
/// file.write_all(b"Hello, world!")?; /// file.write_all(b"Hello, world!")?;
/// #
/// # Ok(())
/// # }
/// ``` /// ```
/// ///
/// Read the contents of a file into a `String`:: /// Read the contents of a file into a `String`::
/// ///
/// ```no_run /// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use std::io::prelude::*; /// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File}; /// use ctru::services::fs::{Fs, File};
/// ///
/// let fs = Fs::init()?; /// let mut fs = Fs::init()?;
/// let sdmc = fs.sdmc()?; /// let mut sdmc = fs.sdmc()?;
/// ///
/// let mut file = File::open(&sdmc, "/foo.txt")?; /// let mut file = File::open(&sdmc, "/foo.txt")?;
/// let mut contents = String::new(); /// let mut contents = String::new();
/// file.read_to_string(&mut contents)?; /// file.read_to_string(&mut contents)?;
/// assert_eq!(contents, "Hello, world!"); /// assert_eq!(contents, "Hello, world!");
/// #
/// # Ok(())
/// # }
/// ``` /// ```
/// ///
/// It can be more efficient to read the contents of a file with a buffered /// It can be more efficient to read the contents of a file with a buffered
/// `Read`er. This can be accomplished with `BufReader<R>`: /// `Read`er. This can be accomplished with `BufReader<R>`:
/// ///
/// ```no_run /// ```no_run
/// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> {
/// #
/// use std::io::BufReader; /// use std::io::BufReader;
/// use std::io::prelude::*; /// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File}; /// use ctru::services::fs::{Fs, File};
/// ///
/// let fs = Fs::init()?; /// let mut fs = Fs::init()?;
/// let sdmc = fs.sdmc()?; /// let mut sdmc = fs.sdmc()?;
/// ///
/// let file = File::open(&sdmc, "/foo.txt")?; /// let file = File::open(&sdmc, "/foo.txt")?;
/// let mut buf_reader = BufReader::new(file); /// let mut buf_reader = BufReader::new(file);
/// let mut contents = String::new(); /// let mut contents = String::new();
/// buf_reader.read_to_string(&mut contents)?; /// buf_reader.read_to_string(&mut contents)?;
/// assert_eq!(contents, "Hello, world!"); /// assert_eq!(contents, "Hello, world!");
/// #
/// # Ok(())
/// # }
/// ``` /// ```
pub struct File { pub struct File {
handle: u32, handle: u32,
@ -209,8 +227,8 @@ pub struct Metadata {
/// ```no_run /// ```no_run
/// use ctru::services::fs::{Fs, OpenOptions}; /// use ctru::services::fs::{Fs, OpenOptions};
/// ///
/// let fs = Fs::init().unwrap(); /// let mut fs = Fs::init().unwrap();
/// let sdmc_archive = fs.sdmc().unwrap(); /// let mut sdmc_archive = fs.sdmc().unwrap();
/// let file = OpenOptions::new() /// let file = OpenOptions::new()
/// .read(true) /// .read(true)
/// .archive(&sdmc_archive) /// .archive(&sdmc_archive)
@ -224,8 +242,8 @@ pub struct Metadata {
/// ```no_run /// ```no_run
/// use ctru::services::fs::{Fs, OpenOptions}; /// use ctru::services::fs::{Fs, OpenOptions};
/// ///
/// let fs = Fs::init().unwrap(); /// let mut fs = Fs::init().unwrap();
/// let sdmc_archive = fs.sdmc().unwrap(); /// let mut sdmc_archive = fs.sdmc().unwrap();
/// let file = OpenOptions::new() /// let file = OpenOptions::new()
/// .read(true) /// .read(true)
/// .write(true) /// .write(true)
@ -351,8 +369,8 @@ impl File {
/// ```no_run /// ```no_run
/// use ctru::services::fs::{Fs, File}; /// use ctru::services::fs::{Fs, File};
/// ///
/// let fs = Fs::init().unwrap(); /// let mut fs = Fs::init().unwrap();
/// let sdmc_archive = fs.sdmc().unwrap(); /// let mut sdmc_archive = fs.sdmc().unwrap();
/// let mut f = File::open(&sdmc_archive, "/foo.txt").unwrap(); /// let mut f = File::open(&sdmc_archive, "/foo.txt").unwrap();
/// ``` /// ```
pub fn open<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<File> { pub fn open<P: AsRef<Path>>(arch: &Archive, path: P) -> IoResult<File> {
@ -380,9 +398,9 @@ impl File {
/// ```no_run /// ```no_run
/// use ctru::services::fs::{Fs, File}; /// use ctru::services::fs::{Fs, File};
/// ///
/// let fs = Fs::init().unwrap(); /// let mut fs = Fs::init().unwrap();
/// let sdmc_archive = fs.sdmc().unwrap(); /// let mut sdmc_archive = fs.sdmc().unwrap();
/// let mut f = File::create(&sdmc_archive, "/foo.txt").unwrap(); /// let mut f = File::create(&mut sdmc_archive, "/foo.txt").unwrap();
/// ``` /// ```
pub fn create<P: AsRef<Path>>(arch: &mut Archive, path: P) -> IoResult<File> { pub fn create<P: AsRef<Path>>(arch: &mut Archive, path: P) -> IoResult<File> {
OpenOptions::new() OpenOptions::new()

Loading…
Cancel
Save