nimbus_cli/sources/
manifest.rs
1use std::fmt::Display;
6
7use anyhow::Result;
8use nimbus_fml::{
9 intermediate_representation::FeatureManifest, parser::Parser, util::loaders::FileLoader,
10};
11
12use crate::{cli::ManifestArgs, config, NimbusApp};
13
14#[derive(Debug, PartialEq)]
15pub(crate) enum ManifestSource {
16 FromGithub {
17 channel: String,
18
19 github_repo: String,
20 ref_: String,
21
22 manifest_file: String,
23 },
24 FromFile {
25 channel: String,
26 manifest_file: String,
27 },
28}
29
30impl ManifestSource {
31 fn manifest_file(&self) -> &str {
32 let (Self::FromFile { manifest_file, .. } | Self::FromGithub { manifest_file, .. }) = self;
33 manifest_file
34 }
35
36 fn channel(&self) -> &str {
37 let (Self::FromFile { channel, .. } | Self::FromGithub { channel, .. }) = self;
38 channel
39 }
40
41 fn manifest_loader(&self) -> Result<FileLoader> {
42 let cwd = std::env::current_dir().expect("Current Working Directory is not set");
43 let mut files = FileLoader::new(cwd, config::manifest_cache_dir(), Default::default())?;
44 if let Self::FromGithub {
45 ref_, github_repo, ..
46 } = self
47 {
48 files.add_repo(github_repo, ref_)?;
49 }
50 Ok(files)
51 }
52
53 pub(crate) fn try_from(params: &NimbusApp, value: &ManifestArgs) -> Result<Self> {
54 Ok(
55 match (value.manifest.clone(), params.channel(), params.app_name()) {
56 (Some(manifest_file), Some(channel), _) => Self::FromFile {
57 channel,
58 manifest_file,
59 },
60 (_, Some(channel), Some(_)) => {
61 let github_repo = params.github_repo(&value.version)?.to_string();
62 let ref_ = params.ref_from_version(&value.version, &value.ref_)?;
63 let manifest_file = format!(
64 "@{}/{}",
65 github_repo,
66 params.manifest_location(&value.version)?,
67 );
68 Self::FromGithub {
69 channel,
70 manifest_file,
71 ref_,
72 github_repo,
73 }
74 }
75 _ => anyhow::bail!("A channel and either a manifest or an app is expected"),
76 },
77 )
78 }
79}
80
81impl Display for ManifestSource {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 let files = self.manifest_loader().unwrap();
84 let path = files.file_path(self.manifest_file()).unwrap();
85 f.write_str(&path.to_string())
86 }
87}
88
89impl TryFrom<&ManifestSource> for FeatureManifest {
90 type Error = anyhow::Error;
91
92 fn try_from(value: &ManifestSource) -> Result<Self> {
93 let files = value.manifest_loader()?;
94 let path = files.file_path(value.manifest_file())?;
95 let parser: Parser = Parser::new(files, path)?;
96 let manifest = parser.get_intermediate_representation(Some(value.channel()))?;
97 manifest.validate_manifest()?;
98 Ok(manifest)
99 }
100}