From 2b4475750220fb8d3c75cea59a1d9b87dba79534 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Sat, 2 Nov 2024 00:05:22 -0700 Subject: [PATCH] new: Add strict project IDs experiment. --- CHANGELOG.md | 3 ++ crates/app/src/components.rs | 1 + .../src/workspace/experiments_config.rs | 5 ++++ .../src/project_graph_builder.rs | 28 ++++++++++++++++++- crates/test-utils/src/project_graph.rs | 1 + packages/types/src/workspace-config.ts | 10 +++++++ website/docs/config/workspace.mdx | 15 ++++++++++ website/static/schemas/workspace.json | 5 ++++ 8 files changed, 67 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41faaf6e3d8..bc2e8e3068c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ #### 🚀 Updates +- Added an `experiments.strictProjectIds` setting to `.moon/workspace.yml`. When enabled, will + disallow using original IDs for renamed projects (via the `id` setting) when building the project + graph. - Updated codegen/template `destination` to be relative from the workspace root if prefixed with `/`, otherwise the current working directory. diff --git a/crates/app/src/components.rs b/crates/app/src/components.rs index cfba514a92b..22fb1169fdf 100644 --- a/crates/app/src/components.rs +++ b/crates/app/src/components.rs @@ -61,6 +61,7 @@ pub async fn create_project_graph_context( extend_project: Emitter::::new(), extend_project_graph: Emitter::::new(), inherited_tasks: &session.tasks_config, + strict_project_ids: session.workspace_config.experiments.strict_project_ids, toolchain_config: &session.toolchain_config, vcs: Some(session.get_vcs_adapter()?), working_dir: &session.working_dir, diff --git a/crates/config/src/workspace/experiments_config.rs b/crates/config/src/workspace/experiments_config.rs index d4f2befca1a..d646d6b747c 100644 --- a/crates/config/src/workspace/experiments_config.rs +++ b/crates/config/src/workspace/experiments_config.rs @@ -17,6 +17,11 @@ cacheable!( #[setting(default = true)] pub strict_project_aliases: bool, + /// Disallow referencing the original ID of a renamed project when + /// building the project graph. + // #[setting(default = true)] + pub strict_project_ids: bool, + /// Disallow task relationships with different `runInCI` options. #[setting(default = true)] pub disallow_run_in_ci_mismatch: bool, diff --git a/crates/project-graph/src/project_graph_builder.rs b/crates/project-graph/src/project_graph_builder.rs index 01c2eb92573..e61123d63f8 100644 --- a/crates/project-graph/src/project_graph_builder.rs +++ b/crates/project-graph/src/project_graph_builder.rs @@ -33,6 +33,7 @@ pub struct ProjectGraphBuilderContext<'app> { pub extend_project: Emitter, pub extend_project_graph: Emitter, pub inherited_tasks: &'app InheritedTasksManager, + pub strict_project_ids: bool, pub toolchain_config: &'app ToolchainConfig, pub vcs: Option>, pub working_dir: &'app Path, @@ -606,6 +607,7 @@ impl<'app> ProjectGraphBuilder<'app> { let context = self.context(); let mut configs = FxHashMap::default(); let mut renamed_ids = FxHashMap::default(); + let mut dupe_original_ids = FxHashSet::default(); for (id, source) in sources { debug!( @@ -621,7 +623,12 @@ impl<'app> ProjectGraphBuilder<'app> { // Track ID renames if let Some(new_id) = &config.id { if new_id != id { - renamed_ids.insert(id.to_owned(), new_id.to_owned()); + if renamed_ids.contains_key(id) { + dupe_original_ids.insert(id.to_owned()); + } else { + renamed_ids.insert(id.to_owned(), new_id.to_owned()); + } + *id = new_id.to_owned(); } } @@ -629,6 +636,17 @@ impl<'app> ProjectGraphBuilder<'app> { configs.insert(config.id.clone().unwrap_or(id.to_owned()), config); } + if !dupe_original_ids.is_empty() { + trace!( + original_ids = ?dupe_original_ids.iter().collect::>(), + "Found multiple projects with the same original ID before being renamed to a custom ID; will ignore these IDs within lookups" + ); + + for dupe_id in dupe_original_ids { + renamed_ids.remove(&dupe_id); + } + } + debug!("Loaded {} project configs", configs.len()); self.configs.extend(configs); @@ -657,6 +675,14 @@ impl<'app> ProjectGraphBuilder<'app> { } }; + if self + .context + .as_ref() + .is_some_and(|ctx| ctx.strict_project_ids) + { + return id; + } + match self.renamed_ids.get(&id) { Some(new_id) => new_id.to_owned(), None => id, diff --git a/crates/test-utils/src/project_graph.rs b/crates/test-utils/src/project_graph.rs index ff8d86fd1cc..9706048fc8a 100644 --- a/crates/test-utils/src/project_graph.rs +++ b/crates/test-utils/src/project_graph.rs @@ -98,6 +98,7 @@ impl ProjectGraphContainer { extend_project: Emitter::::new(), extend_project_graph: Emitter::::new(), inherited_tasks: &self.inherited_tasks, + strict_project_ids: self.workspace_config.experiments.strict_project_ids, toolchain_config: &self.toolchain_config, vcs: self.vcs.clone(), working_dir: &self.workspace_root, diff --git a/packages/types/src/workspace-config.ts b/packages/types/src/workspace-config.ts index d9d0fb6248b..d03b98f62d3 100644 --- a/packages/types/src/workspace-config.ts +++ b/packages/types/src/workspace-config.ts @@ -114,6 +114,11 @@ export interface ExperimentsConfig { * @deprecated */ strictProjectAliases?: boolean; + /** + * Disallow referencing the original ID of a renamed project when + * building the project graph. + */ + strictProjectIds: boolean; /** * @default true * @deprecated @@ -438,6 +443,11 @@ export interface PartialExperimentsConfig { * @deprecated */ strictProjectAliases?: boolean | null; + /** + * Disallow referencing the original ID of a renamed project when + * building the project graph. + */ + strictProjectIds?: boolean | null; /** * @default true * @deprecated diff --git a/website/docs/config/workspace.mdx b/website/docs/config/workspace.mdx index 033bddf125e..6582eeb1a65 100644 --- a/website/docs/config/workspace.mdx +++ b/website/docs/config/workspace.mdx @@ -301,6 +301,21 @@ docker: Enable or disable experiments that alter core functionality. +### `strictProjectIds` + + + +When building the project graph, disallows referencing the original ID of a project (inferred from +the folder name) when the project has been renamed to a new ID using the [`id`](./project#id) +setting. + +Defaults to `false` but will be enabled to `true` in the future. + +```yaml title=".moon/workspace.yml" {1,2} +experiments: + strictProjectIds: true +``` + ## `extensions` diff --git a/website/static/schemas/workspace.json b/website/static/schemas/workspace.json index e836d7d9f90..760504f75fd 100644 --- a/website/static/schemas/workspace.json +++ b/website/static/schemas/workspace.json @@ -326,6 +326,11 @@ "deprecated": true, "type": "boolean" }, + "strictProjectIds": { + "title": "strictProjectIds", + "description": "Disallow referencing the original ID of a renamed project when building the project graph.", + "type": "boolean" + }, "taskOutputBoundaries": { "title": "taskOutputBoundaries", "default": true,