Skip to content
This repository has been archived by the owner on Aug 3, 2023. It is now read-only.

Commit

Permalink
Preliminary "file exists" checks
Browse files Browse the repository at this point in the history
Also, use the nice AsRef<Path> idiom that works so well
  • Loading branch information
caass committed Sep 28, 2020
1 parent 67bfc70 commit 7dafd73
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 25 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ atty = "0.2.14"
base64 = "0.12.3"
billboard = "0.1.0"
binary-install = "0.0.3-alpha.1"
bytesize = "1.0.1"
chrome-devtools-rs = { version = "0.0.0-alpha.1", features = ["color"] }
chrono = "0.4.15"
clap = "2.33.3"
Expand Down
17 changes: 0 additions & 17 deletions src/build/check.rs

This file was deleted.

32 changes: 32 additions & 0 deletions src/build/check/js.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use std::{
ffi::OsString,
fmt::Debug,
fs,
path::{Path, PathBuf},
};

use bytesize::ByteSize;

const WORKER_FILE_NAME: &str = "worker.js";

pub fn check_js<P: AsRef<Path> + Debug>(file_path: P) -> Result<String, failure::Error> {
let worker_js = normalize_filename(file_path)?;
let file_size = ByteSize::b(worker_js.metadata()?.len());

Ok(format!("worker.js OK! Final size: {}", file_size))
}

fn normalize_filename<P: AsRef<Path> + Debug>(file_path: P) -> Result<PathBuf, failure::Error> {
match file_path.as_ref().file_name() {
None => Err(failure::format_err!("{:?} does not exist!", file_path)),
Some(name) if name == OsString::from(WORKER_FILE_NAME) => {
Ok(PathBuf::from(file_path.as_ref()))
}
Some(name) => {
println!("Renaming {:?} to {:?}", name, WORKER_FILE_NAME);
let worker_js = file_path.as_ref().parent().unwrap().join(WORKER_FILE_NAME);
fs::rename(&file_path, &worker_js)?;
Ok(worker_js)
}
}
}
93 changes: 93 additions & 0 deletions src/build/check/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
use std::{ffi::OsStr, fs};
use std::{
fmt::Debug,
path::{Path, PathBuf},
};

mod js;
mod wasm;

use js::check_js;
use wasm::check_wasm;

// TODO: i'm not sure whether it's better to do a pointer to an array of &str, or specify the length.
// my gut feeling is that specifying the length is better since the lengths are known at compile time
const UNAVAILABLE_BUILTINS: [&str; 2] = ["eval", "new Function"];
const AVAILABLE_BUILTINS: [&str; 5] = ["atob", "btoa", "TextEncoder", "TextDecoder", "URL"];
const AVAILABLE_WITHIN_REQUEST_CONTEXT: [&str; 5] = [
"setInterval",
"clearInterval",
"setTimeout",
"clearTimeout",
"fetch",
];

/// Run some sanity checks on a given output directory before
/// uploading. Namely:
///
/// 1. Is there a single JS file named worker.js?
/// 2. Is worker.js small enough?
/// 3. Is worker.js using only explicitly allowed features?
/// 4. Is there optionally a single WASM file named `TODO: wasm file name`?
/// 5. If so, is the file being imported correctly?
///
/// Most of these can be fixed, but some (multiple JS files, file too big, and banned functionality)
/// can't. Encountering anything unfixable will result in an error.
/// If everything goes smoothly, an Ok(String) will be returned with some info
/// about the check process.
///
pub fn check_output_dir<P: AsRef<Path> + Debug>(dir: P) -> Result<String, failure::Error> {
let wasm_file = file_with_extension(&dir, OsStr::new("wasm"))?;
let js_file = file_with_extension(&dir, OsStr::new("js"))?;

let js_result = if let Some(path) = js_file {
check_js(path)?
} else {
return Err(failure::format_err!(
"Failed to find any JS files in ${:?}",
dir,
));
};

let wasm_result = if let Some(path) = wasm_file {
check_wasm(path)?
} else {
// TODO this should be like an info-level warning
format!("No .wasm files found in {:?}", dir)
};

Ok(format!("{}\n{}", js_result, wasm_result))
}

/// Returns either Ok(Some(PathBuf)) if one file with the given extension was found
/// in the directory, or Ok(None) if there weren't any. If multiple files are found
/// with the given extension, returns failure::Error
fn file_with_extension<P: AsRef<Path> + Debug>(
dir: P,
extension: &OsStr,
) -> Result<Option<PathBuf>, failure::Error> {
let mut path: Option<PathBuf> = None;

for entry in fs::read_dir(&dir)? {
let entry = entry?;

// yo dawg, i heard you like conditionals
// so we put some conditionals in your conditionals so you can `if` while you `if`
if let Some(ext) = entry.path().extension() {
if ext == extension {
match path {
Some(_) => {
return Err(failure::format_err!(
"Found multiple files with extension {:?} in {:?}!",
extension,
&dir
));
}
None => path = Some(entry.path()),
};
}
}
}

Ok(path)
}
5 changes: 5 additions & 0 deletions src/build/check/wasm.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use std::{fmt::Debug, path::Path};

pub fn check_wasm<P: AsRef<Path> + Debug>(_path: P) -> Result<String, failure::Error> {
todo!()
}
15 changes: 7 additions & 8 deletions src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,16 @@ pub fn build_target(target: &Target) -> Result<String, failure::Error> {
Err(e) => Err(e),
},

TargetType::Bundler => match target.bundle_config {
TargetType::Bundler => match &target.bundle_config {
None => Err(failure::err_msg("Please specify bundler options!")),
Some(config) => {
if !config.build_command().spawn()?.wait()?.success() {
Err(failure::err_msg(&format!(
"Command {:?} failed!",
config.build_command()
)))
if config.build_command().spawn()?.wait()?.success() {
check::check_output_dir(config.output_dir()?)
} else {
// build command exited successfully
check::full_check(config.output_dir()?)
Err(failure::format_err!(
"Command `{:?}` failed!",
config.build_command()
))
}
}
},
Expand Down

0 comments on commit 7dafd73

Please sign in to comment.