diff --git a/Cargo.lock b/Cargo.lock index 3350ffe98..882dd40ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,7 +40,7 @@ dependencies = [ name = "aes" version = "0.8.1" dependencies = [ - "cipher 0.4.3", + "cipher 0.4.4", ] [[package]] @@ -51,7 +51,7 @@ checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" dependencies = [ "aead", "aes 0.8.1", - "cipher 0.4.3", + "cipher 0.4.4", "ctr", "polyval", "subtle", @@ -488,7 +488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" dependencies = [ "byteorder", - "cipher 0.4.3", + "cipher 0.4.4", ] [[package]] @@ -563,7 +563,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher 0.4.3", + "cipher 0.4.4", ] [[package]] @@ -679,9 +679,9 @@ dependencies = [ [[package]] name = "cipher" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", @@ -1180,7 +1180,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d14f329cfbaf5d0e06b5e87fff7e265d2673c5ea7d2c27691a2c107db1442a0" dependencies = [ - "cipher 0.4.3", + "cipher 0.4.4", ] [[package]] @@ -3352,7 +3352,7 @@ dependencies = [ "bitfield", "bitflags 1.3.2", "blowfish 0.9.1", - "cipher 0.4.3", + "cipher 0.4.4", "digest 0.9.0", "gam", "hex 0.4.3", @@ -4079,7 +4079,7 @@ dependencies = [ "aes-kw", "blowfish 0.8.0", "byteorder", - "cipher 0.4.3", + "cipher 0.4.4", "com", "curve25519-dalek", "digest 0.9.0", diff --git a/xtask/src/app_manifest.rs b/xtask/src/app_manifest.rs index 77a768cf4..6284d182c 100644 --- a/xtask/src/app_manifest.rs +++ b/xtask/src/app_manifest.rs @@ -1,19 +1,19 @@ // This module supports generating the app menus from the JSON manifest in the apps/ directory. +use serde::{Deserialize, Serialize}; +use std::collections::{BTreeMap, HashMap}; use std::{ - fs::{OpenOptions, File}, + fmt::Write as StdWrite, + fs::{File, OpenOptions}, io::{Read, Write}, string::String, - fmt::Write as StdWrite, }; -use serde::{Deserialize, Serialize}; -use std::collections::{BTreeMap, HashMap}; #[derive(Deserialize, Serialize, Debug)] struct AppManifest { context_name: String, menu_name: HashMap>, - submenu: Option::, + submenu: Option, } #[derive(Deserialize, Serialize, Debug)] struct Locales { @@ -89,9 +89,14 @@ pub(crate) fn generate_app_menus(apps: &Vec) { gam_tokens, "\npub const EXPECTED_APP_CONTEXTS: &[&'static str] = &[" ) - .unwrap(); + .unwrap(); for (app_name, manifest) in working_set.iter() { - writeln!(gam_tokens, " APP_NAME_{},", app_name.to_uppercase().replace("-", "_"),).unwrap(); + writeln!( + gam_tokens, + " APP_NAME_{},", + app_name.to_uppercase().replace("-", "_"), + ) + .unwrap(); if let Some(menu_count) = manifest.submenu { for i in 0..menu_count { writeln!( diff --git a/xtask/src/builder.rs b/xtask/src/builder.rs index 60b7e6caa..c54291173 100644 --- a/xtask/src/builder.rs +++ b/xtask/src/builder.rs @@ -22,7 +22,7 @@ impl BuildStream { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum CrateSpec { /// name of the crate Local(String, bool), @@ -30,8 +30,8 @@ pub enum CrateSpec { CratesIo(String, String, bool), /// a prebuilt package: (name of executable, URL for download) Prebuilt(String, String, bool), - /// a prebuilt binary, done using command line tools - BinaryFile(String, bool), + /// a prebuilt binary, done using command line tools: (Optional name, path) + BinaryFile(Option, String, bool), /// an empty entry None, } @@ -41,16 +41,17 @@ impl CrateSpec { CrateSpec::Local(_s, xip) => *xip, CrateSpec::CratesIo(_n, _v, xip) => *xip, CrateSpec::Prebuilt(_n, _u, xip) => *xip, - CrateSpec::BinaryFile(_path, xip) => *xip, + CrateSpec::BinaryFile(_n, _path, xip) => *xip, _ => false } } pub fn set_xip(&mut self, xip: bool) { *self = match self { + //TODO: why do these to_strings need to be here? CrateSpec::Local(s, _xip) => CrateSpec::Local(s.to_string(), xip), CrateSpec::CratesIo(n, v, _xip) => CrateSpec::CratesIo(n.to_string(), v.to_string(), xip), CrateSpec::Prebuilt(n, u, _xip) => CrateSpec::Prebuilt(n.to_string(), u.to_string(), xip), - CrateSpec::BinaryFile(path, _xip) => CrateSpec::BinaryFile(path.to_string(), xip), + CrateSpec::BinaryFile(n, path, _xip) => CrateSpec::BinaryFile(n.as_ref().or(None).cloned(), path.to_string(), xip), CrateSpec::None => CrateSpec::None, } } @@ -59,22 +60,18 @@ impl CrateSpec { CrateSpec::Local(s, _xip) => Some(s.to_string()), CrateSpec::CratesIo(n, _v, _xip) => Some(n.to_string()), CrateSpec::Prebuilt(n, _u, _xip) => Some(n.to_string()), - CrateSpec::BinaryFile(path, _xip) => Some(path.to_string()), + CrateSpec::BinaryFile(n, path, _xip) => { + if let Some(name) = n { + Some(name.to_string()) + } + else { + Some(path.to_string()) + } + }, _ => None, } } } -impl Clone for CrateSpec { - fn clone(&self) -> CrateSpec { - match self { - CrateSpec::Local(s, xip) => CrateSpec::Local(s.to_string(), *xip), - CrateSpec::CratesIo(n, v, xip) => CrateSpec::CratesIo(n.to_string(), v.to_string(), *xip), - CrateSpec::Prebuilt(n, u, xip) => CrateSpec::Prebuilt(n.to_string(), u.to_string(), *xip), - CrateSpec::BinaryFile(path, xip) => CrateSpec::BinaryFile(path.to_string(), *xip), - CrateSpec::None => CrateSpec::None, - } - } -} impl From<&str> for CrateSpec { fn from(spec: &str) -> CrateSpec { // remote crates are specified as "name@version", i.e. "xous-names@0.9.9" @@ -99,7 +96,13 @@ impl From<&str> for CrateSpec { // Note that this is after a test for the '#' character, so that disambiguates URL slashes // It does mean that files with a '#' character in them are mistaken for URL coded paths, and '@' as remote crates. } else if spec.contains('/') || spec.contains('\\') { - CrateSpec::BinaryFile(spec.to_string(), false) + //optionally a BinaryFile can have a name associated with it as "name:path" + if spec.find(':').is_some() { + let (name,path) = spec.split_once(':').unwrap(); + CrateSpec::BinaryFile(Some(name.to_string()), path.to_string(), false) + } else { + CrateSpec::BinaryFile(None, spec.to_string(), false) + } } else { CrateSpec::Local(spec.to_string(), false) } @@ -323,7 +326,6 @@ impl Builder { } self } - /// add a feature to be passed on to services pub fn add_feature<'a>(&'a mut self, feature: &str) -> &'a mut Builder { self.features.push(feature.into()); @@ -595,6 +597,12 @@ impl Builder { match app { CrateSpec::Local(name, _xip) => app_names.push(name.into()), CrateSpec::CratesIo(name, _version, _xip) => app_names.push(name.into()), + CrateSpec::BinaryFile(name, _location, _xip) => { + // if binary file has a name, ensure it ends up in the app menu + if let Some(n) = name { + app_names.push(n.to_string()) + } else {} + }, _ => {} } } @@ -930,7 +938,7 @@ impl Builder { let mut paths = Vec::::new(); for item in [&self.services[..], &self.apps[..]].concat() { match item { - CrateSpec::BinaryFile(path, _xip) => { + CrateSpec::BinaryFile(_name, path, _xip) => { paths.push(path); } _ => {} diff --git a/xtask/src/main.rs b/xtask/src/main.rs index d7fb5ddf9..180cb5f9a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -60,22 +60,24 @@ fn main() -> Result<(), Box> { // A base set of packages. This is all you need for a normal // operating system that can run libstd let base_pkgs = [ - "xous-ticktimer", // "well known" service: thread scheduling - "xous-log", // "well known" service: debug logging - "xous-names", // "well known" service: manage inter-server connection lookup - "xous-susres", // ticktimer registers with susres to coordinate time continuity across sleeps - ].to_vec(); + "xous-ticktimer", // "well known" service: thread scheduling + "xous-log", // "well known" service: debug logging + "xous-names", // "well known" service: manage inter-server connection lookup + "xous-susres", // ticktimer registers with susres to coordinate time continuity across sleeps + ] + .to_vec(); // minimal set of packages to do bare-iron graphical I/O let gfx_base_pkgs = [ &base_pkgs[..], &[ - "graphics-server", // raw (unprotected) frame buffer primitives - "early_settings", // required by keyboard - "keyboard", // required by graphics-server - "spinor", // required by keyboard - to save key mapping - "llio", // required by spinor - ] - ].concat(); + "graphics-server", // raw (unprotected) frame buffer primitives + "early_settings", // required by keyboard + "keyboard", // required by graphics-server + "spinor", // required by keyboard - to save key mapping + "llio", // required by spinor + ], + ] + .concat(); // packages in the user image - most of the services at this layer have cross-dependencies let user_pkgs = [ &gfx_base_pkgs[..], @@ -103,16 +105,11 @@ fn main() -> Result<(), Box> { "pddb", // usb services "usb-device-xous", - ] - ].concat(); - // for fast testing of compilation targets of the PDDB to real hardware - let pddb_dev_pkgs = [ - &base_pkgs[..], - &[ - "pddb", - "sha2", ], - ].concat(); + ] + .concat(); + // for fast testing of compilation targets of the PDDB to real hardware + let pddb_dev_pkgs = [&base_pkgs[..], &["pddb", "sha2"]].concat(); // for fast checking of AES hardware accelerator let aestest_pkgs = ["xous-ticktimer", "xous-log", "aes-test"].to_vec(); @@ -145,7 +142,8 @@ fn main() -> Result<(), Box> { builder.add_kernel_feature(&feature); } - if !language_set { // the default language is english + if !language_set { + // the default language is english track_language_changes("en")?; } let gdb_stub = env::args().filter(|x| x == "--gdb-stub").count() != 0; @@ -170,112 +168,130 @@ fn main() -> Result<(), Box> { } // ----- renode configs -------- Some("renode-image") => { - builder.target_renode() - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_apps(&get_cratespecs()); + builder + .target_renode() + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_apps(&get_cratespecs()); } Some("renode-image-debug") => { - builder.target_renode() - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .stream(BuildStream::Debug) - .add_apps(&get_cratespecs()); + builder + .target_renode() + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .stream(BuildStream::Debug) + .add_apps(&get_cratespecs()); } Some("renode-test") => { - builder.target_renode() - .add_services(&base_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); + builder + .target_renode() + .add_services(&base_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); } Some("libstd-test") => { - builder.target_renode() - .add_services(&base_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); + builder + .target_renode() + .add_services(&base_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); builder.add_loader_feature("renode-bypass"); } Some("libstd-net") => { - builder.target_renode() - .add_services(&base_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); - builder.add_loader_feature("renode-bypass") - .add_loader_feature("renode-minimal"); - builder.add_service("net", false) + builder + .target_renode() + .add_services(&base_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); + builder + .add_loader_feature("renode-bypass") + .add_loader_feature("renode-minimal"); + builder + .add_service("net", false) .add_service("com", false) .add_service("llio", false) .add_service("dns", false); } Some("renode-aes-test") => { - builder.target_renode() - .add_services(&aestest_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); + builder + .target_renode() + .add_services(&aestest_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); } Some("ffi-test") => { - builder.target_renode() - .add_services(&gfx_base_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); + builder + .target_renode() + .add_services(&gfx_base_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); builder.add_service("ffi-test", false); builder.add_loader_feature("renode-bypass"); } // ------- hosted mode configs ------- Some("run") => { - builder.target_hosted() - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("pddbtest") - .add_feature("ditherpunk") - .add_feature("tracking-alloc") - .add_feature("tls") - // .add_feature("test-rekey") - .add_apps(&get_cratespecs()); + builder + .target_hosted() + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("pddbtest") + .add_feature("ditherpunk") + .add_feature("tracking-alloc") + .add_feature("tls") + // .add_feature("test-rekey") + .add_apps(&get_cratespecs()); } Some("pddb-ci") => { - builder.target_hosted() - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("pddb/ci") - .add_feature("pddb/deterministic"); + builder + .target_hosted() + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("pddb/ci") + .add_feature("pddb/deterministic"); } Some("pddb-btest") => { - builder.target_hosted() - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("pddbtest") - .add_feature("autobasis") // this will make secret basis tracking synthetic and automated for stress testing - .add_feature("autobasis-ci") - .add_feature("pddb/deterministic"); + builder + .target_hosted() + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("pddbtest") + .add_feature("autobasis") // this will make secret basis tracking synthetic and automated for stress testing + .add_feature("autobasis-ci") + .add_feature("pddb/deterministic"); } Some("hosted-debug") => { - builder.target_hosted() - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("pddbtest") - .add_feature("ditherpunk") - .add_feature("tracking-alloc") - .add_feature("tls") - .stream(BuildStream::Debug) - .add_apps(&get_cratespecs()); + builder + .target_hosted() + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("pddbtest") + .add_feature("ditherpunk") + .add_feature("tracking-alloc") + .add_feature("tls") + .stream(BuildStream::Debug) + .add_apps(&get_cratespecs()); } Some("gfx-dev") => { - builder.target_hosted() - .add_services(&gfx_base_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()) - .add_feature("graphics-server/gfx-testing"); - }, + builder + .target_hosted() + .add_services(&gfx_base_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()) + .add_feature("graphics-server/gfx-testing"); + } Some("hosted-ci") => { - builder.target_hosted() - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .hosted_build_only() - .add_apps(&get_cratespecs()); + builder + .target_hosted() + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .hosted_build_only() + .add_apps(&get_cratespecs()); } // ------ Precursor hardware image configs ------ Some("app-image") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("mass-storage") // add this in by default to help with testing - .add_apps(&get_cratespecs()); + builder + .target_precursor(PRECURSOR_SOC_VERSION) + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("mass-storage") // add this in by default to help with testing + .add_apps(&get_cratespecs()); } Some("app-image-xip") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - //.add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("mass-storage"); // add this in by default to help with testing + builder + .target_precursor(PRECURSOR_SOC_VERSION) + //.add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("mass-storage"); // add this in by default to help with testing for service in user_pkgs { - if (service != "shellchat") && (service != "ime-plugin-shell" && (service != "net")) { + if (service != "shellchat") && (service != "ime-plugin-shell" && (service != "net")) + { builder.add_service(service, false); } else { builder.add_service(service, true); @@ -298,26 +314,26 @@ fn main() -> Result<(), Box> { // ` python3 .\..\usb_update.py --dump v2p.txt --dump-file .\ring_aes_8.bin` // where the `v2p.txt` file contains a virtual to physical mapping that is generated by the `perflib` framework and // formatted in a fashion that can be automatically extracted by the usb_update script. - builder.target_precursor("c809403-perflib") - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_apps(&get_cratespecs()) - .add_feature("perfcounter") - .add_kernel_feature("v2p"); + builder + .target_precursor("c809403-perflib") + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_apps(&get_cratespecs()) + .add_feature("perfcounter") + .add_kernel_feature("v2p"); } Some("dvt-image") => { // this image targets a mostly deprecated DVT hardware generation. The purpose of it is to re-use some // of the now-defunct hardware for eFuse code testing, especially since FPGAs have gotten very scarce. // Once the eFuse path is validated, we could remove this target. - let mut services: Vec = user_pkgs - .into_iter() - .map(String::from).collect(); + let mut services: Vec = user_pkgs.into_iter().map(String::from).collect(); services.retain(|x| x != "codec"); // codec is not compatible with DVT boards - builder.target_precursor("2753c12-dvt") - .add_services(&services) - .add_feature("no-codec") - .add_feature("dvt") - .add_apps(&get_cratespecs()); + builder + .target_precursor("2753c12-dvt") + .add_services(&services) + .add_feature("no-codec") + .add_feature("dvt") + .add_apps(&get_cratespecs()); } Some("tts") => { builder.target_precursor(PRECURSOR_SOC_VERSION); @@ -335,50 +351,53 @@ fn main() -> Result<(), Box> { .add_feature("braille"); } Some("tiny") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - .add_services(&base_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); + builder + .target_precursor(PRECURSOR_SOC_VERSION) + .add_services(&base_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); } Some("usbdev") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - .add_services(&base_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); + builder + .target_precursor(PRECURSOR_SOC_VERSION) + .add_services(&base_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); //builder.add_service("usb-test"); builder.add_service("usb-device-xous", false); } Some("pddb-dev") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - .add_services(&pddb_dev_pkgs.into_iter().map(String::from).collect()) - .add_services(&get_cratespecs()); - }, + builder + .target_precursor(PRECURSOR_SOC_VERSION) + .add_services(&pddb_dev_pkgs.into_iter().map(String::from).collect()) + .add_services(&get_cratespecs()); + } Some("trng-test") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("urandomtest"); - }, + builder + .target_precursor(PRECURSOR_SOC_VERSION) + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("urandomtest"); + } Some("ro-test") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("ringosctest"); + builder + .target_precursor(PRECURSOR_SOC_VERSION) + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("ringosctest"); } Some("av-test") => { - builder.target_precursor(PRECURSOR_SOC_VERSION) - .add_services(&user_pkgs.into_iter().map(String::from).collect()) - .add_feature("avalanchetest"); + builder + .target_precursor(PRECURSOR_SOC_VERSION) + .add_services(&user_pkgs.into_iter().map(String::from).collect()) + .add_feature("avalanchetest"); + } + Some("compile-apps") => { + builder + .target_precursor_no_image(PRECURSOR_SOC_VERSION) + .add_services(&gfx_base_pkgs.into_iter().map(String::from).collect()); } - Some("compile-apps") => { - builder.target_precursor_no_image(PRECURSOR_SOC_VERSION) - .add_services(&gfx_base_pkgs.into_iter().map(String::from).collect()); - } // ------ Cramium hardware image configs ------ Some("cramium-fpga") | Some("cramium-soc") => { - let cramium_pkgs = [ - "xous-log", - "xous-names", - "xous-ticktimer", - "cram-console", - ].to_vec(); + let cramium_pkgs = + ["xous-log", "xous-names", "xous-ticktimer", "cram-console"].to_vec(); match task.as_deref() { Some("cramium-fpga") => builder.target_cramium_fpga(), Some("cramium-soc") => builder.target_cramium_soc(), @@ -392,7 +411,8 @@ fn main() -> Result<(), Box> { // ------ ARM hardware image configs ------ Some("arm-tiny") => { - builder.target_arm() + builder + .target_arm() .add_services(&vec![ "xous-log".to_string(), "xous-ticktimer".to_string(), @@ -461,6 +481,10 @@ fn print_help() { [name#URL] pre-built binary crate of 'name' downloaded from a server at 'URL' [path-to-binary] file path to a prebuilt binary image on local machine. Files in '.' must be specified as './file' to avoid confusion with local source + [name:path-to-binary] file path to a prebuilt binary image on local machine which will be renamed. + This is useful if the binary image is an app since the name will be required + for registration with the gam. + Files in '.' must be specified as './file' to avoid confusion with local source The [cratespecs] list is treated as apps or services based on the context of [verb]. Additional crates can be merged in with explicit app/service treatment with the following flags: @@ -543,16 +567,19 @@ fn get_flag(flag: &str) -> Result, DynError> { for arg in args { if arg == flag { flag_found = true; - continue + continue; } if flag_found { if arg.starts_with('-') { - eprintln!("Malformed arguments. Expected argument after flag {}, but found {}", flag, arg); + eprintln!( + "Malformed arguments. Expected argument after flag {}, but found {}", + flag, arg + ); return Err("Bad arguments".into()); } list.push(arg); flag_found = false; - continue + continue; } } Ok(list) diff --git a/xtask/src/utils.rs b/xtask/src/utils.rs index f348333c8..2a6cc4928 100644 --- a/xtask/src/utils.rs +++ b/xtask/src/utils.rs @@ -8,15 +8,19 @@ use std::{ }; use crate::{cargo, project_root}; -use crate::{TARGET_TRIPLE_RISCV32, TARGET_TRIPLE_ARM}; +use crate::{TARGET_TRIPLE_ARM, TARGET_TRIPLE_RISCV32}; -const TOOLCHAIN_RELEASE_URL_RISCV32: &str = "https://api.github.com/repos/betrusted-io/rust/releases"; +const TOOLCHAIN_RELEASE_URL_RISCV32: &str = + "https://api.github.com/repos/betrusted-io/rust/releases"; const TOOLCHAIN_RELEASE_URL_ARM: &str = "https://api.github.com/repos/Foundation-Devices/rust/releases"; lazy_static! { static ref TOOLCHAIN_RELEASE_URLS: HashMap = HashMap::from([ - (TARGET_TRIPLE_RISCV32.to_owned(), TOOLCHAIN_RELEASE_URL_RISCV32.to_owned()), + ( + TARGET_TRIPLE_RISCV32.to_owned(), + TOOLCHAIN_RELEASE_URL_RISCV32.to_owned() + ), ( TARGET_TRIPLE_ARM.to_owned(), TOOLCHAIN_RELEASE_URL_ARM.to_owned() @@ -402,9 +406,7 @@ pub(crate) fn track_language_changes(last_lang: &str) -> Result<(), crate::DynEr let last_config = "target/LAST_LANG"; let mut contents = String::new(); - let changed = match OpenOptions::new() - .read(true) - .open(&last_config) { + let changed = match OpenOptions::new().read(true).open(&last_config) { Ok(mut file) => { file.read_to_string(&mut contents).unwrap(); if contents != last_lang { @@ -413,7 +415,7 @@ pub(crate) fn track_language_changes(last_lang: &str) -> Result<(), crate::DynEr false } } - _ => true + _ => true, }; if changed { println!("Locale language changed to {}", last_lang); @@ -421,7 +423,8 @@ pub(crate) fn track_language_changes(last_lang: &str) -> Result<(), crate::DynEr .create(true) .write(true) .truncate(true) - .open(&last_config).unwrap(); + .open(&last_config) + .unwrap(); write!(file, "{}", last_lang).unwrap(); generate_locales()? } else { diff --git a/xtask/src/verifier.rs b/xtask/src/verifier.rs index e3ea91ac3..13d12963e 100644 --- a/xtask/src/verifier.rs +++ b/xtask/src/verifier.rs @@ -1,9 +1,9 @@ -use std::env; use crate::builder::CrateSpec; -use std::path::Path; +use std::env; use std::fs; use std::fs::File; use std::io::{BufReader, Read}; +use std::path::Path; use crate::DynError; @@ -47,19 +47,23 @@ pub fn verify(spec: CrateSpec, hard_failure: bool) -> Result<(), DynError> { let path = entry.path(); // this should *really* exist if the build system is stable, so just unwrap all the things let regdir = path.file_name().unwrap().to_str().unwrap().to_string(); - if regdir.contains("crates.io") { // crates.io sticks sources in something with git yadda yadda...docs don't really say what/why/how... + if regdir.contains("crates.io") { + // crates.io sticks sources in something with git yadda yadda...docs don't really say what/why/how... cache_leaf.push_str(®dir); } } if cache_leaf.len() == 0 { - return Err("Can't find expected registry source location".into()) + return Err("Can't find expected registry source location".into()); } // this now has the path to the cache directory cache_path.push(cache_leaf); // form the package source name cache_path.push(format!("{}-{}", name, version)); if !cache_path.exists() { - println!("Package not in registry, skipping consistency check: {}", cache_path.as_os_str().to_str().unwrap()); + println!( + "Package not in registry, skipping consistency check: {}", + cache_path.as_os_str().to_str().unwrap() + ); return Ok(()); } @@ -71,8 +75,12 @@ pub fn verify(spec: CrateSpec, hard_failure: bool) -> Result<(), DynError> { }; let subdir = format!("./{}/{}/", subdir, name); // handle special cases of xous kernel and ipc crates - let src_path = if name != "xous" && name != "xous-ipc" && name != "xous-kernel" - && name != "utralib" && name != "svd2utra" { + let src_path = if name != "xous" + && name != "xous-ipc" + && name != "xous-kernel" + && name != "utralib" + && name != "svd2utra" + { Path::new(&subdir) } else { if name == "xous" { @@ -86,26 +94,33 @@ pub fn verify(spec: CrateSpec, hard_failure: bool) -> Result<(), DynError> { } else if name == "svd2utra" { Path::new("./svd2utra") } else { - panic!("Consistency error: special case handling did not find either xous or xous-ipc"); + panic!( + "Consistency error: special case handling did not find either xous or xous-ipc" + ); } }; // now recurse through the source path and check that it matches the cache, except for Cargo.toml - println!("Comparing {} <-> {}", src_path.as_os_str().to_str().unwrap(), cache_path.as_os_str().to_str().unwrap()); + println!( + "Comparing {} <-> {}", + src_path.as_os_str().to_str().unwrap(), + cache_path.as_os_str().to_str().unwrap() + ); match compare_dirs(src_path, &cache_path) { Ok(true) => Ok(()), - Ok(false) => if hard_failure { - Err("Crates.io downloaded data does not match local source".into())} - else { + Ok(false) => { + if hard_failure { + Err("Crates.io downloaded data does not match local source".into()) + } else { println!("**WARNING**: Local package does not match the published source. Third parties downloading from crates.io will be inconsistent with this build."); Ok(()) - }, + } + } _ => Err("Error matching local source to crates.io cache files".into()), } } else { Err("Can't verify crates that aren't from crates.io".into()) } - } fn compare_dirs(src: &Path, other: &Path) -> Result { @@ -115,30 +130,34 @@ fn compare_dirs(src: &Path, other: &Path) -> Result { let fname = entry.file_name(); if fname.as_os_str().to_str().unwrap() == "Cargo.toml" { /* - This is awful. The Cargo.toml file is parsed and reformatted by the packaging tool to normalize its contents. - Thus, the Cargo.toml file of the downloaded version never matches the Cargo.toml file that's actually used. - Unfortunately, there doesn't seem to be an easy way to check the equivalence of two Cargo.toml files, - except for recursively and deeply parsing through and comparing all the possibile keys and values of - the abstract key/value tree. + This is awful. The Cargo.toml file is parsed and reformatted by the packaging tool to normalize its contents. + Thus, the Cargo.toml file of the downloaded version never matches the Cargo.toml file that's actually used. + Unfortunately, there doesn't seem to be an easy way to check the equivalence of two Cargo.toml files, + except for recursively and deeply parsing through and comparing all the possibile keys and values of + the abstract key/value tree. - As a hack, we compare to the Cargo.toml.orig file. Which is...kind of OK, but really, this opens us - up to attacks where someone just has to replace a version on a package or even just swap out an - entire package for a malicious one by just using package name re-assignment which is a thing that - the format supports. In other words, all this checking is kind of pointless because it's super-easy - to swap out key crates for whole other crates and have it go undetected. - */ + As a hack, we compare to the Cargo.toml.orig file. Which is...kind of OK, but really, this opens us + up to attacks where someone just has to replace a version on a package or even just swap out an + entire package for a malicious one by just using package name re-assignment which is a thing that + the format supports. In other words, all this checking is kind of pointless because it's super-easy + to swap out key crates for whole other crates and have it go undetected. + */ let mut other_file = other.to_path_buf(); other_file.push("Cargo.toml.orig"); let mut src_file = src.to_path_buf(); src_file.push(&fname); // println!("comparing {} <-> {}", src_file.as_os_str().to_str().unwrap(), other_file.as_os_str().to_str().unwrap()); match compare_files(&src_file, &other_file) { - Ok(true) => {}, + Ok(true) => {} Ok(false) => { - println!("Cargo.toml FAIL: {} <-> {}", src_file.as_os_str().to_str().unwrap(), other_file.as_os_str().to_str().unwrap()); - return Ok(false) - }, - Err(_) => return Err("Access error comparing remote and local crates".into()) + println!( + "Cargo.toml FAIL: {} <-> {}", + src_file.as_os_str().to_str().unwrap(), + other_file.as_os_str().to_str().unwrap() + ); + return Ok(false); + } + Err(_) => return Err("Access error comparing remote and local crates".into()), } // Cargo.toml's do *not* match /* turns out it's *really hard* to check equivalence of cargo files...you have to deep parse it into all the values. @@ -205,18 +224,29 @@ fn compare_dirs(src: &Path, other: &Path) -> Result { // println!("comparing {} <-> {}", src_file.as_os_str().to_str().unwrap(), other_file.as_os_str().to_str().unwrap()); if (src_file.as_os_str().to_str().unwrap().contains("ticktimer") && fname.as_os_str().to_str().unwrap() == "version.rs") - || src_file.as_os_str().to_str().unwrap().contains("Cargo.lock") { + || src_file + .as_os_str() + .to_str() + .unwrap() + .contains("Cargo.lock") + { // don't compare the version.rs, as it's supposed to be different due to the timestamp // don't compare Cargo.lock files that happen to be checked into packages // println!("skipping ticktimer version.rs or Cargo.lock file"); // this line is helpful to ensure our skip exception isn't too broad. } else { match compare_files(&src_file, &other_file) { - Ok(true) => {}, + Ok(true) => {} Ok(false) => { - println!("DIFF FAIL: {} <-> {}", src_file.as_os_str().to_str().unwrap(), other_file.as_os_str().to_str().unwrap()); - return Ok(false) - }, - Err(_) => return Err("Access error comparing remote and local crates".into()) + println!( + "DIFF FAIL: {} <-> {}", + src_file.as_os_str().to_str().unwrap(), + other_file.as_os_str().to_str().unwrap() + ); + return Ok(false); + } + Err(_) => { + return Err("Access error comparing remote and local crates".into()) + } } } } @@ -232,12 +262,16 @@ fn compare_dirs(src: &Path, other: &Path) -> Result { src_dir.push(&dname); // println!("comparing {}/ <-> {}/", src_dir.as_os_str().to_str().unwrap(), &other_dir.as_os_str().to_str().unwrap()); match compare_dirs(&src_dir, &other_dir) { - Ok(true) => {}, + Ok(true) => {} Ok(false) => { - println!("DIR FAIL: {}/ <-> {}/", src_dir.as_os_str().to_str().unwrap(), &other_dir.as_os_str().to_str().unwrap()); - return Ok(false) - }, - Err(_) => return Err("Access error comparing remote to local crates".into()) + println!( + "DIR FAIL: {}/ <-> {}/", + src_dir.as_os_str().to_str().unwrap(), + &other_dir.as_os_str().to_str().unwrap() + ); + return Ok(false); + } + Err(_) => return Err("Access error comparing remote to local crates".into()), }; } } @@ -279,4 +313,4 @@ fn compare_files(a: &Path, b: &Path) -> Result { } Ok(true) } -} \ No newline at end of file +} diff --git a/xtask/src/versioning.rs b/xtask/src/versioning.rs index a371add19..f141baaa7 100644 --- a/xtask/src/versioning.rs +++ b/xtask/src/versioning.rs @@ -2,10 +2,10 @@ // This generates the SEMVER data that is displayed when quering `xous ver` // It also generates timestamps, if demanded. -use std::io::{Write, Read}; +use chrono::Local; use std::fs::OpenOptions; +use std::io::{Read, Write}; use std::process::Command; -use chrono::Local; pub(crate) fn generate_version(add_timestamp: bool) { let output = if cfg!(target_os = "windows") {