Skip to content

Commit

Permalink
cacheDir for env, config, and flag (#8947)
Browse files Browse the repository at this point in the history
  • Loading branch information
dimitropoulos authored Aug 12, 2024
1 parent 0145168 commit 9ed775d
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 23 deletions.
7 changes: 4 additions & 3 deletions crates/turborepo-cache/src/async_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ mod tests {
use std::{assert_matches::assert_matches, time::Duration};

use anyhow::Result;
use camino::Utf8PathBuf;
use futures::future::try_join_all;
use tempfile::tempdir;
use turbopath::AbsoluteSystemPathBuf;
Expand Down Expand Up @@ -253,7 +254,7 @@ mod tests {
let hash = format!("{}-no-fs", test_case.hash);

let opts = CacheOpts {
override_dir: None,
cache_dir: Utf8PathBuf::from(".turbo/cache"),
remote_cache_read_only: false,
skip_remote: false,
skip_filesystem: true,
Expand Down Expand Up @@ -335,7 +336,7 @@ mod tests {
let hash = format!("{}-no-remote", test_case.hash);

let opts = CacheOpts {
override_dir: None,
cache_dir: Utf8PathBuf::from(".turbo/cache"),
remote_cache_read_only: false,
skip_remote: true,
skip_filesystem: false,
Expand Down Expand Up @@ -427,7 +428,7 @@ mod tests {
let hash = format!("{}-both", test_case.hash);

let opts = CacheOpts {
override_dir: None,
cache_dir: Utf8PathBuf::from(".turbo/cache"),
remote_cache_read_only: false,
skip_remote: false,
skip_filesystem: false,
Expand Down
18 changes: 9 additions & 9 deletions crates/turborepo-cache/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,18 @@ impl CacheMetadata {
impl FSCache {
fn resolve_cache_dir(
repo_root: &AbsoluteSystemPath,
override_dir: Option<&Utf8Path>,
cache_dir: &Utf8Path,
) -> AbsoluteSystemPathBuf {
if let Some(override_dir) = override_dir {
AbsoluteSystemPathBuf::from_unknown(repo_root, override_dir)
} else {
repo_root.join_components(&[".turbo", "cache"])
}
AbsoluteSystemPathBuf::from_unknown(repo_root, cache_dir)
}

#[tracing::instrument(skip_all)]
pub fn new(
override_dir: Option<&Utf8Path>,
cache_dir: &Utf8Path,
repo_root: &AbsoluteSystemPath,
analytics_recorder: Option<AnalyticsSender>,
) -> Result<Self, CacheError> {
let cache_directory = Self::resolve_cache_dir(repo_root, override_dir);
let cache_directory = Self::resolve_cache_dir(repo_root, cache_dir);
cache_directory.create_dir_all()?;

Ok(FSCache {
Expand Down Expand Up @@ -233,7 +229,11 @@ mod test {
let (analytics_sender, analytics_handle) =
start_analytics(api_auth.clone(), api_client.clone());

let cache = FSCache::new(None, repo_root_path, Some(analytics_sender.clone()))?;
let cache = FSCache::new(
Utf8Path::new(""),
repo_root_path,
Some(analytics_sender.clone()),
)?;

let expected_miss = cache.fetch(repo_root_path, test_case.hash)?;
assert!(expected_miss.is_none());
Expand Down
2 changes: 1 addition & 1 deletion crates/turborepo-cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub struct CacheHitMetadata {

#[derive(Debug, Default)]
pub struct CacheOpts {
pub override_dir: Option<Utf8PathBuf>,
pub cache_dir: Utf8PathBuf,
pub remote_cache_read_only: bool,
pub skip_remote: bool,
pub skip_filesystem: bool,
Expand Down
8 changes: 1 addition & 7 deletions crates/turborepo-cache/src/multiplexer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,7 @@ impl CacheMultiplexer {
}

let fs_cache = use_fs_cache
.then(|| {
FSCache::new(
opts.override_dir.as_deref(),
repo_root,
analytics_recorder.clone(),
)
})
.then(|| FSCache::new(&opts.cache_dir, repo_root, analytics_recorder.clone()))
.transpose()?;

let http_cache = use_http_cache
Expand Down
3 changes: 3 additions & 0 deletions crates/turborepo-lib/src/commands/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use camino::Utf8Path;
use serde::Serialize;
use turborepo_repository::{
package_graph::PackageGraph, package_json::PackageJson, package_manager::PackageManager,
Expand All @@ -24,6 +25,7 @@ struct ConfigOutput<'a> {
env_mode: EnvMode,
scm_base: &'a str,
scm_head: &'a str,
cache_dir: &'a Utf8Path,
}

pub async fn run(base: CommandBase) -> Result<(), cli::Error> {
Expand Down Expand Up @@ -55,6 +57,7 @@ pub async fn run(base: CommandBase) -> Result<(), cli::Error> {
env_mode: config.env_mode(),
scm_base: config.scm_base(),
scm_head: config.scm_head(),
cache_dir: config.cache_dir(),
})?
);
Ok(())
Expand Down
15 changes: 15 additions & 0 deletions crates/turborepo-lib/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,21 @@ impl CommandBase {
.and_then(|args| args.env_mode)
}),
)
.with_cache_dir(
self.args
.command
.as_ref()
.and_then(|c| match c {
Command::Run { execution_args, .. } => execution_args.cache_dir.clone(),
_ => None,
})
.or_else(|| {
self.args
.execution_args
.as_ref()
.and_then(|args| args.cache_dir.clone())
}),
)
.build()
}

Expand Down
52 changes: 51 additions & 1 deletion crates/turborepo-lib/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use std::{
io,
};

use camino::{Utf8Path, Utf8PathBuf};
use convert_case::{Case, Casing};
use miette::{Diagnostic, NamedSource, SourceSpan};
use serde::Deserialize;
use struct_iterable::Iterable;
use thiserror::Error;
use turbopath::{AbsoluteSystemPathBuf, AnchoredSystemPath};
use turbopath::{AbsoluteSystemPathBuf, AnchoredSystemPath, RelativeUnixPath};
use turborepo_auth::{TURBO_TOKEN_DIR, TURBO_TOKEN_FILE, VERCEL_TOKEN_DIR, VERCEL_TOKEN_FILE};
use turborepo_dirs::{config_dir, vercel_config_dir};
use turborepo_errors::TURBO_SITE;
Expand Down Expand Up @@ -161,6 +162,14 @@ pub enum Error {
#[error(transparent)]
#[diagnostic(transparent)]
TurboJsonParseError(#[from] turbo_json::parser::Error),
#[error("found absolute path in `cacheDir`")]
#[diagnostic(help("if absolute paths are required, use `--cache-dir` or `TURBO_CACHE_DIR`"))]
AbsoluteCacheDir {
#[label("make `cacheDir` value a relative unix path")]
span: Option<SourceSpan>,
#[source_code]
text: NamedSource,
},
}

macro_rules! create_builder {
Expand Down Expand Up @@ -215,6 +224,8 @@ pub struct ConfigurationOptions {
pub(crate) env_mode: Option<EnvMode>,
pub(crate) scm_base: Option<String>,
pub(crate) scm_head: Option<String>,
#[serde(rename = "cacheDir")]
pub(crate) cache_dir: Option<Utf8PathBuf>,
}

#[derive(Default)]
Expand Down Expand Up @@ -306,6 +317,16 @@ impl ConfigurationOptions {
pub fn env_mode(&self) -> EnvMode {
self.env_mode.unwrap_or_default()
}

pub fn cache_dir(&self) -> &Utf8Path {
self.cache_dir.as_deref().unwrap_or_else(|| {
Utf8Path::new(if cfg!(windows) {
".turbo\\cache"
} else {
".turbo/cache"
})
})
}
}

// Maps Some("") to None to emulate how Go handles empty strings
Expand All @@ -332,6 +353,21 @@ impl ResolvedConfigurationOptions for RawTurboJson {
} else {
ConfigurationOptions::default()
};

let cache_dir = if let Some(cache_dir) = self.cache_dir {
let cache_dir_str: &str = &cache_dir;
let cache_dir_unix = RelativeUnixPath::new(cache_dir_str).map_err(|_| {
let (span, text) = cache_dir.span_and_text("turbo.json");
Error::AbsoluteCacheDir { span, text }
})?;
// Convert the relative unix path to an anchored system path
// For unix/macos this is a no-op
let cache_dir_system = cache_dir_unix.to_anchored_system_path_buf();
Some(Utf8PathBuf::from(cache_dir_system.to_string()))
} else {
None
};

// Don't allow token to be set for shared config.
opts.token = None;
opts.spaces_id = self
Expand All @@ -342,6 +378,7 @@ impl ResolvedConfigurationOptions for RawTurboJson {
opts.allow_no_package_manager = self.allow_no_package_manager;
opts.daemon = self.daemon.map(|daemon| *daemon.as_inner());
opts.env_mode = self.env_mode;
opts.cache_dir = cache_dir;
Ok(opts)
}
}
Expand Down Expand Up @@ -380,6 +417,7 @@ fn get_env_var_config(
);
turbo_mapping.insert(OsString::from("turbo_daemon"), "daemon");
turbo_mapping.insert(OsString::from("turbo_env_mode"), "env_mode");
turbo_mapping.insert(OsString::from("turbo_cache_dir"), "cache_dir");
turbo_mapping.insert(OsString::from("turbo_preflight"), "preflight");
turbo_mapping.insert(OsString::from("turbo_scm_base"), "scm_base");
turbo_mapping.insert(OsString::from("turbo_scm_head"), "scm_head");
Expand Down Expand Up @@ -490,6 +528,8 @@ fn get_env_var_config(
_ => None,
});

let cache_dir = output_map.get("cache_dir").map(|s| s.clone().into());

// We currently don't pick up a Spaces ID via env var, we likely won't
// continue using the Spaces name, we can add an env var when we have the
// name we want to stick with.
Expand Down Expand Up @@ -517,6 +557,7 @@ fn get_env_var_config(
upload_timeout,
spaces_id,
env_mode,
cache_dir,
};

Ok(output)
Expand Down Expand Up @@ -580,6 +621,7 @@ fn get_override_env_var_config(
spaces_id: None,
allow_no_package_manager: None,
env_mode: None,
cache_dir: None,
};

Ok(output)
Expand Down Expand Up @@ -722,6 +764,7 @@ impl TurborepoConfigBuilder {
);
create_builder!(with_daemon, daemon, Option<bool>);
create_builder!(with_env_mode, env_mode, Option<EnvMode>);
create_builder!(with_cache_dir, cache_dir, Option<Utf8PathBuf>);

pub fn build(&self) -> Result<ConfigurationOptions, Error> {
// Priority, from least significant to most significant:
Expand Down Expand Up @@ -816,6 +859,9 @@ impl TurborepoConfigBuilder {
if let Some(scm_head) = current_source_config.scm_head {
acc.scm_head = Some(scm_head);
}
if let Some(cache_dir) = current_source_config.cache_dir {
acc.cache_dir = Some(cache_dir);
}

acc
})
Expand All @@ -828,6 +874,7 @@ impl TurborepoConfigBuilder {
mod test {
use std::{collections::HashMap, ffi::OsString};

use camino::Utf8PathBuf;
use tempfile::TempDir;
use turbopath::AbsoluteSystemPathBuf;

Expand Down Expand Up @@ -865,6 +912,7 @@ mod test {
let turbo_team = "vercel";
let turbo_teamid = "team_nLlpyC6REAqxydlFKbrMDlud";
let turbo_token = "abcdef1234567890abcdef";
let cache_dir = Utf8PathBuf::from("nebulo9");
let turbo_remote_cache_timeout = 200;

env.insert("turbo_api".into(), turbo_api.into());
Expand All @@ -884,6 +932,7 @@ mod test {
env.insert("turbo_daemon".into(), "true".into());
env.insert("turbo_preflight".into(), "true".into());
env.insert("turbo_env_mode".into(), "strict".into());
env.insert("turbo_cache_dir".into(), cache_dir.clone().into());

let config = get_env_var_config(&env).unwrap();
assert!(config.preflight());
Expand All @@ -897,6 +946,7 @@ mod test {
assert_eq!(Some(true), config.allow_no_package_manager);
assert_eq!(Some(true), config.daemon);
assert_eq!(Some(EnvMode::Strict), config.env_mode);
assert_eq!(cache_dir, config.cache_dir.unwrap());
}

#[test]
Expand Down
6 changes: 5 additions & 1 deletion crates/turborepo-lib/src/opts.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{backtrace, backtrace::Backtrace};

use camino::Utf8PathBuf;
use thiserror::Error;
use turbopath::AnchoredSystemPathBuf;
use turborepo_api_client::APIAuth;
Expand Down Expand Up @@ -149,6 +150,7 @@ pub struct RunOpts {
pub(crate) concurrency: u32,
pub(crate) parallel: bool,
pub(crate) env_mode: EnvMode,
pub(crate) cache_dir: Utf8PathBuf,
// Whether or not to infer the framework for each workspace.
pub(crate) framework_inference: bool,
pub profile: Option<String>,
Expand Down Expand Up @@ -263,6 +265,7 @@ impl<'a> TryFrom<OptsInputs<'a>> for RunOpts {
graph,
dry_run: inputs.run_args.dry_run,
env_mode: inputs.config.env_mode(),
cache_dir: inputs.config.cache_dir().into(),
is_github_actions,
})
}
Expand Down Expand Up @@ -358,7 +361,7 @@ impl<'a> From<OptsInputs<'a>> for CacheOpts {
));

CacheOpts {
override_dir: inputs.execution_args.cache_dir.clone(),
cache_dir: inputs.config.cache_dir().into(),
skip_filesystem: inputs.execution_args.remote_only,
remote_cache_read_only: inputs.run_args.remote_cache_read_only,
workers: inputs.run_args.cache_workers,
Expand Down Expand Up @@ -488,6 +491,7 @@ mod test {
concurrency: 10,
parallel: opts_input.parallel,
env_mode: crate::cli::EnvMode::Loose,
cache_dir: camino::Utf8PathBuf::new(),
framework_inference: true,
profile: None,
continue_on_error: opts_input.continue_on_error,
Expand Down
2 changes: 2 additions & 0 deletions crates/turborepo-lib/src/turbo_json/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ pub struct RawTurboJson {
pub daemon: Option<Spanned<bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub env_mode: Option<EnvMode>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cache_dir: Option<Spanned<UnescapedString>>,

#[deserializable(rename = "//")]
#[serde(skip)]
Expand Down
2 changes: 2 additions & 0 deletions crates/turborepo-lib/src/turbo_json/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ impl WithMetadata for RawTurboJson {
self.global_env.add_text(text.clone());
self.global_pass_through_env.add_text(text.clone());
self.tasks.add_text(text.clone());
self.cache_dir.add_text(text.clone());
self.pipeline.add_text(text);
}

Expand All @@ -115,6 +116,7 @@ impl WithMetadata for RawTurboJson {
self.global_env.add_path(path.clone());
self.global_pass_through_env.add_path(path.clone());
self.tasks.add_path(path.clone());
self.cache_dir.add_path(path.clone());
self.pipeline.add_path(path);
}
}
Expand Down
Loading

0 comments on commit 9ed775d

Please sign in to comment.