From 7a96d8d7542120f616c9dc01d9b528aef6abf3ed Mon Sep 17 00:00:00 2001 From: ibaryshnikov Date: Sat, 23 Mar 2019 02:46:53 +0300 Subject: [PATCH 1/9] initial support for --out-name added --- docs/src/commands/build.md | 10 ++++++++++ src/bindgen.rs | 5 +++++ src/command/build.rs | 10 +++++++++- src/command/test.rs | 2 +- src/manifest/mod.rs | 22 ++++++++++++++++------ tests/all/license.rs | 10 +++++----- tests/all/lockfile.rs | 8 ++++---- tests/all/manifest.rs | 36 ++++++++++++++++++------------------ 8 files changed, 68 insertions(+), 35 deletions(-) diff --git a/docs/src/commands/build.md b/docs/src/commands/build.md index 00ab2e9a..8058e184 100644 --- a/docs/src/commands/build.md +++ b/docs/src/commands/build.md @@ -32,6 +32,16 @@ wasm-pack build --out-dir out The above command will put your build artifacts in a directory called `out`, instead of the default `pkg`. +## Output file names + +Set output file names. Defaults to package name. + +``` +wasm-pack build --out-name index +``` + +This command will build the package with file names like `index.js`, `index.d.ts`, and so on. + ## Profile The `build` command accepts an optional profile argument: one of `--dev`, diff --git a/src/bindgen.rs b/src/bindgen.rs index bf30d78e..9caf1f3b 100644 --- a/src/bindgen.rs +++ b/src/bindgen.rs @@ -173,6 +173,7 @@ pub fn wasm_bindgen_build( data: &CrateData, bindgen: &Download, out_dir: &Path, + out_name: &Option, disable_dts: bool, target: &Target, profile: BuildProfile, @@ -210,6 +211,10 @@ pub fn wasm_bindgen_build( .arg(dts_arg) .arg(target_arg); + if let Some(value) = out_name { + cmd.arg("--out-name").arg(value); + } + let profile = data.configured_profile(profile); if profile.wasm_bindgen_debug_js_glue() { cmd.arg("--debug"); diff --git a/src/command/build.rs b/src/command/build.rs index 924ef8e6..af1926b6 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -28,6 +28,7 @@ pub struct Build { pub profile: BuildProfile, pub mode: BuildMode, pub out_dir: PathBuf, + pub out_name: Option, pub bindgen: Option, pub cache: Cache, pub extra_options: Vec, @@ -159,6 +160,10 @@ pub struct BuildOptions { /// Sets the output directory with a relative path. pub out_dir: String, + #[structopt(long = "out-name")] + /// Sets the output file names. Defaults to package name. + pub out_name: Option, + #[structopt(last = true)] /// List of extra options to pass to `cargo build` pub extra_options: Vec, @@ -177,6 +182,7 @@ impl Default for BuildOptions { release: false, profiling: false, out_dir: String::new(), + out_name: None, extra_options: Vec::new(), } } @@ -188,7 +194,7 @@ impl Build { /// Construct a build command from the given options. pub fn try_from_opts(build_opts: BuildOptions) -> Result { let crate_path = set_crate_path(build_opts.path)?; - let crate_data = manifest::CrateData::new(&crate_path)?; + let crate_data = manifest::CrateData::new(&crate_path, build_opts.out_name.clone())?; let out_dir = crate_path.join(PathBuf::from(build_opts.out_dir)); let dev = build_opts.dev || build_opts.debug; @@ -210,6 +216,7 @@ impl Build { profile, mode: build_opts.mode, out_dir, + out_name: build_opts.out_name, bindgen: None, cache: cache::get_wasm_pack_cache()?, extra_options: build_opts.extra_options, @@ -388,6 +395,7 @@ impl Build { &self.crate_data, self.bindgen.as_ref().unwrap(), &self.out_dir, + &self.out_name, self.disable_dts, &self.target, self.profile, diff --git a/src/command/test.rs b/src/command/test.rs index 67436aad..78d8e78b 100644 --- a/src/command/test.rs +++ b/src/command/test.rs @@ -120,7 +120,7 @@ impl Test { } = test_opts; let crate_path = set_crate_path(path)?; - let crate_data = manifest::CrateData::new(&crate_path)?; + let crate_data = manifest::CrateData::new(&crate_path, None)?; let any_browser = chrome || firefox || safari; if !node && !any_browser { diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 617af868..3dfb6126 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -27,6 +27,7 @@ pub struct CrateData { data: Metadata, current_idx: usize, manifest: CargoManifest, + out_name: Option, } #[doc(hidden)] @@ -214,7 +215,7 @@ pub struct ManifestAndUnsedKeys { impl CrateData { /// Reads all metadata for the crate whose manifest is inside the directory /// specified by `path`. - pub fn new(crate_path: &Path) -> Result { + pub fn new(crate_path: &Path, out_name: Option) -> Result { let manifest_path = crate_path.join("Cargo.toml"); if !manifest_path.is_file() { bail!( @@ -241,6 +242,7 @@ impl CrateData { data, manifest, current_idx, + out_name, }); fn error_chain_to_failure(err: cargo_metadata::Error) -> Error { @@ -346,6 +348,14 @@ impl CrateData { } } + /// Get the prefix for output file names + fn name_prefix(&self) -> String { + match &self.out_name { + Some(value) => value.clone(), + None => self.crate_name(), + } + } + /// Get the license for the crate at the given path. pub fn crate_license(&self) -> &Option { &self.manifest.package.license @@ -396,14 +406,14 @@ impl CrateData { disable_dts: bool, out_dir: &Path, ) -> NpmData { - let crate_name = self.crate_name(); - let wasm_file = format!("{}_bg.wasm", crate_name); - let js_file = format!("{}.js", crate_name); + let name_prefix = self.name_prefix(); + let wasm_file = format!("{}_bg.wasm", name_prefix); + let js_file = format!("{}.js", name_prefix); let mut files = vec![wasm_file]; files.push(js_file.clone()); if include_commonjs_shim { - let js_bg_file = format!("{}_bg.js", crate_name); + let js_bg_file = format!("{}_bg.js", name_prefix); files.push(js_bg_file.to_string()); } @@ -414,7 +424,7 @@ impl CrateData { }; let dts_file = if !disable_dts { - let file = format!("{}.d.ts", crate_name); + let file = format!("{}.d.ts", name_prefix); files.push(file.to_string()); Some(file) } else { diff --git a/tests/all/license.rs b/tests/all/license.rs index f56f6505..cffa7995 100644 --- a/tests/all/license.rs +++ b/tests/all/license.rs @@ -12,7 +12,7 @@ fn it_copies_a_license_default_path() { let fixture = fixture::single_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path); + let crate_data = CrateData::new(&fixture.path, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); @@ -37,7 +37,7 @@ fn it_copies_a_license_provided_path() { let fixture = fixture::single_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path); + let crate_data = CrateData::new(&fixture.path, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); let crate_license_path = fixture.path.join("LICENSE"); @@ -60,7 +60,7 @@ fn it_copies_all_licenses_default_path() { let fixture = fixture::dual_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path); + let crate_data = CrateData::new(&fixture.path, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); @@ -95,7 +95,7 @@ fn it_copies_all_licenses_provided_path() { let fixture = fixture::dual_license(); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path); + let crate_data = CrateData::new(&fixture.path, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); @@ -131,7 +131,7 @@ fn it_copies_a_non_standard_license_provided_path() { let fixture = fixture::non_standard_license(license_file); let out_dir = fixture.path.join("pkg"); fs::create_dir(&out_dir).expect("should create pkg directory OK"); - let crate_data = CrateData::new(&fixture.path); + let crate_data = CrateData::new(&fixture.path, None); assert!(license::copy_from_crate(&crate_data.unwrap(), &fixture.path, &out_dir).is_ok()); diff --git a/tests/all/lockfile.rs b/tests/all/lockfile.rs index 87e4434e..1a42ce88 100644 --- a/tests/all/lockfile.rs +++ b/tests/all/lockfile.rs @@ -6,7 +6,7 @@ use wasm_pack::manifest::CrateData; fn it_gets_wasm_bindgen_version() { let fixture = fixture::js_hello_world(); fixture.cargo_check(); - let data = CrateData::new(&fixture.path).unwrap(); + let data = CrateData::new(&fixture.path, None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_version(), Some("0.2.37"),); } @@ -15,7 +15,7 @@ fn it_gets_wasm_bindgen_version() { fn it_gets_wasm_bindgen_test_version() { let fixture = fixture::wbg_test_node(); fixture.cargo_check(); - let data = CrateData::new(&fixture.path).unwrap(); + let data = CrateData::new(&fixture.path, None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_test_version(), Some("0.2.37"),); } @@ -60,7 +60,7 @@ fn it_gets_wasm_bindgen_version_in_crate_inside_workspace() { "#, ); fixture.cargo_check(); - let data = CrateData::new(&fixture.path.join("blah")).unwrap(); + let data = CrateData::new(&fixture.path.join("blah"), None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_version(), Some("0.2.37"),); } @@ -128,7 +128,7 @@ fn it_gets_wasm_bindgen_version_from_dependencies() { "#, ); fixture.cargo_check(); - let data = CrateData::new(&fixture.path.join("parent")).unwrap(); + let data = CrateData::new(&fixture.path.join("parent"), None).unwrap(); let lock = Lockfile::new(&data).unwrap(); assert_eq!(lock.wasm_bindgen_version(), Some("0.2.37"),); } diff --git a/tests/all/manifest.rs b/tests/all/manifest.rs index a68cf27b..31ef3abc 100644 --- a/tests/all/manifest.rs +++ b/tests/all/manifest.rs @@ -9,7 +9,7 @@ use wasm_pack::{self, license, manifest}; #[test] fn it_gets_the_crate_name_default_path() { let path = &PathBuf::from("."); - let crate_data = manifest::CrateData::new(&path).unwrap(); + let crate_data = manifest::CrateData::new(&path, None).unwrap(); let name = crate_data.crate_name(); assert_eq!(name, "wasm_pack"); } @@ -17,7 +17,7 @@ fn it_gets_the_crate_name_default_path() { #[test] fn it_gets_the_crate_name_provided_path() { let fixture = fixture::js_hello_world(); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); assert_eq!(crate_data.crate_name(), "js_hello_world"); } @@ -26,7 +26,7 @@ fn it_checks_has_cdylib_default_path() { let fixture = fixture::no_cdylib(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); assert!(crate_data.check_crate_config().is_err()); } @@ -35,14 +35,14 @@ fn it_checks_has_cdylib_provided_path() { let fixture = fixture::js_hello_world(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); crate_data.check_crate_config().unwrap(); } #[test] fn it_checks_has_cdylib_wrong_crate_type() { let fixture = fixture::bad_cargo_toml(); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); assert!(crate_data.check_crate_config().is_err()); } @@ -51,7 +51,7 @@ fn it_recognizes_a_map_during_depcheck() { let fixture = fixture::serde_feature(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); crate_data.check_crate_config().unwrap(); } @@ -59,7 +59,7 @@ fn it_recognizes_a_map_during_depcheck() { fn it_creates_a_package_json_default_path() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, &Target::Bundler) @@ -94,7 +94,7 @@ fn it_creates_a_package_json_default_path() { fn it_creates_a_package_json_provided_path() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, &Target::Bundler) @@ -122,7 +122,7 @@ fn it_creates_a_package_json_provided_path() { fn it_creates_a_package_json_provided_path_with_scope() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &Some("test".to_string()), false, &Target::Bundler,) @@ -150,7 +150,7 @@ fn it_creates_a_package_json_provided_path_with_scope() { fn it_creates_a_pkg_json_with_correct_files_on_node() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, &Target::Nodejs) @@ -185,7 +185,7 @@ fn it_creates_a_pkg_json_with_correct_files_on_node() { fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, &Target::NoModules) @@ -219,7 +219,7 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { fn it_creates_a_pkg_json_in_out_dir() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("./custom/out"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, false, &Target::Bundler) @@ -234,7 +234,7 @@ fn it_creates_a_pkg_json_in_out_dir() { fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() { let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); assert!(crate_data .write_package_json(&out_dir, &None, true, &Target::Bundler) @@ -262,7 +262,7 @@ fn it_creates_a_package_json_with_correct_keys_when_types_are_skipped() { #[test] fn it_errors_when_wasm_bindgen_is_not_declared() { let fixture = fixture::bad_cargo_toml(); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); assert!(crate_data.check_crate_config().is_err()); } @@ -294,7 +294,7 @@ fn it_sets_homepage_field_if_available_in_cargo_toml() { ); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); crate_data @@ -310,7 +310,7 @@ fn it_sets_homepage_field_if_available_in_cargo_toml() { // When 'homepage' is unavailable let fixture = fixture::js_hello_world(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); crate_data @@ -326,7 +326,7 @@ fn it_does_not_error_when_wasm_bindgen_is_declared() { let fixture = fixture::js_hello_world(); // Ensure that there is a `Cargo.lock`. fixture.cargo_check(); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); crate_data.check_crate_config().unwrap(); } @@ -410,7 +410,7 @@ fn it_lists_license_files_in_files_field_of_package_json() { let fixture = fixture::dual_license(); let out_dir = fixture.path.join("pkg"); - let crate_data = manifest::CrateData::new(&fixture.path).unwrap(); + let crate_data = manifest::CrateData::new(&fixture.path, None).unwrap(); wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); license::copy_from_crate(&crate_data, &fixture.path, &out_dir).unwrap(); From b329fefc844c4c09b647ab8c47ab5015a3ad40a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20H=C3=A5kansson?= Date: Sat, 23 Mar 2019 13:44:56 +0100 Subject: [PATCH 2/9] feat: Print unexpected panics to standard error This will print to standard error for unexpected panics and then let `human_panic` handle panics, just like before. --- src/main.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index c99f5af0..2ad82952 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,13 +2,13 @@ extern crate atty; extern crate env_logger; #[macro_use] extern crate failure; -#[macro_use] extern crate human_panic; extern crate structopt; extern crate wasm_pack; extern crate which; use std::env; +use std::panic; use structopt::StructOpt; use wasm_pack::{command::run_wasm_pack, Cli}; @@ -16,7 +16,9 @@ mod installer; fn main() { env_logger::init(); - setup_panic!(); + + setup_panic_hooks(); + if let Err(e) = run() { eprintln!("Error: {}", e); for cause in e.iter_causes() { @@ -49,3 +51,29 @@ fn run() -> Result<(), failure::Error> { run_wasm_pack(args.cmd)?; Ok(()) } + +fn setup_panic_hooks() { + let meta = human_panic::Metadata { + version: env!("CARGO_PKG_VERSION").into(), + name: env!("CARGO_PKG_NAME").into(), + authors: env!("CARGO_PKG_AUTHORS").replace(":", ", ").into(), + homepage: env!("CARGO_PKG_HOMEPAGE").into(), + }; + + let default_hook = panic::take_hook(); + + match env::var("RUST_BACKTRACE") { + Err(_) => { + panic::set_hook(Box::new(move |info: &panic::PanicInfo| { + // First call the default hook that prints to standard error. + default_hook(info); + + // Then call human_panic. + let file_path = human_panic::handle_dump(&meta, info); + human_panic::print_msg(file_path, &meta) + .expect("human-panic: printing error message to console failed"); + })); + } + Ok(_) => {} + } +} From f17e65954c255fadf0b9606ab5192154d84f7af7 Mon Sep 17 00:00:00 2001 From: ibaryshnikov Date: Sun, 24 Mar 2019 21:55:19 +0300 Subject: [PATCH 3/9] added tests for --out-name flag --- src/manifest/mod.rs | 2 +- tests/all/manifest.rs | 47 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 3dfb6126..25047d62 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -349,7 +349,7 @@ impl CrateData { } /// Get the prefix for output file names - fn name_prefix(&self) -> String { + pub fn name_prefix(&self) -> String { match &self.out_name { Some(value) => value.clone(), None => self.crate_name(), diff --git a/tests/all/manifest.rs b/tests/all/manifest.rs index 31ef3abc..099ad318 100644 --- a/tests/all/manifest.rs +++ b/tests/all/manifest.rs @@ -21,6 +21,22 @@ fn it_gets_the_crate_name_provided_path() { assert_eq!(crate_data.crate_name(), "js_hello_world"); } +#[test] +fn it_gets_the_default_name_prefix() { + let path = &PathBuf::from("."); + let crate_data = manifest::CrateData::new(&path, None).unwrap(); + let name = crate_data.name_prefix(); + assert_eq!(name, "wasm_pack"); +} + +#[test] +fn it_gets_the_name_prefix_passed_from_cli() { + let path = &PathBuf::from("."); + let crate_data = manifest::CrateData::new(&path, Some("index".to_owned())).unwrap(); + let name = crate_data.name_prefix(); + assert_eq!(name, "index"); +} + #[test] fn it_checks_has_cdylib_default_path() { let fixture = fixture::no_cdylib(); @@ -215,6 +231,37 @@ fn it_creates_a_pkg_json_with_correct_files_on_nomodules() { assert_eq!(actual_files, expected_files); } +#[test] +fn it_creates_a_package_json_with_correct_files_when_out_name_is_provided() { + let fixture = fixture::js_hello_world(); + let out_dir = fixture.path.join("pkg"); + let crate_data = manifest::CrateData::new(&fixture.path, Some("index".to_owned())).unwrap(); + wasm_pack::command::utils::create_pkg_dir(&out_dir).unwrap(); + assert!(crate_data + .write_package_json(&out_dir, &None, false, &Target::Bundler) + .is_ok()); + let package_json_path = &fixture.path.join("pkg").join("package.json"); + fs::metadata(package_json_path).unwrap(); + utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); + let pkg = utils::manifest::read_package_json(&fixture.path, &out_dir).unwrap(); + assert_eq!(pkg.name, "js-hello-world"); + assert_eq!(pkg.repository.ty, "git"); + assert_eq!( + pkg.repository.url, + "https://github.com/rustwasm/wasm-pack.git" + ); + assert_eq!(pkg.module, "index.js"); + assert_eq!(pkg.types, "index.d.ts"); + assert_eq!(pkg.side_effects, "false"); + + let actual_files: HashSet = pkg.files.into_iter().collect(); + let expected_files: HashSet = ["index_bg.wasm", "index.d.ts", "index.js"] + .iter() + .map(|&s| String::from(s)) + .collect(); + assert_eq!(actual_files, expected_files); +} + #[test] fn it_creates_a_pkg_json_in_out_dir() { let fixture = fixture::js_hello_world(); From 00a6ec8e94ef25d922c36568079b4b6465585ea1 Mon Sep 17 00:00:00 2001 From: ibaryshnikov Date: Mon, 25 Mar 2019 02:24:25 +0300 Subject: [PATCH 4/9] updated docs for --out-name flag --- docs/src/commands/build.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/src/commands/build.md b/docs/src/commands/build.md index 8058e184..e235202c 100644 --- a/docs/src/commands/build.md +++ b/docs/src/commands/build.md @@ -34,13 +34,20 @@ of the default `pkg`. ## Output file names -Set output file names. Defaults to package name. +Flag `--out-name` sets the prefix for output file names. If not provided, package name is used instead. + +Usage examples, assuming our crate is named `dom`: ``` +wasm-pack build +# will produce files +# dom.d.ts dom.js dom_bg.d.ts dom_bg.wasm package.json README.md + wasm-pack build --out-name index +# will produce files +# index.d.ts index.js index_bg.d.ts index_bg.wasm package.json README.md ``` -This command will build the package with file names like `index.js`, `index.d.ts`, and so on. ## Profile From c8f03591ee82b87d0fc43bc0dd3f745e2ecd809c Mon Sep 17 00:00:00 2001 From: Jacob Date: Wed, 27 Mar 2019 05:35:42 -0300 Subject: [PATCH 5/9] Fixed a single typo --- docs/src/commands/build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/commands/build.md b/docs/src/commands/build.md index 00ab2e9a..b1769b1f 100644 --- a/docs/src/commands/build.md +++ b/docs/src/commands/build.md @@ -37,7 +37,7 @@ of the default `pkg`. The `build` command accepts an optional profile argument: one of `--dev`, `--profiling`, or `--release`. If none is supplied, then `--release` is used. -Th controls whether debug assertions are enabled, debug info is generated, and +This controls whether debug assertions are enabled, debug info is generated, and which (if any) optimizations are enabled. | Profile | Debug Assertions | Debug Info | Optimizations | Notes | From 12fcdad8b43d6c6a83f9c76bc74a3fb6b15564e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20H=C3=A5kansson?= Date: Sat, 23 Mar 2019 15:07:39 +0100 Subject: [PATCH 6/9] fix: Improve error message when wasm32-unknown-unknown is missing doc: Write about adding wasm32-unknown-unknown manually --- docs/src/SUMMARY.md | 1 + docs/src/non-rustup-setups.md | 37 +++++++++++++++++ docs/src/prerequisites/index.md | 2 + src/build.rs | 70 ++++++++++++++++++++++++++++++--- 4 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 docs/src/non-rustup-setups.md diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index a59ee16d..743e50fc 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -25,4 +25,5 @@ - [Packaging and publishing](./tutorials/npm-browser-packages/packaging-and-publishing.md) - [Using your library](./tutorials/npm-browser-packages/using-your-library.md) - [`Cargo.toml` Configuration](./cargo-toml-configuration.md) +- [Non-rustup setups](./non-rustup-setups.md) - [Contributing](./contributing.md) diff --git a/docs/src/non-rustup-setups.md b/docs/src/non-rustup-setups.md new file mode 100644 index 00000000..5171bdca --- /dev/null +++ b/docs/src/non-rustup-setups.md @@ -0,0 +1,37 @@ +# Non-Rustup setups +`wasm-pack` compiles your code using the `wasm32-unknown-unknown` target. `wasm-pack` will automatically add this target for Rustup setups if you don't already have it installed by doing `rustup target add wasm32-unknown-unknown`. However, if you're not using Rustup we won't be able to this automatically and you'll have to do this yourself. + +## Manually add wasm32-unknown-unknown +*Disclaimer: This is not guaranteed to work for every setup. These instructions below are specific for setups that match the exact rustc release, which means that the downloaded wasm32 target can be incompatible.* + +To manually add the `wasm32-unknown-unknown` target you will need to download it from the rust-lang website and put the contents in the correct folder. + +All the targets for all the different `rustc` versions are not presented in a human way on a website (yet) for you to just select the one you want and download it, one reason for this is that Rustup handles all of this for you and the packaging of targets was mainly built for tools. However, the following steps will walk through how to do this. + +First, check what version of `rustc` you're using by running `rustc --version`. This should display something like: `rustc 1.33.0 (2aa4c46cf 2019-02-28)`. Then you need to download the correct wasm32 target for your rustc version. The rustc version is part of the url, which means for `rustc 1.33.0` the url will look like this: `https://static.rust-lang.org/dist/rust-std-1.33.0-wasm32-unknown-unknown.tar.gz`. + +Here's some examples of urls for different rustc versions: + * Nightly https://static.rust-lang.org/dist/rust-std-nightly-wasm32-unknown-unknown.tar.gz + * Specific date nightly (2019-03-10) https://static.rust-lang.org/dist/2019-03-10/rust-std-nightly-wasm32-unknown-unknown.tar.gz + * Beta https://static.rust-lang.org/dist/rust-std-beta-wasm32-unknown-unknown.tar.gz + +You should be able to download this either by doing `wget https://static.rust-lang.org/dist/rust-std-1.33.0-wasm32-unknown-unknown.tar.gz` or by just visiting the url in a web browser. + +After you have downloaded this tarball at a location of your choice, you should unpack it. This should result in a folder named `rust-std-1.33.0-wasm32-unknown-unknown` that contains some folders and files, but the interesting one is a folder called `rust-std-wasm32-unknown-unknown` which contains a `lib` and that should contain a `rustlib` folder and in that, a folder called `wasm32-unknown-unknown`. This is the folder we want to move. + +Here's how the structure should look like for rustc 1.33.0: +``` +rust-std-1.33.0-wasm32-unknown-unknown +├── components +├── install.sh +├── rust-installer-version +└── rust-std-wasm32-unknown-unknown + ├── lib + │   └── rustlib + │   └── wasm32-unknown-unknown +``` + +To know where we should move this `wasm32-unknown-unknown` folder we need to run `rustc --print sysroot` which should print a path that looks something like this (this will vary on different operating systems): `/home/user/rust/rust-1.33.0-2019-02-28-2aa4c46cf`. That folder should contain a `lib` folder that contains a `rustlib` folder. We should move the `wasm32-unknown-unknown` to this folder. + +On unix-like operating systems we can do that with the following command: +`mv rust-std-1.33.0-wasm32-unknown-unknown/rust-std-wasm32-unknown-unknown/lib/rustlib/wasm32-unknown-unknown /home/user/rust/rust-1.33.0-2019-02-28-2aa4c46cf/lib/rustlib/` and that should be it! diff --git a/docs/src/prerequisites/index.md b/docs/src/prerequisites/index.md index c537f70c..1d295d6d 100644 --- a/docs/src/prerequisites/index.md +++ b/docs/src/prerequisites/index.md @@ -17,3 +17,5 @@ you're excited about that work- you should reach out to the maintainers and get involved! [npm]: prerequisites/npm.html + +Using a non-rustup setup? Learn how to configure it for wasm-pack [here](./non-rustup-setups.html). diff --git a/src/build.rs b/src/build.rs index 2b32b674..8c577743 100644 --- a/src/build.rs +++ b/src/build.rs @@ -5,6 +5,7 @@ use command::build::BuildProfile; use emoji; use failure::{Error, ResultExt}; use log::info; +use std::fmt; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; @@ -80,20 +81,77 @@ fn is_wasm32_target_in_sysroot(sysroot: &PathBuf) -> bool { } } -fn check_wasm32_target() -> Result { +struct Wasm32Check { + rustc_path: PathBuf, + sysroot: PathBuf, + found: bool, + is_rustup: bool, +} + +impl fmt::Display for Wasm32Check { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let target = "wasm32-unknown-unknown"; + + if self.found { + let rustup_string = if self.is_rustup { + "It looks like Rustup is being used.".to_owned() + } else { + format!("It looks like Rustup is not being used. For non-Rustup setups, the {} target needs to be installed manually. See https://rustwasm.github.io/wasm-pack/book/prerequisites/index.html#target-wasm32-unknown-unknown on how to do this.", target) + }; + + writeln!( + f, + "{} target not found in sysroot: {:?}", + target, self.sysroot + ) + .and_then(|_| { + writeln!( + f, + "\nUsed rustc from the following path: {:?}", + self.rustc_path + ) + }) + .and_then(|_| writeln!(f, "{}", rustup_string)) + } else { + write!( + f, + "sysroot: {:?}, rustc path: {:?}, was found: {}, isRustup: {}", + self.sysroot, self.rustc_path, self.found, self.is_rustup + ) + } + } +} + +fn check_wasm32_target() -> Result { let sysroot = get_rustc_sysroot()?; + let rustc_path = which::which("rustc")?; // If wasm32-unknown-unknown already exists we're ok. if is_wasm32_target_in_sysroot(&sysroot) { - Ok(true) + Ok(Wasm32Check { + rustc_path, + sysroot, + found: true, + is_rustup: false, + }) // If it doesn't exist, then we need to check if we're using rustup. } else { // If sysroot contains .rustup, then we can assume we're using rustup // and use rustup to add the wasm32-unknown-unknown target. if sysroot.to_string_lossy().contains(".rustup") { - rustup_add_wasm_target().map(|()| true) + rustup_add_wasm_target().map(|()| Wasm32Check { + rustc_path, + sysroot, + found: true, + is_rustup: true, + }) } else { - Ok(false) + Ok(Wasm32Check { + rustc_path, + sysroot, + found: false, + is_rustup: false, + }) } } } @@ -115,8 +173,8 @@ pub fn check_for_wasm32_target() -> Result<(), Error> { // Check if wasm32 target is present, otherwise bail. match check_wasm32_target() { - Ok(true) => Ok(()), - Ok(false) => bail!("wasm32-unknown-unknown target not found!"), + Ok(ref wasm32_check) if wasm32_check.found => Ok(()), + Ok(wasm32_check) => bail!("{}", wasm32_check), Err(err) => Err(err), } } From 735c5865a215f76f5699cd2f6a813149abddc1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20H=C3=A5kansson?= Date: Wed, 27 Mar 2019 22:01:06 +0100 Subject: [PATCH 7/9] refactor: Move wasm32 checking to it's own file --- src/build/mod.rs | 97 +++++++++++++ src/{build.rs => build/wasm_target.rs} | 185 +++++++------------------ src/command/build.rs | 2 +- src/command/test.rs | 2 +- 4 files changed, 148 insertions(+), 138 deletions(-) create mode 100644 src/build/mod.rs rename src/{build.rs => build/wasm_target.rs} (57%) diff --git a/src/build/mod.rs b/src/build/mod.rs new file mode 100644 index 00000000..2e8d3dd0 --- /dev/null +++ b/src/build/mod.rs @@ -0,0 +1,97 @@ +//! Building a Rust crate into a `.wasm` binary. + +use child; +use command::build::BuildProfile; +use emoji; +use failure::{Error, ResultExt}; +use std::path::Path; +use std::process::Command; +use std::str; +use PBAR; + +pub mod wasm_target; + +/// Ensure that `rustc` is present and that it is >= 1.30.0 +pub fn check_rustc_version() -> Result { + let local_minor_version = rustc_minor_version(); + match local_minor_version { + Some(mv) => { + if mv < 30 { + bail!( + "Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.", + mv.to_string() + ) + } else { + Ok(mv.to_string()) + } + } + None => bail!("We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher."), + } +} + +// from https://github.com/alexcrichton/proc-macro2/blob/79e40a113b51836f33214c6d00228934b41bd4ad/build.rs#L44-L61 +fn rustc_minor_version() -> Option { + macro_rules! otry { + ($e:expr) => { + match $e { + Some(e) => e, + None => return None, + } + }; + } + let output = otry!(Command::new("rustc").arg("--version").output().ok()); + let version = otry!(str::from_utf8(&output.stdout).ok()); + let mut pieces = version.split('.'); + if pieces.next() != Some("rustc 1") { + return None; + } + otry!(pieces.next()).parse().ok() +} + +/// Run `cargo build` targetting `wasm32-unknown-unknown`. +pub fn cargo_build_wasm( + path: &Path, + profile: BuildProfile, + extra_options: &Vec, +) -> Result<(), Error> { + let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE); + PBAR.info(&msg); + let mut cmd = Command::new("cargo"); + cmd.current_dir(path).arg("build").arg("--lib"); + match profile { + BuildProfile::Profiling => { + // Once there are DWARF debug info consumers, force enable debug + // info, because builds that use the release cargo profile disables + // debug info. + // + // cmd.env("RUSTFLAGS", "-g"); + cmd.arg("--release"); + } + BuildProfile::Release => { + cmd.arg("--release"); + } + BuildProfile::Dev => { + // Plain cargo builds use the dev cargo profile, which includes + // debug info by default. + } + } + cmd.arg("--target").arg("wasm32-unknown-unknown"); + cmd.args(extra_options); + child::run(cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?; + Ok(()) +} + +/// Run `cargo build --tests` targetting `wasm32-unknown-unknown`. +/// +/// This generates the `Cargo.lock` file that we use in order to know which version of +/// wasm-bindgen-cli to use when running tests. +pub fn cargo_build_wasm_tests(path: &Path, debug: bool) -> Result<(), Error> { + let mut cmd = Command::new("cargo"); + cmd.current_dir(path).arg("build").arg("--tests"); + if !debug { + cmd.arg("--release"); + } + cmd.arg("--target").arg("wasm32-unknown-unknown"); + child::run(cmd, "cargo build").context("Compilation of your program failed")?; + Ok(()) +} diff --git a/src/build.rs b/src/build/wasm_target.rs similarity index 57% rename from src/build.rs rename to src/build/wasm_target.rs index 8c577743..ccd3c4bc 100644 --- a/src/build.rs +++ b/src/build/wasm_target.rs @@ -1,86 +1,14 @@ -//! Building a Rust crate into a `.wasm` binary. +//! Checking for the wasm32 target use child; -use command::build::BuildProfile; use emoji; use failure::{Error, ResultExt}; use log::info; use std::fmt; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; use std::process::Command; -use std::str; use PBAR; -/// Ensure that `rustc` is present and that it is >= 1.30.0 -pub fn check_rustc_version() -> Result { - let local_minor_version = rustc_minor_version(); - match local_minor_version { - Some(mv) => { - if mv < 30 { - bail!( - "Your version of Rust, '1.{}', is not supported. Please install Rust version 1.30.0 or higher.", - mv.to_string() - ) - } else { - Ok(mv.to_string()) - } - } - None => bail!("We can't figure out what your Rust version is- which means you might not have Rust installed. Please install Rust version 1.30.0 or higher."), - } -} - -// from https://github.com/alexcrichton/proc-macro2/blob/79e40a113b51836f33214c6d00228934b41bd4ad/build.rs#L44-L61 -fn rustc_minor_version() -> Option { - macro_rules! otry { - ($e:expr) => { - match $e { - Some(e) => e, - None => return None, - } - }; - } - let output = otry!(Command::new("rustc").arg("--version").output().ok()); - let version = otry!(str::from_utf8(&output.stdout).ok()); - let mut pieces = version.split('.'); - if pieces.next() != Some("rustc 1") { - return None; - } - otry!(pieces.next()).parse().ok() -} - -/// Get rustc's sysroot as a PathBuf -fn get_rustc_sysroot() -> Result { - let command = Command::new("rustc") - .args(&["--print", "sysroot"]) - .output()?; - - if command.status.success() { - Ok(String::from_utf8(command.stdout)?.trim().into()) - } else { - Err(format_err!( - "Getting rustc's sysroot wasn't successful. Got {}", - command.status - )) - } -} - -/// Checks if the wasm32-unknown-unknown is present in rustc's sysroot. -fn is_wasm32_target_in_sysroot(sysroot: &PathBuf) -> bool { - let wasm32_target = "wasm32-unknown-unknown"; - - let rustlib_path = sysroot.join("lib/rustlib"); - - info!("Looking for {} in {:?}", wasm32_target, rustlib_path); - - if rustlib_path.join(wasm32_target).exists() { - info!("Found {} in {:?}", wasm32_target, rustlib_path); - true - } else { - info!("Failed to find {} in {:?}", wasm32_target, rustlib_path); - false - } -} - struct Wasm32Check { rustc_path: PathBuf, sysroot: PathBuf, @@ -122,6 +50,53 @@ impl fmt::Display for Wasm32Check { } } +/// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for +/// current toolchain +pub fn check_for_wasm32_target() -> Result<(), Error> { + let msg = format!("{}Checking for the Wasm target...", emoji::TARGET); + PBAR.info(&msg); + + // Check if wasm32 target is present, otherwise bail. + match check_wasm32_target() { + Ok(ref wasm32_check) if wasm32_check.found => Ok(()), + Ok(wasm32_check) => bail!("{}", wasm32_check), + Err(err) => Err(err), + } +} + +/// Get rustc's sysroot as a PathBuf +fn get_rustc_sysroot() -> Result { + let command = Command::new("rustc") + .args(&["--print", "sysroot"]) + .output()?; + + if command.status.success() { + Ok(String::from_utf8(command.stdout)?.trim().into()) + } else { + Err(format_err!( + "Getting rustc's sysroot wasn't successful. Got {}", + command.status + )) + } +} + +/// Checks if the wasm32-unknown-unknown is present in rustc's sysroot. +fn is_wasm32_target_in_sysroot(sysroot: &PathBuf) -> bool { + let wasm32_target = "wasm32-unknown-unknown"; + + let rustlib_path = sysroot.join("lib/rustlib"); + + info!("Looking for {} in {:?}", wasm32_target, rustlib_path); + + if rustlib_path.join(wasm32_target).exists() { + info!("Found {} in {:?}", wasm32_target, rustlib_path); + true + } else { + info!("Failed to find {} in {:?}", wasm32_target, rustlib_path); + false + } +} + fn check_wasm32_target() -> Result { let sysroot = get_rustc_sysroot()?; let rustc_path = which::which("rustc")?; @@ -164,65 +139,3 @@ fn rustup_add_wasm_target() -> Result<(), Error> { Ok(()) } - -/// Ensure that `rustup` has the `wasm32-unknown-unknown` target installed for -/// current toolchain -pub fn check_for_wasm32_target() -> Result<(), Error> { - let msg = format!("{}Checking for the Wasm target...", emoji::TARGET); - PBAR.info(&msg); - - // Check if wasm32 target is present, otherwise bail. - match check_wasm32_target() { - Ok(ref wasm32_check) if wasm32_check.found => Ok(()), - Ok(wasm32_check) => bail!("{}", wasm32_check), - Err(err) => Err(err), - } -} - -/// Run `cargo build` targetting `wasm32-unknown-unknown`. -pub fn cargo_build_wasm( - path: &Path, - profile: BuildProfile, - extra_options: &Vec, -) -> Result<(), Error> { - let msg = format!("{}Compiling to Wasm...", emoji::CYCLONE); - PBAR.info(&msg); - let mut cmd = Command::new("cargo"); - cmd.current_dir(path).arg("build").arg("--lib"); - match profile { - BuildProfile::Profiling => { - // Once there are DWARF debug info consumers, force enable debug - // info, because builds that use the release cargo profile disables - // debug info. - // - // cmd.env("RUSTFLAGS", "-g"); - cmd.arg("--release"); - } - BuildProfile::Release => { - cmd.arg("--release"); - } - BuildProfile::Dev => { - // Plain cargo builds use the dev cargo profile, which includes - // debug info by default. - } - } - cmd.arg("--target").arg("wasm32-unknown-unknown"); - cmd.args(extra_options); - child::run(cmd, "cargo build").context("Compiling your crate to WebAssembly failed")?; - Ok(()) -} - -/// Run `cargo build --tests` targetting `wasm32-unknown-unknown`. -/// -/// This generates the `Cargo.lock` file that we use in order to know which version of -/// wasm-bindgen-cli to use when running tests. -pub fn cargo_build_wasm_tests(path: &Path, debug: bool) -> Result<(), Error> { - let mut cmd = Command::new("cargo"); - cmd.current_dir(path).arg("build").arg("--tests"); - if !debug { - cmd.arg("--release"); - } - cmd.arg("--target").arg("wasm32-unknown-unknown"); - child::run(cmd, "cargo build").context("Compilation of your program failed")?; - Ok(()) -} diff --git a/src/command/build.rs b/src/command/build.rs index 9ce9890c..b92bb95a 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -299,7 +299,7 @@ impl Build { fn step_check_for_wasm_target(&mut self) -> Result<(), Error> { info!("Checking for wasm-target..."); - build::check_for_wasm32_target()?; + build::wasm_target::check_for_wasm32_target()?; info!("Checking for wasm-target was successful."); Ok(()) } diff --git a/src/command/test.rs b/src/command/test.rs index 67436aad..7ca5ff7b 100644 --- a/src/command/test.rs +++ b/src/command/test.rs @@ -236,7 +236,7 @@ impl Test { fn step_check_for_wasm_target(&mut self) -> Result<(), Error> { info!("Adding wasm-target..."); - build::check_for_wasm32_target()?; + build::wasm_target::check_for_wasm32_target()?; info!("Adding wasm-target was successful."); Ok(()) } From 92b80f6395f7ee02f81cda1e2eee2affd0b1e779 Mon Sep 17 00:00:00 2001 From: ibaryshnikov Date: Fri, 29 Mar 2019 23:48:36 +0300 Subject: [PATCH 8/9] updated docs title for --out-name flag --- docs/src/commands/build.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/commands/build.md b/docs/src/commands/build.md index e235202c..28bbdfe9 100644 --- a/docs/src/commands/build.md +++ b/docs/src/commands/build.md @@ -32,7 +32,7 @@ wasm-pack build --out-dir out The above command will put your build artifacts in a directory called `out`, instead of the default `pkg`. -## Output file names +## Generated file names Flag `--out-name` sets the prefix for output file names. If not provided, package name is used instead. From 2bf330868d914e1d05071d003b21ebea63608106 Mon Sep 17 00:00:00 2001 From: Ashley Williams Date: Fri, 29 Mar 2019 15:49:34 -0500 Subject: [PATCH 9/9] fix(doc): put non rustup conetnt in the right spot --- docs/src/SUMMARY.md | 2 +- docs/src/{ => prerequisites}/non-rustup-setups.md | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/src/{ => prerequisites}/non-rustup-setups.md (100%) diff --git a/docs/src/SUMMARY.md b/docs/src/SUMMARY.md index 743e50fc..a2ced358 100644 --- a/docs/src/SUMMARY.md +++ b/docs/src/SUMMARY.md @@ -2,6 +2,7 @@ - [Prerequisites](./prerequisites/index.md) - [npm (optional)](./prerequisites/npm.md) + - [Non-`rustup` setups](./prerequisites/non-rustup-setups.md) - [Commands](./commands/index.md) - [`build`](./commands/build.md) - [`test`](./commands/test.md) @@ -25,5 +26,4 @@ - [Packaging and publishing](./tutorials/npm-browser-packages/packaging-and-publishing.md) - [Using your library](./tutorials/npm-browser-packages/using-your-library.md) - [`Cargo.toml` Configuration](./cargo-toml-configuration.md) -- [Non-rustup setups](./non-rustup-setups.md) - [Contributing](./contributing.md) diff --git a/docs/src/non-rustup-setups.md b/docs/src/prerequisites/non-rustup-setups.md similarity index 100% rename from docs/src/non-rustup-setups.md rename to docs/src/prerequisites/non-rustup-setups.md