moon_config/
project_config.rs

1use crate::language_platform::{LanguageType, PlatformType};
2use crate::project::*;
3use crate::shapes::Input;
4use crate::{config_enum, config_struct, config_unit_enum};
5use moon_common::Id;
6use rustc_hash::FxHashMap;
7use schematic::{Config, ConfigEnum, ValidateError, validate};
8use std::collections::BTreeMap;
9
10fn validate_channel<D, C>(
11    value: &str,
12    _data: &D,
13    _ctx: &C,
14    _finalize: bool,
15) -> Result<(), ValidateError> {
16    if !value.is_empty() && !value.starts_with('#') {
17        return Err(ValidateError::new("must start with a `#`"));
18    }
19
20    Ok(())
21}
22
23config_unit_enum!(
24    /// The technology stack of the project, for categorizing.
25    #[derive(ConfigEnum)]
26    pub enum StackType {
27        Backend,
28        Frontend,
29        Infrastructure,
30        Systems,
31        #[default]
32        Unknown,
33    }
34);
35
36config_unit_enum!(
37    /// The layer within the project stack, for categorizing.
38    #[derive(ConfigEnum)]
39    pub enum LayerType {
40        Application,
41        Automation,
42        Configuration,
43        Library,
44        Scaffolding,
45        Tool,
46        #[default]
47        Unknown,
48    }
49);
50
51config_struct!(
52    /// Expanded information about the project.
53    #[derive(Config)]
54    pub struct ProjectMetadataConfig {
55        /// A human-readable name of the project.
56        pub name: Option<String>,
57
58        /// A description on what the project does, and why it exists.
59        #[setting(validate = validate::not_empty)]
60        pub description: String,
61
62        /// The owner of the project. Can be an individual, team, or
63        /// organization. The format is unspecified.
64        pub owner: Option<String>,
65
66        /// The individual maintainers of the project. The format is unspecified.
67        pub maintainers: Vec<String>,
68
69        /// The Slack, Discord, etc, channel to discuss the project.
70        /// Must start with a `#`.
71        #[setting(validate = validate_channel)]
72        pub channel: Option<String>,
73
74        /// Custom metadata fields.
75        pub metadata: FxHashMap<String, serde_json::Value>,
76    }
77);
78
79config_enum!(
80    /// Expanded information about a project dependency.
81    #[derive(Config)]
82    #[serde(
83        untagged,
84        expecting = "expected a project name or dependency config object"
85    )]
86    pub enum ProjectDependsOn {
87        /// A project referenced by ID.
88        String(Id),
89
90        /// A project referenced by ID, with additional parameters to pass through.
91        #[setting(nested)]
92        Object(ProjectDependencyConfig),
93    }
94);
95
96config_struct!(
97    /// Configures information and tasks for a project.
98    /// Docs: https://moonrepo.dev/docs/config/project
99    #[derive(Config)]
100    pub struct ProjectConfig {
101        #[setting(
102            default = "https://moonrepo.dev/schemas/project.json",
103            rename = "$schema"
104        )]
105        pub schema: String,
106
107        /// Other projects that this project depends on.
108        #[setting(nested)]
109        pub depends_on: Vec<ProjectDependsOn>,
110
111        /// Configures Docker integration for this project.
112        #[setting(nested)]
113        pub docker: ProjectDockerConfig,
114
115        /// A mapping of environment variables that will be set for
116        /// all tasks within the project.
117        pub env: FxHashMap<String, String>,
118
119        /// A mapping of group IDs to a list of file paths, globs, and
120        /// environment variables, that can be referenced from tasks.
121        pub file_groups: FxHashMap<Id, Vec<Input>>,
122
123        /// Overrides the ID within the project graph, as defined in
124        /// the workspace `projects` setting.
125        pub id: Option<Id>,
126
127        /// The primary programming language of the project.
128        pub language: LanguageType,
129
130        /// The layer within the project stack, for categorizing.
131        #[serde(alias = "type")]
132        pub layer: LayerType,
133
134        /// Defines ownership of source code within the current project, by mapping
135        /// file paths and globs to owners. An owner is either a user, team, or group.
136        #[setting(nested)]
137        pub owners: OwnersConfig,
138
139        /// The default platform for all tasks within the project,
140        /// if their platform is unknown.
141        #[deprecated]
142        pub platform: Option<PlatformType>,
143
144        /// Expanded information about the project.
145        #[setting(nested)]
146        pub project: Option<ProjectMetadataConfig>,
147
148        /// The technology stack of the project, for categorizing.
149        pub stack: StackType,
150
151        /// A list of tags that this project belongs to, for categorizing,
152        /// boundary enforcement, and task inheritance.
153        pub tags: Vec<Id>,
154
155        /// A mapping of tasks by ID to parameters required for running the task.
156        #[setting(nested)]
157        pub tasks: BTreeMap<Id, TaskConfig>,
158
159        /// Overrides top-level toolchain settings, scoped to this project.
160        #[setting(nested)]
161        pub toolchain: ProjectToolchainConfig,
162
163        /// Overrides top-level workspace settings, scoped to this project.
164        #[setting(nested)]
165        pub workspace: ProjectWorkspaceConfig,
166    }
167);