diff --git a/crates/core/test-utils/src/cli.rs b/crates/core/test-utils/src/cli.rs index c49ee399615..79a04af81c9 100644 --- a/crates/core/test-utils/src/cli.rs +++ b/crates/core/test-utils/src/cli.rs @@ -18,8 +18,6 @@ pub fn create_moon_command>(path: T) -> assert_cmd::Command { // Enable logging for code coverage cmd.env("MOON_LOG", "trace"); cmd.env("PROTO_LOG", "trace"); - // Feature flags - // cmd.env("MOON_DISABLE_OVERLAPPING_OUTPUTS", "true"); cmd } diff --git a/nextgen/config/src/workspace/experiments_config.rs b/nextgen/config/src/workspace/experiments_config.rs new file mode 100644 index 00000000000..ed99836734e --- /dev/null +++ b/nextgen/config/src/workspace/experiments_config.rs @@ -0,0 +1,10 @@ +use moon_common::cacheable; +use schematic::{env, Config}; + +cacheable!( + #[derive(Config, Debug)] + pub struct ExperimentsConfig { + #[setting(default = true, env = "MOON_DISABLE_OVERLAPPING_OUTPUTS", parse_env = env::parse_bool)] + pub task_output_boundaries: bool, + } +); diff --git a/nextgen/config/src/workspace/mod.rs b/nextgen/config/src/workspace/mod.rs index ddcadaf668f..8dab1e3e257 100644 --- a/nextgen/config/src/workspace/mod.rs +++ b/nextgen/config/src/workspace/mod.rs @@ -1,5 +1,6 @@ mod codeowners_config; mod constraints_config; +mod experiments_config; mod generator_config; mod hasher_config; mod notifier_config; @@ -8,6 +9,7 @@ mod vcs_config; pub use codeowners_config::*; pub use constraints_config::*; +pub use experiments_config::*; pub use generator_config::*; pub use hasher_config::*; pub use notifier_config::*; diff --git a/nextgen/config/src/workspace_config.rs b/nextgen/config/src/workspace_config.rs index 9117d678b5d..027d2d9d7f3 100644 --- a/nextgen/config/src/workspace_config.rs +++ b/nextgen/config/src/workspace_config.rs @@ -98,6 +98,9 @@ pub struct WorkspaceConfig { #[setting(nested)] pub constraints: ConstraintsConfig, + #[setting(nested)] + pub experiments: ExperimentsConfig, + #[setting(extend, validate = validate::extends_string)] pub extends: Option, diff --git a/nextgen/project-graph/src/project_graph.rs b/nextgen/project-graph/src/project_graph.rs index 6ded9c7b8fc..fef7327f422 100644 --- a/nextgen/project-graph/src/project_graph.rs +++ b/nextgen/project-graph/src/project_graph.rs @@ -1,7 +1,7 @@ use crate::project_graph_error::ProjectGraphError; use miette::IntoDiagnostic; use moon_common::path::WorkspaceRelativePathBuf; -use moon_common::{color, is_test_env, Id}; +use moon_common::{color, Id}; use moon_config::DependencyScope; use moon_project::Project; use moon_project_expander::{ExpanderContext, ExpansionBoundaries, ProjectExpander}; @@ -15,7 +15,6 @@ use petgraph::Direction; use rustc_hash::FxHashMap; use serde::Serialize; use starbase_utils::json; -use std::env; use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; use tracing::{debug, trace}; @@ -66,8 +65,7 @@ impl ProjectGraph { projects: Arc::new(RwLock::new(FxHashMap::default())), workspace_root: workspace_root.to_owned(), query_cache: OnceMap::new(), - check_boundaries: !is_test_env() - && env::var("MOON_DISABLE_OVERLAPPING_OUTPUTS").is_err(), + check_boundaries: false, } } diff --git a/nextgen/project-graph/src/project_graph_builder.rs b/nextgen/project-graph/src/project_graph_builder.rs index 3e05c68bb19..384e20a9797 100644 --- a/nextgen/project-graph/src/project_graph_builder.rs +++ b/nextgen/project-graph/src/project_graph_builder.rs @@ -6,6 +6,7 @@ use crate::project_graph_hash::ProjectGraphHash; use crate::projects_locator::locate_projects_with_globs; use async_recursion::async_recursion; use moon_cache::CacheEngine; +use moon_common::is_test_env; use moon_common::path::{to_virtual_string, WorkspaceRelativePath, WorkspaceRelativePathBuf}; use moon_common::{color, consts, Id}; use moon_config::{InheritedTasksManager, ToolchainConfig, WorkspaceConfig, WorkspaceProjects}; @@ -151,6 +152,7 @@ impl<'app> ProjectGraphBuilder<'app> { pub async fn build(mut self) -> miette::Result { self.enforce_constraints()?; + let context = self.context.take().unwrap(); let mut nodes = FxHashMap::default(); for (id, index) in self.nodes { @@ -172,11 +174,12 @@ impl<'app> ProjectGraphBuilder<'app> { }); } - Ok(ProjectGraph::new( - self.graph, - nodes, - self.context.unwrap().workspace_root, - )) + let mut graph = ProjectGraph::new(self.graph, nodes, context.workspace_root); + + graph.check_boundaries = + !is_test_env() && context.workspace_config.experiments.task_output_boundaries; + + Ok(graph) } /// Load a single project by name or alias into the graph. diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 7a2926d7775..e4cdf40c4bf 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -15,6 +15,8 @@ - Graph edges now indicate the type of relationship: development, production, build, peer. - Updated `moon project-graph --json` to include the fully expanded graph data. - Identifiers (project names, file groups, etc) can now be prefixed with underscores (`_`). +- Added Poetry detection support for Python projects. +- Added an `experiments` setting to `.moon/workspace.yml`. - **Tasks** - Environment variables in `command` and `args` are now substituted. - Task `deps` can now depend on tag targets (`#tag:task`). diff --git a/packages/types/src/project-config.ts b/packages/types/src/project-config.ts index a37f2972a12..4b998b3b676 100644 --- a/packages/types/src/project-config.ts +++ b/packages/types/src/project-config.ts @@ -97,7 +97,7 @@ export interface PartialProjectConfig { export interface DependencyConfig { id: string; scope: DependencyScope; - source: DependencySource | null; + source: DependencySource; via: string | null; } diff --git a/packages/types/src/workspace-config.ts b/packages/types/src/workspace-config.ts index 346eb56053c..5b934093b13 100644 --- a/packages/types/src/workspace-config.ts +++ b/packages/types/src/workspace-config.ts @@ -16,6 +16,11 @@ export interface PartialConstraintsConfig { tagRelationships?: Record | null; } +export interface PartialExperimentsConfig { + /** @default true */ + taskOutputBoundaries?: boolean | null; +} + export interface PartialGeneratorConfig { templates?: string[] | null; } @@ -77,6 +82,7 @@ export interface PartialWorkspaceConfig { $schema?: string | null; codeowners?: PartialCodeownersConfig | null; constraints?: PartialConstraintsConfig | null; + experiments?: PartialExperimentsConfig | null; extends?: string | null; generator?: PartialGeneratorConfig | null; hasher?: PartialHasherConfig | null; @@ -101,6 +107,11 @@ export interface ConstraintsConfig { tagRelationships: Record; } +export interface ExperimentsConfig { + /** @default true */ + taskOutputBoundaries: boolean; +} + export interface GeneratorConfig { templates: string[]; } @@ -151,6 +162,7 @@ export interface WorkspaceConfig { $schema: string; codeowners: CodeownersConfig; constraints: ConstraintsConfig; + experiments: ExperimentsConfig; extends: string | null; generator: GeneratorConfig; hasher: HasherConfig; diff --git a/website/docs/config/workspace.mdx b/website/docs/config/workspace.mdx index 1d3ee900666..730c2c54d4e 100644 --- a/website/docs/config/workspace.mdx +++ b/website/docs/config/workspace.mdx @@ -204,6 +204,25 @@ dependsOn: ['components'] tags: ['react'] ``` +## `experiments` + + + +Enable or disable experiments that alter core functionality. + +### `taskOutputBoundaries` + + + +Enforces strict boundaries for task outputs and will error when multiple tasks write to the same +output location. This includes output globs that overlap with literal output file paths. Defaults to +`true`, and will be fully enabled by default in a future release. + +```yaml title=".moon/workspace.yml" {2} +experiments: + taskOutputBoundaries: false +``` + ## `generator` diff --git a/website/static/schemas/workspace.json b/website/static/schemas/workspace.json index f2e3d096b2e..a4c052e2d00 100644 --- a/website/static/schemas/workspace.json +++ b/website/static/schemas/workspace.json @@ -35,6 +35,16 @@ } ] }, + "experiments": { + "anyOf": [ + { + "$ref": "#/definitions/PartialExperimentsConfig" + }, + { + "type": "null" + } + ] + }, "extends": { "anyOf": [ { @@ -233,6 +243,24 @@ }, "additionalProperties": false }, + "PartialExperimentsConfig": { + "title": "PartialExperimentsConfig", + "type": "object", + "properties": { + "taskOutputBoundaries": { + "default": true, + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, "PartialGeneratorConfig": { "title": "PartialGeneratorConfig", "type": "object",