/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use clap::{Args, Parser, Subcommand, ValueEnum}; use crate::intermediate_representation::TargetLanguage; #[derive(Parser)] #[command(name = "nimbus-fml")] #[command(author = "nimbus-dev@mozilla.com")] /// Tool for working with Nimbus Feature Manifests pub struct App { #[clap(subcommand)] pub subcommand: Command, } #[derive(Subcommand)] pub enum Command { /// Generate feature structs against the Feature Variables API. Generate(Generate), /// Generate a version of this manifest compatible with Experimenter's format. GenerateExperimenter(GenerateExperimenter), /// Get the input file, with the same rules that govern how FilePaths work. Fetch(Fetch), /// Create a single file out of the given manifest, suited for production environments where /// only one file is allowed, and only one channel is needed. SingleFile(SingleFile), /// Validate an FML configuration and all of its channels. Validate(Validate), /// Print out all the channels to stdout, as JSON or one-per-line Channels(Channels), /// Prints out information about the manifest Info(Info), } #[derive(Args)] pub struct Generate { /// Sets the input file to use #[arg(value_name = "INPUT")] pub input: String, /// The file or directory where generated code is created #[arg(value_name = "OUTPUT")] pub output: String, /// The language of the output file #[arg(long)] pub language: Option, /// The channel to generate the defaults for #[arg(long)] pub channel: String, #[command(flatten)] pub loader_info: LoaderInfo, } #[derive(Args)] pub struct GenerateExperimenter { /// Sets the input file to use #[arg(value_name = "INPUT")] pub input: String, /// The file or directory where generated code is created #[arg(value_name = "OUTPUT")] pub output: String, /// Deprecated: The channel to generate the defaults for. This can be omitted. #[arg(long)] // This is no longer needed, but we keep it for backward compatibility. pub channel: Option, #[command(flatten)] pub loader_info: LoaderInfo, } #[derive(Args)] pub struct Fetch { /// Sets the input file to use #[arg(value_name = "INPUT")] pub input: String, #[command(flatten)] pub loader_info: LoaderInfo, } #[derive(Args)] pub struct SingleFile { /// Sets the input file to use #[arg(value_name = "INPUT")] pub input: String, /// The file or directory where generated code is created #[arg(value_name = "OUTPUT")] pub output: String, /// The channel to generate the defaults for #[arg(long)] pub channel: Option, #[command(flatten)] pub loader_info: LoaderInfo, } #[derive(Args)] pub struct Validate { /// Sets the input file to use #[arg(value_name = "INPUT")] pub input: String, #[command(flatten)] pub loader_info: LoaderInfo, } #[derive(Args)] pub struct Channels { /// Sets the input file to use #[arg(value_name = "INPUT")] pub input: String, #[command(flatten)] pub loader_info: LoaderInfo, /// If present, then print the channels as JSON. If not, then print one per line. #[arg(long)] pub json: bool, } #[derive(Args)] pub struct Info { /// Sets the input file to use #[arg(value_name = "INPUT")] pub input: String, /// The channel to generate the defaults for #[arg(long)] pub channel: Option, /// Print the info of one feature only, if present #[arg(long)] pub feature: Option, #[command(flatten)] pub loader_info: LoaderInfo, /// If present, then print the channels as JSON. If not, then print one per line. #[arg(long)] pub json: bool, } #[derive(Clone, Copy, ValueEnum)] pub enum Language { Swift, Kotlin, } #[derive(Args)] pub struct LoaderInfo { /// The directory where downloaded files are cached #[arg(long)] pub cache_dir: Option, /// The file containing the version/refs/locations for other repos #[arg(long)] pub repo_file: Vec, /// If INPUT is a remote file, then use this as the tag or branch name. #[arg(long = "ref")] pub ref_: Option, #[arg(long)] /// Enable lax gecko-pref validation. pub lax_gecko_pref_validation: bool, } impl From for TargetLanguage { fn from(lang: Language) -> Self { match lang { Language::Swift => Self::Swift, Language::Kotlin => Self::Kotlin, } } }