forked from JuliaLang/juliaup
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand_selfupdate.rs
More file actions
144 lines (114 loc) · 4.92 KB
/
command_selfupdate.rs
File metadata and controls
144 lines (114 loc) · 4.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
use crate::global_paths::GlobalPaths;
use crate::operations::update_version_db;
use anyhow::{Context, Result};
#[cfg(feature = "selfupdate")]
pub fn run_command_selfupdate(paths: &GlobalPaths) -> Result<()> {
use crate::config_file::{load_mut_config_db, save_config_db};
use crate::operations::{download_extract_sans_parent, download_juliaup_version};
use crate::utils::get_juliaserver_base_url;
use crate::{get_juliaup_target, get_own_version};
use anyhow::bail;
update_version_db(paths).with_context(|| "Failed to update versions db.")?;
let mut config_file = load_mut_config_db(paths)
.with_context(|| "`selfupdate` command failed to load configuration db.")?;
let juliaup_channel = match &config_file.self_data.juliaup_channel {
Some(juliaup_channel) => juliaup_channel.to_string(),
None => "release".to_string(),
};
let juliaupserver_base =
get_juliaserver_base_url().with_context(|| "Failed to get Juliaup server base URL.")?;
let version_url_path = match juliaup_channel.as_str() {
"release" => "juliaup/RELEASECHANNELVERSION",
"releasepreview" => "juliaup/RELEASEPREVIEWCHANNELVERSION",
"dev" => "juliaup/DEVCHANNELVERSION",
_ => bail!(
"Juliaup is configured to a channel named '{}' that does not exist.",
&juliaup_channel
),
};
eprintln!("Checking for self-updates");
let version_url = juliaupserver_base.join(version_url_path).with_context(|| {
format!(
"Failed to construct a valid url from '{}' and '{}'.",
juliaupserver_base, version_url_path
)
})?;
let version = download_juliaup_version(&version_url.to_string())?;
config_file.self_data.last_selfupdate = Some(chrono::Utc::now());
save_config_db(&mut config_file).with_context(|| "Failed to save configuration file.")?;
if version == get_own_version().unwrap() {
eprintln!(
"Juliaup unchanged on channel '{}' - {}",
juliaup_channel, version
);
} else {
let juliaup_target = get_juliaup_target();
let juliaupserver_base =
get_juliaserver_base_url().with_context(|| "Failed to get Juliaup server base URL.")?;
let download_url_path =
format!("juliaup/bin/juliaup-{}-{}.tar.gz", version, juliaup_target);
let new_juliaup_url = juliaupserver_base
.join(&download_url_path)
.with_context(|| {
format!(
"Failed to construct a valid url from '{}' and '{}'.",
juliaupserver_base, download_url_path
)
})?;
eprintln!(
"Found new version {} on channel {}.",
version, juliaup_channel
);
download_extract_sans_parent(&new_juliaup_url.to_string(), &paths.juliaupselfbin, 0)?;
eprintln!("Updated Juliaup to version {}.", version);
}
Ok(())
}
#[cfg(feature = "windowsstore")]
pub fn run_command_selfupdate(paths: &GlobalPaths) -> Result<()> {
use windows::{
core::Interface,
Win32::{System::Console::GetConsoleWindow, UI::Shell::IInitializeWithWindow},
};
update_version_db(paths).with_context(|| "Failed to update versions db.")?;
let update_manager = windows::Services::Store::StoreContext::GetDefault()
.with_context(|| "Failed to get the store context.")?;
let interop: IInitializeWithWindow = update_manager
.cast()
.with_context(|| "Failed to cast the store context to IInitializeWithWindow.")?;
unsafe {
let x = GetConsoleWindow();
interop
.Initialize(x)
.with_context(|| "Call to IInitializeWithWindow.Initialize failed.")?;
}
let updates = update_manager
.GetAppAndOptionalStorePackageUpdatesAsync()
.with_context(|| "Call to GetAppAndOptionalStorePackageUpdatesAsync failed.")?
.get()
.with_context(|| {
"get on the return of GetAppAndOptionalStorePackageUpdatesAsync failed."
})?;
if updates
.Size()
.with_context(|| "Call to Size on update results failed.")?
> 0
{
println!("An update is available.");
let download_operation = update_manager
.RequestDownloadAndInstallStorePackageUpdatesAsync(&updates)
.with_context(|| "Call to RequestDownloadAndInstallStorePackageUpdatesAsync failed.")?;
download_operation.get().with_context(|| {
"get on result from RequestDownloadAndInstallStorePackageUpdatesAsync failed."
})?;
// This code will not be reached if the user opts to install updates
} else {
println!("No updates available.");
}
Ok(())
}
#[cfg(not(any(feature = "windowsstore", feature = "selfupdate")))]
pub fn run_command_selfupdate(paths: &GlobalPaths) -> Result<()> {
update_version_db(paths).with_context(|| "Failed to update versions db.")?;
Ok(())
}