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);