Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change manifest locations, repos and branches based on major version #6012

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,11 @@
# v123.0 (In progress)

## Nimbus CLI [⛅️🔬🔭👾](./components/support/nimbus-cli)

### 🦊 What's Changed 🦊

- Changed the locations of firefox-ios and focus-ios feature manifest files ([#6012](https://github.com/mozilla/application-services/pull/6012)) and added version sensitivity.

[Full Changelog](In progress)

# v122.0 (_2023-12-18_)
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion components/support/nimbus-cli/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "nimbus-cli"
version = "0.4.0"
version = "0.5.0"
edition = "2021"
authors = ["Nimbus SDK Engineering"]
license = "MPL-2.0"
Expand Down
113 changes: 99 additions & 14 deletions components/support/nimbus-cli/src/config.rs
Expand Up @@ -4,7 +4,11 @@

use std::path::PathBuf;

use crate::{cli::Cli, LaunchableApp, NimbusApp};
use crate::{
cli::Cli,
version_utils::{is_before, pad_major, pad_major_minor, pad_major_minor_patch},
LaunchableApp, NimbusApp,
};
use anyhow::{bail, Result};

impl TryFrom<&Cli> for LaunchableApp {
Expand Down Expand Up @@ -144,43 +148,124 @@ impl NimbusApp {
if version.is_none() {
return Ok(ref_.to_string());
}
let version = version.as_ref().unwrap();
let app_name = self
.app_name()
.ok_or_else(|| anyhow::anyhow!("Either an --app or a --manifest must be specified"))?;

let v = version.as_ref().unwrap();
let v = match app_name.as_str() {
"fenix" => {
if is_before(version, 110) {
pad_major_minor_patch(v)
} else {
pad_major(v)
}
}
"focus_android" => {
if is_before(version, 110) {
pad_major_minor(v)
} else {
pad_major(v)
}
}
"firefox_ios" => {
if is_before(version, 112) {
pad_major_minor(v)
} else {
pad_major(v)
}
}
"focus_ios" => pad_major(v),
_ => v.to_string(),
};

Ok(match app_name.as_str() {
// Fenix and Focus are both in the same repo, so should have the
// same branching structure.
"fenix" | "focus_android" => format!("releases_v{version}"),
"firefox_ios" => format!("release/v{version}"),
"focus_ios" => format!("releases_v{version}"),
"fenix" => format!("releases_v{v}"),
"focus_android" => format!("releases_v{v}"),
"firefox_ios" => {
if is_before(version, 106) {
format!("v{v}")
} else {
format!("release/v{v}")
}
}
"focus_ios" => format!("releases_v{v}"),

_ => anyhow::bail!("{} is not defined", app_name),
})
}

pub(crate) fn github_repo<'a>(&self) -> Result<&'a str> {
pub(crate) fn github_repo<'a>(&self, version: &Option<String>) -> Result<&'a str> {
let app_name = self
.app_name()
.ok_or_else(|| anyhow::anyhow!("Either an --app or a --manifest must be specified"))?;
Ok(match app_name.as_str() {
// Fenix and Focus are both in the same repo
"fenix" | "focus_android" => "mozilla-mobile/firefox-android",
"fenix" => {
if is_before(version, 110) {
"mozilla-mobile/fenix"
} else {
"mozilla-mobile/firefox-android"
}
}
"focus_android" => {
if is_before(version, 110) {
"mozilla-mobile/focus-android"
} else {
"mozilla-mobile/firefox-android"
}
}
"firefox_ios" => "mozilla-mobile/firefox-ios",
"focus_ios" => "mozilla-mobile/focus-ios",
_ => unreachable!("{} is not defined", app_name),
})
}

pub(crate) fn manifest_location<'a>(&self) -> Result<&'a str> {
pub(crate) fn manifest_location<'a>(&self, version: &Option<String>) -> Result<&'a str> {
let app_name = self
.app_name()
.ok_or_else(|| anyhow::anyhow!("Either an --app or a --manifest must be specified"))?;
Ok(match app_name.as_str() {
"fenix" => "fenix/app/nimbus.fml.yaml",
"focus_android" => "focus-android/app/nimbus.fml.yaml",
"firefox_ios" => "nimbus.fml.yaml",
"focus_ios" => "nimbus.fml.yaml",
"fenix" => {
if is_before(version, 98) {
bail!("Fenix wasn't Nimbus enabled before v98")
} else if is_before(version, 110) {
"nimbus.fml.yaml"
} else if is_before(version, 112) {
"fenix/nimbus.fml.yaml"
} else {
"fenix/app/nimbus.fml.yaml"
}
}
"focus_android" => {
if is_before(version, 102) {
bail!("Focus for Android wasn't Nimbus enabled before v102")
} else if is_before(version, 110) {
"nimbus.fml.yaml"
} else if is_before(version, 112) {
"focus-android/nimbus.fml.yaml"
} else {
"focus-android/app/nimbus.fml.yaml"
}
}
"firefox_ios" => {
if is_before(version, 98) {
bail!("Firefox for iOS wasn't Nimbus enabled before v98")
} else if is_before(version, 122) {
"nimbus.fml.yaml"
} else {
"firefox-ios/nimbus.fml.yaml"
}
}
"focus_ios" => {
if is_before(version, 108) {
bail!("Focus wasn't Nimbus enabled before v108")
} else if is_before(version, 122) {
"nimbus.fml.yaml"
} else {
"focus-ios/nimbus.fml.yaml"
}
}
_ => anyhow::bail!("{} is not defined", app_name),
})
}
Expand Down
1 change: 1 addition & 0 deletions components/support/nimbus-cli/src/main.rs
Expand Up @@ -11,6 +11,7 @@ mod protocol;
mod sources;
mod updater;
mod value_utils;
mod version_utils;

use anyhow::{bail, Result};
use clap::Parser;
Expand Down
9 changes: 6 additions & 3 deletions components/support/nimbus-cli/src/sources/manifest.rs
Expand Up @@ -58,10 +58,13 @@ impl ManifestSource {
manifest_file,
},
(_, Some(channel), Some(_)) => {
let github_repo = params.github_repo()?.to_string();
let github_repo = params.github_repo(&value.version)?.to_string();
let ref_ = params.ref_from_version(&value.version, &value.ref_)?;
let manifest_file =
format!("@{}/{}", github_repo, params.manifest_location()?,);
let manifest_file = format!(
"@{}/{}",
github_repo,
params.manifest_location(&value.version)?,
);
Self::FromGithub {
channel,
manifest_file,
Expand Down
67 changes: 67 additions & 0 deletions components/support/nimbus-cli/src/version_utils.rs
@@ -0,0 +1,67 @@
// This Source Code Form is subject to the terms of the Mozilla Public
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should consider using a crate like semver long term.

// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use anyhow::Result;

pub(crate) fn is_before(current_version: &Option<String>, upto_version: usize) -> bool {
if current_version.is_none() {
false
} else {
let current_version = current_version.as_deref().unwrap();
is_between(0, current_version, upto_version).unwrap_or(false)
}
}

fn is_between(min_version: usize, current_version: &str, max_version: usize) -> Result<bool> {
let (major, _) = current_version
.split_once('.')
.unwrap_or((current_version, ""));
let v = major.parse::<usize>()?;
Ok(min_version <= v && v < max_version)
}

/// The following are dumb string manipulations to pad out a version number.
/// We might use a version library if we need much more functionality, but right now
/// it's isolated in a single file where it can be replaced as/when necessary.

/// pad_major_minor_patch will zero pad the minor and patch versions if they are not present.
/// 112.1.3 --> 112.1.3
/// 112.1 --> 112.1.0
/// 112 --> 112.0.0
pub(crate) fn pad_major_minor_patch(version: &str) -> String {
match version_split(version) {
(Some(_), Some(_), Some(_)) => version.to_owned(),
(Some(major), Some(minor), None) => format!("{major}.{minor}.0"),
(Some(major), None, None) => format!("{major}.0.0"),
_ => format!("{version}.0.0"),
}
}

/// pad_major_minor will zero pad the minor version if it is not present.
/// If the patch version is present, then it is left intact.
/// 112.1.3 --> 112.1.3
/// 112.1 --> 112.1
/// 112 --> 112.0
pub(crate) fn pad_major_minor(version: &str) -> String {
match version_split(version) {
(Some(_), Some(_), Some(_)) => version.to_owned(),
(Some(major), Some(minor), None) => format!("{major}.{minor}"),
(Some(major), None, None) => format!("{major}.0"),
_ => format!("{version}.0"),
}
}

/// pad_major will keep the string as it is.
/// If the minor and/or patch versions are present, then they are left intact.
/// 112.1.3 --> 112.1.3
/// 112.1 --> 112.1
/// 112 --> 112
pub(crate) fn pad_major(version: &str) -> String {
version.to_owned()
}

fn version_split(version: &str) -> (Option<&str>, Option<&str>, Option<&str>) {
let mut split = version.splitn(3, '.');
(split.next(), split.next(), split.next())
}