moon_pdk_api/toolchain/tier2.rs
1use crate::context::*;
2use crate::host::*;
3use crate::is_false;
4use moon_config::{UnresolvedVersionSpec, Version, VersionSpec};
5use moon_project::ProjectFragment;
6use moon_task::TaskFragment;
7use std::collections::BTreeMap;
8use std::path::PathBuf;
9use warpgate_api::{VirtualPath, api_enum, api_struct};
10
11api_struct!(
12 /// Input passed to the `define_requirements` function.
13 pub struct DefineRequirementsInput {
14 /// Current moon context.
15 pub context: MoonContext,
16
17 /// Workspace toolchain configuration.
18 pub toolchain_config: serde_json::Value,
19 }
20);
21
22api_struct!(
23 /// Output returned from the `define_requirements` function.
24 #[serde(default)]
25 pub struct DefineRequirementsOutput {
26 /// Other toolchains that this toolchain requires and must be setup before hand.
27 /// If targeting an unstable toolchain, the identifier must be prefixed with "unstable_".
28 /// When the toolchain is stable, both identifiers will continue to work.
29 #[serde(skip_serializing_if = "Vec::is_empty")]
30 pub requires: Vec<String>,
31 }
32);
33
34api_struct!(
35 /// Input passed to the `setup_environment` function.
36 pub struct SetupEnvironmentInput {
37 /// Current moon context.
38 pub context: MoonContext,
39
40 /// Virtual path to a global executables directory
41 /// for the current toolchain.
42 pub globals_dir: Option<VirtualPath>,
43
44 /// The project if the dependencies and environment root
45 /// are the project root (non-workspace).
46 pub project: Option<ProjectFragment>,
47
48 /// Virtual path to the dependencies root. This is where
49 /// the lockfile and root manifest should exist.
50 pub root: VirtualPath,
51
52 /// Workspace and project merged toolchain configuration,
53 /// with the latter taking precedence.
54 pub toolchain_config: serde_json::Value,
55 }
56);
57
58api_struct!(
59 /// Output returned from the `setup_environment` function.
60 #[serde(default)]
61 pub struct SetupEnvironmentOutput {
62 /// List of files that have been changed because of this action.
63 #[serde(skip_serializing_if = "Vec::is_empty")]
64 pub changed_files: Vec<PathBuf>,
65
66 /// List of commands to execute during setup.
67 #[serde(skip_serializing_if = "Vec::is_empty")]
68 pub commands: Vec<ExecCommand>,
69
70 /// Operations that were performed. This can be used to track
71 /// metadata like time taken, result status, and more.
72 #[serde(skip_serializing_if = "Vec::is_empty")]
73 pub operations: Vec<Operation>,
74 }
75);
76
77api_struct!(
78 /// Input passed to the `locate_dependencies_root` function.
79 pub struct LocateDependenciesRootInput {
80 /// Current moon context.
81 pub context: MoonContext,
82
83 /// The starting directory in which to locate the root.
84 /// This is typically a project root.
85 pub starting_dir: VirtualPath,
86
87 /// Workspace and project merged toolchain configuration,
88 /// with the latter taking precedence.
89 pub toolchain_config: serde_json::Value,
90 }
91);
92
93api_struct!(
94 /// Output returned from the `locate_dependencies_root` function.
95 #[serde(default)]
96 pub struct LocateDependenciesRootOutput {
97 /// A list of relative globs for all members (packages, libs, etc)
98 /// within the current dependencies workspace. If not defined,
99 /// the current project is the root, or there is no workspace.
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub members: Option<Vec<String>>,
102
103 /// Virtual path to the located root. If no root was found,
104 /// return `None` to abort any relevant operations.
105 #[serde(skip_serializing_if = "Option::is_none")]
106 pub root: Option<PathBuf>,
107 }
108);
109
110api_struct!(
111 /// Input passed to the `install_dependencies` function.
112 /// Requires `locate_dependencies_root`.
113 pub struct InstallDependenciesInput {
114 /// Current moon context.
115 pub context: MoonContext,
116
117 /// List of packages to only install dependencies for.
118 pub packages: Vec<String>,
119
120 /// Only install production dependencies.
121 pub production: bool,
122
123 /// The project if the dependencies and environment root
124 /// are the project root (non-workspace).
125 pub project: Option<ProjectFragment>,
126
127 /// Virtual path to the dependencies root. This is where
128 /// the lockfile and root manifest should exist.
129 pub root: VirtualPath,
130
131 /// Workspace and project merged toolchain configuration,
132 /// with the latter taking precedence.
133 pub toolchain_config: serde_json::Value,
134 }
135);
136
137api_struct!(
138 /// Output returned from the `install_dependencies` function.
139 #[serde(default)]
140 pub struct InstallDependenciesOutput {
141 /// The command to run in the dependencies root to dedupe
142 /// dependencies. If not defined, will not dedupe.
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub dedupe_command: Option<ExecCommand>,
145
146 /// The command to run in the dependencies root to install
147 /// dependencies. If not defined, will not install.
148 #[serde(skip_serializing_if = "Option::is_none")]
149 pub install_command: Option<ExecCommand>,
150
151 /// Operations that were performed. This can be used to track
152 /// metadata like time taken, result status, and more.
153 #[serde(skip_serializing_if = "Vec::is_empty")]
154 pub operations: Vec<Operation>,
155 }
156);
157
158api_struct!(
159 /// Input passed to the `parse_manifest` function.
160 pub struct ParseManifestInput {
161 /// Current moon context.
162 pub context: MoonContext,
163
164 /// Virtual path to the manifest file.
165 pub path: VirtualPath,
166
167 /// Virtual path to the dependencies root. This is where
168 /// the lockfile and root manifest should exist.
169 pub root: VirtualPath,
170 }
171);
172
173api_struct!(
174 /// Output returned from the `parse_manifest` function.
175 #[serde(default)]
176 pub struct ParseManifestOutput {
177 /// Build dependencies.
178 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
179 pub build_dependencies: BTreeMap<String, ManifestDependency>,
180
181 /// Development dependencies.
182 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
183 pub dev_dependencies: BTreeMap<String, ManifestDependency>,
184
185 /// Production dependencies.
186 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
187 pub dependencies: BTreeMap<String, ManifestDependency>,
188
189 /// Peer dependencies.
190 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
191 pub peer_dependencies: BTreeMap<String, ManifestDependency>,
192
193 /// Can the package be published or not.
194 #[serde(skip_serializing_if = "is_false")]
195 pub publishable: bool,
196
197 /// Current version of the package.
198 #[serde(skip_serializing_if = "Option::is_none")]
199 pub version: Option<Version>,
200 }
201);
202
203api_struct!(
204 /// Represents a dependency in a manifest file.
205 #[serde(default)]
206 pub struct ManifestDependencyConfig {
207 /// The version is inherited from the workspace.
208 #[serde(skip_serializing_if = "is_false")]
209 pub inherited: bool,
210
211 /// List of features enabled for this dependency.
212 #[serde(skip_serializing_if = "Vec::is_empty")]
213 pub features: Vec<String>,
214
215 /// Relative path to the dependency on the local file system.
216 #[serde(skip_serializing_if = "Option::is_none")]
217 pub path: Option<PathBuf>,
218
219 /// Unique reference, identifier, or specifier.
220 #[serde(skip_serializing_if = "Option::is_none")]
221 pub reference: Option<String>,
222
223 /// URL of the remote dependency.
224 #[serde(skip_serializing_if = "Option::is_none")]
225 pub url: Option<String>,
226
227 /// The defined version or requirement.
228 #[serde(skip_serializing_if = "Option::is_none")]
229 pub version: Option<UnresolvedVersionSpec>,
230 }
231);
232
233api_enum!(
234 /// Represents a dependency definition in a manifest file.
235 #[serde(untagged)]
236 pub enum ManifestDependency {
237 /// Inherited from workspace.
238 Inherited(bool),
239
240 /// Only a version.
241 Version(UnresolvedVersionSpec),
242
243 /// Full configuration.
244 Config(ManifestDependencyConfig),
245 }
246);
247
248impl ManifestDependency {
249 /// Defines an explicit version or requirement.
250 pub fn new(version: UnresolvedVersionSpec) -> Self {
251 Self::Version(version)
252 }
253
254 /// Inherits a version from the workspace.
255 pub fn inherited() -> Self {
256 Self::Inherited(true)
257 }
258
259 /// Defines an explicit local path.
260 pub fn path(path: PathBuf) -> Self {
261 Self::Config(ManifestDependencyConfig {
262 path: Some(path),
263 ..Default::default()
264 })
265 }
266
267 /// Defines an explicit remote URL.
268 pub fn url(url: String) -> Self {
269 Self::Config(ManifestDependencyConfig {
270 url: Some(url),
271 ..Default::default()
272 })
273 }
274
275 /// Return an applicable version.
276 pub fn get_version(&self) -> Option<&UnresolvedVersionSpec> {
277 match self {
278 ManifestDependency::Version(version) => Some(version),
279 ManifestDependency::Config(cfg) => cfg.version.as_ref(),
280 _ => None,
281 }
282 }
283
284 /// Is the dependency version inherited.
285 pub fn is_inherited(&self) -> bool {
286 match self {
287 ManifestDependency::Inherited(state) => *state,
288 ManifestDependency::Config(cfg) => cfg.inherited,
289 _ => false,
290 }
291 }
292}
293
294api_struct!(
295 /// Input passed to the `parse_lock` function.
296 pub struct ParseLockInput {
297 /// Current moon context.
298 pub context: MoonContext,
299
300 /// Virtual path to the lockfile.
301 pub path: VirtualPath,
302
303 /// Virtual path to the dependencies root. This is where
304 /// the lockfile and root manifest should exist.
305 pub root: VirtualPath,
306 }
307);
308
309api_struct!(
310 /// Output returned from the `parse_lock` function.
311 #[serde(default)]
312 pub struct ParseLockOutput {
313 /// Map of all dependencies and their locked versions.
314 #[serde(skip_serializing_if = "BTreeMap::is_empty")]
315 pub dependencies: BTreeMap<String, Vec<LockDependency>>,
316 }
317);
318
319api_struct!(
320 /// Represents a dependency definition in a lockfile.
321 #[serde(default)]
322 pub struct LockDependency {
323 /// A unique hash: checksum, integrity, etc.
324 #[serde(skip_serializing_if = "Option::is_none")]
325 pub hash: Option<String>,
326
327 /// General metadata.
328 #[serde(skip_serializing_if = "Option::is_none")]
329 pub meta: Option<String>,
330
331 /// The version requirement.
332 #[serde(skip_serializing_if = "Option::is_none")]
333 pub req: Option<UnresolvedVersionSpec>,
334
335 /// The resolved version.
336 #[serde(skip_serializing_if = "Option::is_none")]
337 pub version: Option<VersionSpec>,
338 }
339);
340
341api_struct!(
342 /// Input passed to the `hash_task_contents` function.
343 pub struct HashTaskContentsInput {
344 /// Current moon context.
345 pub context: MoonContext,
346
347 /// Fragment of the project that the task belongs to.
348 pub project: ProjectFragment,
349
350 /// Fragment of the task being hashed.
351 pub task: TaskFragment,
352
353 /// Workspace and project merged toolchain configuration,
354 /// with the latter taking precedence.
355 pub toolchain_config: serde_json::Value,
356 }
357);
358
359api_struct!(
360 /// Output returned from the `hash_task_contents` function.
361 pub struct HashTaskContentsOutput {
362 /// Contents that should be included during hash generation.
363 pub contents: Vec<serde_json::Value>,
364 }
365);