feat(updater): include version_code as part of release_version (#9)

This commit is contained in:
Felix Angelov
2023-04-19 16:07:09 -05:00
committed by GitHub
parent 1281624ccf
commit 182ce073e2
6 changed files with 35 additions and 95 deletions
+1 -2
View File
@@ -21,8 +21,7 @@ fn main() {
let config = updater::AppConfig {
cache_dir: "updater_cache".to_owned(),
version_name: "0.1.0".to_owned(),
version_code: 1,
release_version: "0.1.0+1".to_owned(),
original_libapp_paths: vec!["libapp.so".to_owned()],
};
let yaml_str = "
+5 -2
View File
@@ -51,8 +51,11 @@ fn app_config_from_c(c_params: *const AppParameters) -> updater::AppConfig {
updater::AppConfig {
cache_dir: to_rust(c_params_ref.cache_dir),
version_name: to_rust(c_params_ref.version_name),
version_code: c_params_ref.version_code,
release_version: format!(
"{}+{}",
to_rust(c_params_ref.version_name),
c_params_ref.version_code
),
original_libapp_paths: to_rust_vector(
c_params_ref.original_libapp_paths,
c_params_ref.original_libapp_paths_size,
+12 -45
View File
@@ -41,11 +41,7 @@ pub struct UpdaterState {
/// The release version this cache corresponds to.
/// If this does not match the release version we're booting from we will
/// clear the cache.
version_name: String,
/// The version code this cache corresponds to.
/// If this does not match the version code we're booting from we will
/// clear the cache.
version_code: i64,
release_version: String,
/// The patch number of the patch that was last downloaded.
latest_downloaded_patch: Option<usize>,
/// List of patches that failed to boot. We will never attempt these again.
@@ -61,11 +57,10 @@ pub struct UpdaterState {
}
impl UpdaterState {
fn new(cache_dir: String, version_name: String, version_code: i64) -> Self {
fn new(cache_dir: String, release_version: String) -> Self {
Self {
cache_dir,
version_name,
version_code,
release_version,
current_slot_index: None,
latest_downloaded_patch: None,
failed_patches: Vec::new(),
@@ -120,25 +115,19 @@ impl UpdaterState {
Ok(state)
}
pub fn load_or_new_on_error(cache_dir: &str, version_name: &str, version_code: i64) -> Self {
pub fn load_or_new_on_error(cache_dir: &str, release_version: &str) -> Self {
let loaded = Self::load(cache_dir).unwrap_or_else(|e| {
// FIXME: Should match on errorKind and display a warning if it's
// not a file not found error.
info!("No cached state, making empty: {}", e);
Self::new(cache_dir.to_owned(), version_name.to_owned(), version_code)
Self::new(cache_dir.to_owned(), release_version.to_owned())
});
if loaded.version_name != version_name {
if loaded.release_version != release_version {
info!(
"version_name changed {} -> {}, clearing updater state",
loaded.version_name, version_name
"release_version changed {} -> {}, clearing updater state",
loaded.release_version, release_version
);
Self::new(cache_dir.to_owned(), version_name.to_owned(), version_code)
} else if loaded.version_code != version_code {
info!(
"version_code changed {} -> {}, clearing updater state",
loaded.version_code, version_code
);
Self::new(cache_dir.to_owned(), version_name.to_owned(), version_code)
Self::new(cache_dir.to_owned(), release_version.to_owned())
} else {
loaded
}
@@ -316,7 +305,7 @@ mod tests {
fn test_state(tmp_dir: &TempDir) -> UpdaterState {
let cache_dir = tmp_dir.path().to_str().unwrap().to_string();
UpdaterState::new(cache_dir, "1.0.0".to_string(), 1)
UpdaterState::new(cache_dir, "1.0.0+1".to_string())
}
fn fake_patch(tmp_dir: &TempDir, number: usize) -> super::PatchInfo {
@@ -346,33 +335,11 @@ mod tests {
let mut state = test_state(&tmp_dir);
state.latest_downloaded_patch = Some(1);
state.save().unwrap();
let loaded = UpdaterState::load_or_new_on_error(
&state.cache_dir,
&state.version_name,
state.version_code,
);
let loaded = UpdaterState::load_or_new_on_error(&state.cache_dir, &state.release_version);
assert_eq!(loaded.latest_downloaded_patch, Some(1));
let loaded_after_version_change =
UpdaterState::load_or_new_on_error(&state.cache_dir, "1.0.1", state.version_code);
assert_eq!(loaded_after_version_change.latest_downloaded_patch, None);
}
#[test]
fn version_code_changed() {
let tmp_dir = TempDir::new("example").unwrap();
let mut state = test_state(&tmp_dir);
state.latest_downloaded_patch = Some(1);
state.save().unwrap();
let loaded = UpdaterState::load_or_new_on_error(
&state.cache_dir,
&state.version_name,
state.version_code,
);
assert_eq!(loaded.latest_downloaded_patch, Some(1));
let loaded_after_version_change =
UpdaterState::load_or_new_on_error(&state.cache_dir, &state.version_name, 2);
UpdaterState::load_or_new_on_error(&state.cache_dir, "1.0.0+2");
assert_eq!(loaded_after_version_change.latest_downloaded_patch, None);
}
+3 -6
View File
@@ -39,8 +39,7 @@ pub struct ResolvedConfig {
pub download_dir: String,
pub channel: String,
pub app_id: String,
pub version_name: String,
pub version_code: i64,
pub release_version: String,
pub original_libapp_paths: Vec<String>,
pub vm_path: String,
pub base_url: String,
@@ -54,8 +53,7 @@ impl ResolvedConfig {
download_dir: String::new(),
channel: String::new(),
app_id: String::new(),
version_name: String::new(),
version_code: 0,
release_version: String::new(),
original_libapp_paths: Vec::new(),
vm_path: String::new(),
base_url: String::new(),
@@ -84,8 +82,7 @@ pub fn set_config(config: AppConfig, yaml: YamlConfig) {
cache_path.push("downloads");
lock.download_dir = cache_path.to_str().unwrap().to_string();
lock.app_id = yaml.app_id.to_string();
lock.version_name = config.version_name.to_string();
lock.version_code = config.version_code;
lock.release_version = config.release_version.to_string();
lock.original_libapp_paths = config.original_libapp_paths;
lock.is_initialized = true;
info!("Updater configured with: {:?}", lock);
+2 -4
View File
@@ -36,8 +36,7 @@ pub struct PatchCheckRequest {
pub release_version: String,
/// The latest patch number that the client has downloaded.
/// Not necessarily the one it's running (if some have been marked bad).
/// We could rename this to be more clear.
pub version_code: i64,
/// We could rename this to be more clear.
#[serde(skip_serializing_if = "Option::is_none")]
pub patch_number: Option<usize>,
/// Platform (e.g. "android", "ios", "windows", "macos", "linux").
@@ -64,8 +63,7 @@ pub fn send_patch_check_request(
let req = PatchCheckRequest {
app_id: config.app_id.clone(),
channel: config.channel.clone(),
release_version: config.version_name.clone(),
version_code: config.version_code,
release_version: config.release_version.clone(),
patch_number: latest_patch_number,
platform: current_platform().to_string(),
arch: current_arch().to_string(),
+12 -36
View File
@@ -61,8 +61,7 @@ impl Display for UpdateError {
// but making &str from CStr* is a bit of a pain.
pub struct AppConfig {
pub cache_dir: String,
pub version_name: String,
pub version_code: i64,
pub release_version: String,
pub original_libapp_paths: Vec<String>,
}
@@ -82,11 +81,7 @@ pub fn init(app_config: AppConfig, yaml: &str) -> Result<(), UpdateError> {
fn check_for_update_internal(config: &ResolvedConfig) -> bool {
// Load UpdaterState from disk
// If there is no state, make an empty state.
let state = UpdaterState::load_or_new_on_error(
&config.cache_dir,
&config.version_name,
config.version_code,
);
let state = UpdaterState::load_or_new_on_error(&config.cache_dir, &config.release_version);
// Send info from app + current slot to server.
let response_result = send_patch_check_request(&config, &state);
match response_result {
@@ -278,11 +273,7 @@ fn open_base_lib(apks_dir: &Path, lib_name: &str) -> anyhow::Result<Cursor<Vec<u
// Run the update logic with the resolved config.
fn update_internal(config: &ResolvedConfig) -> anyhow::Result<UpdateStatus> {
// Load the state from disk.
let mut state = UpdaterState::load_or_new_on_error(
&config.cache_dir,
&config.version_name,
config.version_code,
);
let mut state = UpdaterState::load_or_new_on_error(&config.cache_dir, &config.release_version);
// Check for update.
let response = send_patch_check_request(&config, &state)?;
if !response.patch_available {
@@ -393,11 +384,7 @@ where
/// Reads the current patch from the cache and returns it.
pub fn active_patch() -> Option<PatchInfo> {
return with_config(|config| {
let state = UpdaterState::load_or_new_on_error(
&config.cache_dir,
&config.version_name,
config.version_code,
);
let state = UpdaterState::load_or_new_on_error(&config.cache_dir, &config.release_version);
return state.current_patch();
});
}
@@ -407,11 +394,8 @@ pub fn active_patch() -> Option<PatchInfo> {
pub fn report_failed_launch() -> Result<(), UpdateError> {
info!("Reporting failed launch.");
with_config(|config| {
let mut state = UpdaterState::load_or_new_on_error(
&config.cache_dir,
&config.version_name,
config.version_code,
);
let mut state =
UpdaterState::load_or_new_on_error(&config.cache_dir, &config.release_version);
// FIXME: We need to separate out the concept of "running patch" and
// "next patch to activate". Currently these are smooshed which will
@@ -426,11 +410,8 @@ pub fn report_failed_launch() -> Result<(), UpdateError> {
pub fn report_successful_launch() -> Result<(), UpdateError> {
with_config(|config| {
let mut state = UpdaterState::load_or_new_on_error(
&config.cache_dir,
&config.version_name,
config.version_code,
);
let mut state =
UpdaterState::load_or_new_on_error(&config.cache_dir, &config.release_version);
let patch = state
.current_patch()
@@ -465,8 +446,7 @@ mod tests {
crate::init(
crate::AppConfig {
cache_dir: cache_dir.clone(),
version_name: "1.0.0".to_string(),
version_code: 1,
release_version: "1.0.0+1".to_string(),
original_libapp_paths: vec!["original_libapp_path".to_string()],
},
"app_id: 1234",
@@ -482,8 +462,7 @@ mod tests {
crate::init(
crate::AppConfig {
cache_dir: cache_dir.clone(),
version_name: "1.0.0".to_string(),
version_code: 1,
release_version: "1.0.0+1".to_string(),
original_libapp_paths: vec!["original_libapp_path".to_string()],
},
"",
@@ -529,11 +508,8 @@ mod tests {
fs::create_dir_all(&download_dir).unwrap();
fs::write(&artifact_path, "hello").unwrap();
let mut state = UpdaterState::load_or_new_on_error(
&config.cache_dir,
&config.version_name,
config.version_code,
);
let mut state =
UpdaterState::load_or_new_on_error(&config.cache_dir, &config.release_version);
state
.install_patch(PatchInfo {
path: artifact_path.to_str().unwrap().to_string(),