From 1cf619d6ab6d7b7bae88c0e67d731306fdca50da Mon Sep 17 00:00:00 2001 From: Kitson Kelly Date: Sat, 27 Apr 2019 11:57:24 +0100 Subject: [PATCH] Config changes invalidate cache. --- cli/deno_dir.rs | 70 ++++++++++++++++++++++++++++++++++++++----------- cli/state.rs | 2 +- 2 files changed, 55 insertions(+), 17 deletions(-) diff --git a/cli/deno_dir.rs b/cli/deno_dir.rs index 5dc9afed3663f5..3320addb3b15f3 100644 --- a/cli/deno_dir.rs +++ b/cli/deno_dir.rs @@ -51,12 +51,16 @@ pub struct DenoDir { // This splits to http and https deps pub deps_http: PathBuf, pub deps_https: PathBuf, + pub config: Vec, } impl DenoDir { // Must be called before using any function from this module. // https://github.com/denoland/deno/blob/golang/deno_dir.go#L99-L111 - pub fn new(custom_root: Option) -> std::io::Result { + pub fn new( + custom_root: Option, + state_config: &Option>, + ) -> std::io::Result { // Only setup once. let home_dir = dirs::home_dir().expect("Could not get home directory."); let fallback = home_dir.join(".deno"); @@ -73,12 +77,18 @@ impl DenoDir { let deps_http = deps.join("http"); let deps_https = deps.join("https"); + let config = match state_config { + Some(config) => config.clone(), + _ => b"".to_vec(), + }; + let deno_dir = Self { root, gen, deps, deps_http, deps_https, + config, }; // TODO Lazily create these directories. @@ -102,7 +112,8 @@ impl DenoDir { filename: &str, source_code: &[u8], ) -> (PathBuf, PathBuf) { - let cache_key = source_code_hash(filename, source_code, version::DENO); + let cache_key = + source_code_hash(filename, source_code, version::DENO, &self.config); ( self.gen.join(cache_key.to_string() + ".js"), self.gen.join(cache_key.to_string() + ".js.map"), @@ -156,6 +167,8 @@ impl DenoDir { let gen = self.gen.clone(); + let config = self.config.clone(); + Either::B( get_source_code_async( self, @@ -191,8 +204,12 @@ impl DenoDir { return Ok(out); } - let cache_key = - source_code_hash(&out.filename, &out.source_code, version::DENO); + let cache_key = source_code_hash( + &out.filename, + &out.source_code, + version::DENO, + &config, + ); let (output_code_filename, output_source_map_filename) = ( gen.join(cache_key.to_string() + ".js"), gen.join(cache_key.to_string() + ".js.map"), @@ -472,11 +489,13 @@ fn source_code_hash( filename: &str, source_code: &[u8], version: &str, + config: &[u8], ) -> String { let mut ctx = ring::digest::Context::new(&ring::digest::SHA1); ctx.update(version.as_bytes()); ctx.update(filename.as_bytes()); ctx.update(source_code); + ctx.update(config); let digest = ctx.finish(); let mut out = String::new(); // TODO There must be a better way to do this... @@ -860,8 +879,9 @@ mod tests { fn test_setup() -> (TempDir, DenoDir) { let temp_dir = TempDir::new().expect("tempdir fail"); - let deno_dir = - DenoDir::new(Some(temp_dir.path().to_path_buf())).expect("setup fail"); + let config = Some(b"{}".to_vec()); + let deno_dir = DenoDir::new(Some(temp_dir.path().to_path_buf()), &config) + .expect("setup fail"); (temp_dir, deno_dir) } @@ -904,7 +924,8 @@ mod tests { let (temp_dir, deno_dir) = test_setup(); let filename = "hello.js"; let source_code = b"1+2"; - let hash = source_code_hash(filename, source_code, version::DENO); + let config = b"{}"; + let hash = source_code_hash(filename, source_code, version::DENO, config); assert_eq!( ( temp_dir.path().join(format!("gen/{}.js", hash)), @@ -914,6 +935,22 @@ mod tests { ); } + #[test] + fn test_cache_path_config() { + let (temp_dir, deno_dir) = test_setup(); + let filename = "hello.js"; + let source_code = b"1+2"; + let config = b"{\"compilerOptions\":{}}"; + let hash = source_code_hash(filename, source_code, version::DENO, config); + assert_ne!( + ( + temp_dir.path().join(format!("gen/{}.js", hash)), + temp_dir.path().join(format!("gen/{}.js.map", hash)) + ), + deno_dir.cache_path(filename, source_code) + ); + } + #[test] fn test_code_cache() { let (_temp_dir, deno_dir) = test_setup(); @@ -922,7 +959,8 @@ mod tests { let source_code = b"1+2"; let output_code = b"1+2 // output code"; let source_map = b"{}"; - let hash = source_code_hash(filename, source_code, version::DENO); + let config = b"{}"; + let hash = source_code_hash(filename, source_code, version::DENO, config); let (cache_path, source_map_path) = deno_dir.cache_path(filename, source_code); assert!(cache_path.ends_with(format!("gen/{}.js", hash))); @@ -949,23 +987,23 @@ mod tests { #[test] fn test_source_code_hash() { assert_eq!( - "7e44de2ed9e0065da09d835b76b8d70be503d276", - source_code_hash("hello.ts", b"1+2", "0.2.11") + "830c8b63ba3194cf2108a3054c176b2bf53aee45", + source_code_hash("hello.ts", b"1+2", "0.2.11", b"{}") ); // Different source_code should result in different hash. assert_eq!( - "57033366cf9db1ef93deca258cdbcd9ef5f4bde1", - source_code_hash("hello.ts", b"1", "0.2.11") + "fb06127e9b2e169bea9c697fa73386ae7c901e8b", + source_code_hash("hello.ts", b"1", "0.2.11", b"{}") ); // Different filename should result in different hash. assert_eq!( - "19657f90b5b0540f87679e2fb362e7bd62b644b0", - source_code_hash("hi.ts", b"1+2", "0.2.11") + "3a17b6a493ff744b6a455071935f4bdcd2b72ec7", + source_code_hash("hi.ts", b"1+2", "0.2.11", b"{}") ); // Different version should result in different hash. assert_eq!( - "e2b4b7162975a02bf2770f16836eb21d5bcb8be1", - source_code_hash("hi.ts", b"1+2", "0.2.0") + "d6b2cfdc39dae9bd3ad5b493ee1544eb22e7475f", + source_code_hash("hi.ts", b"1+2", "0.2.0", b"{}") ); } diff --git a/cli/state.rs b/cli/state.rs index 3a8a5a1a8d9bc1..09553341817d70 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -136,7 +136,7 @@ impl ThreadSafeState { }; ThreadSafeState(Arc::new(State { - dir: deno_dir::DenoDir::new(custom_root).unwrap(), + dir: deno_dir::DenoDir::new(custom_root, &config).unwrap(), argv: argv_rest, permissions: DenoPermissions::from_flags(&flags), flags,