mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-12 11:39:57 +01:00
wip
This commit is contained in:
@@ -8,16 +8,10 @@ parameters:
|
||||
default: {}
|
||||
|
||||
steps:
|
||||
- script: cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code-tunnel
|
||||
- script: cargo build --release --target ${{ parameters.VSCODE_CLI_TARGET }} --bin=code
|
||||
displayName: Compile ${{ parameters.VSCODE_CLI_TARGET }}
|
||||
workingDirectory: $(Build.SourcesDirectory)/cli
|
||||
env:
|
||||
VSCODE_CLI_VERSION: $(VSCODE_CLI_VERSION)
|
||||
VSCODE_CLI_REMOTE_LICENSE_TEXT: $(VSCODE_CLI_REMOTE_LICENSE_TEXT)
|
||||
VSCODE_CLI_REMOTE_LICENSE_PROMPT: $(VSCODE_CLI_REMOTE_LICENSE_PROMPT)
|
||||
VSCODE_CLI_ASSET_NAME: ${{ parameters.VSCODE_CLI_ARTIFACT }}
|
||||
VSCODE_CLI_AI_KEY: $(VSCODE_CLI_AI_KEY)
|
||||
VSCODE_CLI_AI_ENDPOINT: $(VSCODE_CLI_AI_ENDPOINT)
|
||||
${{ each pair in parameters.VSCODE_CLI_ENV }}:
|
||||
${{ pair.key }}: ${{ pair.value }}
|
||||
|
||||
@@ -25,9 +19,9 @@ steps:
|
||||
- task: ArchiveFiles@2
|
||||
inputs:
|
||||
${{ if contains(parameters.VSCODE_CLI_TARGET, '-windows-') }}:
|
||||
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code-tunnel.exe
|
||||
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code.exe
|
||||
${{ if contains(parameters.VSCODE_CLI_TARGET, '-darwin') }}:
|
||||
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code-tunnel
|
||||
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code
|
||||
includeRootFolder: false
|
||||
archiveType: zip
|
||||
archiveFile: $(Build.ArtifactStagingDirectory)/${{ parameters.VSCODE_CLI_ARTIFACT }}.zip
|
||||
@@ -39,7 +33,7 @@ steps:
|
||||
- ${{ else }}:
|
||||
- task: ArchiveFiles@2
|
||||
inputs:
|
||||
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code-tunnel
|
||||
rootFolderOrFile: $(Build.SourcesDirectory)/cli/target/${{ parameters.VSCODE_CLI_TARGET }}/release/code
|
||||
includeRootFolder: false
|
||||
archiveType: tar
|
||||
tarCompression: gz
|
||||
|
||||
@@ -56,7 +56,7 @@ steps:
|
||||
|
||||
- task: ArchiveFiles@2
|
||||
inputs:
|
||||
rootFolderOrFile: $(Build.ArtifactStagingDirectory)/sign/${{ target }}/code-tunnel.exe
|
||||
rootFolderOrFile: $(Build.ArtifactStagingDirectory)/sign/${{ target }}/code.exe
|
||||
includeRootFolder: false
|
||||
archiveType: zip
|
||||
archiveFile: $(Build.ArtifactStagingDirectory)/$(ASSET_ID).zip
|
||||
|
||||
@@ -22,6 +22,7 @@ const setLauncherEnvironmentVars = () => {
|
||||
['VSCODE_CLI_AI_KEY', product.aiConfig?.cliKey],
|
||||
['VSCODE_CLI_AI_ENDPOINT', product.aiConfig?.cliEndpoint],
|
||||
['VSCODE_CLI_VERSION', packageJson.version],
|
||||
['VSCODE_CLI_UPDATE_ENDPOINT', product.updateUrl],
|
||||
['VSCODE_CLI_QUALIY', product.quality],
|
||||
['VSCODE_CLI_COMMIT', commit],
|
||||
]);
|
||||
|
||||
@@ -202,7 +202,8 @@ steps:
|
||||
- script: |
|
||||
set -e
|
||||
ARCHIVE_NAME=$(ls "$(Build.ArtifactStagingDirectory)/cli" | head -n 1)
|
||||
unzip "$(Build.ArtifactStagingDirectory)/cli/$ARCHIVE_NAME" -d "$(APP_PATH)/Contents/Resources/app/bin"
|
||||
unzip "$(Build.ArtifactStagingDirectory)/cli/$ARCHIVE_NAME" -d "$(Build.ArtifactStagingDirectory)/cli"
|
||||
mv "$(Build.ArtifactStagingDirectory)/cli" "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel"
|
||||
chmod +x "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel"
|
||||
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
|
||||
mv "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel" "$(APP_PATH)/Contents/Resources/app/bin/code-tunnel-$(VSCODE_QUALITY)"
|
||||
|
||||
@@ -273,7 +273,8 @@ steps:
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
tar -xzvf $(Build.ArtifactStagingDirectory)/cli/*.tar.gz -C $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin
|
||||
tar -xzvf $(Build.ArtifactStagingDirectory)/cli/*.tar.gz -C $(Build.ArtifactStagingDirectory)/cli
|
||||
mv $(Build.ArtifactStagingDirectory)/cli/code $(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel
|
||||
if [ "$(VSCODE_QUALITY)" != "stable" ]; then
|
||||
mv "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel" "$(agent.builddirectory)/VSCode-linux-$(VSCODE_ARCH)/bin/code-tunnel-$(VSCODE_QUALITY)"
|
||||
fi
|
||||
|
||||
@@ -233,6 +233,7 @@ stages:
|
||||
VSCODE_QUALITY: ${{ variables.VSCODE_QUALITY }}
|
||||
VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }}
|
||||
VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }}
|
||||
VSCODE_BUILD_WIN32_32BIT: ${{ parameters.VSCODE_BUILD_WIN32_32BIT }}
|
||||
|
||||
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_WINDOWS'], true)) }}:
|
||||
- stage: Windows
|
||||
@@ -339,6 +340,7 @@ stages:
|
||||
parameters:
|
||||
VSCODE_BUILD_WIN32: ${{ parameters.VSCODE_BUILD_WIN32 }}
|
||||
VSCODE_BUILD_WIN32_ARM64: ${{ parameters.VSCODE_BUILD_WIN32_ARM64 }}
|
||||
VSCODE_BUILD_WIN32_32BIT: ${{ parameters.VSCODE_BUILD_WIN32_32BIT }}
|
||||
|
||||
- ${{ if and(eq(parameters.VSCODE_COMPILE_ONLY, false), eq(variables['VSCODE_BUILD_STAGE_LINUX'], true)) }}:
|
||||
- stage: LinuxServerDependencies
|
||||
|
||||
@@ -3,6 +3,8 @@ parameters:
|
||||
type: boolean
|
||||
- name: VSCODE_BUILD_WIN32_ARM64
|
||||
type: boolean
|
||||
- name: VSCODE_BUILD_WIN32_32BIT
|
||||
type: boolean
|
||||
- name: VSCODE_QUALITY
|
||||
type: string
|
||||
- name: channel
|
||||
@@ -33,6 +35,8 @@ steps:
|
||||
- x86_64-pc-windows-msvc
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
|
||||
- aarch64-pc-windows-msvc
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}:
|
||||
- i686-pc-windows-msvc
|
||||
|
||||
- template: ../vcpkg-install.yml
|
||||
parameters:
|
||||
@@ -41,6 +45,8 @@ steps:
|
||||
- x64-windows-static-md
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
|
||||
- arm64-windows-static-md
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}:
|
||||
- x86-windows-static-md
|
||||
vcpkgDir: $(Build.SourcesDirectory)/build/azure-pipelines/cli/vcpkg
|
||||
targetDirectory: $(Build.ArtifactStagingDirectory)/deps
|
||||
|
||||
@@ -61,3 +67,12 @@ steps:
|
||||
VSCODE_CLI_ENV:
|
||||
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/deps/arm64-windows-static-md/lib
|
||||
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/deps/arm64-windows-static-md/include
|
||||
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}:
|
||||
- template: ../cli/cli-compile-and-publish.yml
|
||||
parameters:
|
||||
VSCODE_CLI_TARGET: i686-pc-windows-msvc
|
||||
VSCODE_CLI_ARTIFACT: unsigned_vscode_cli_win32_ia32_cli
|
||||
VSCODE_CLI_ENV:
|
||||
OPENSSL_LIB_DIR: $(Build.ArtifactStagingDirectory)/deps/x86-windows-static-md/lib
|
||||
OPENSSL_INCLUDE_DIR: $(Build.ArtifactStagingDirectory)/deps/x86-windows-static-md/include
|
||||
|
||||
@@ -3,14 +3,9 @@ parameters:
|
||||
type: boolean
|
||||
- name: VSCODE_BUILD_WIN32_ARM64
|
||||
type: boolean
|
||||
- name: VSCODE_BUILD_WIN32_32BIT
|
||||
type: boolean
|
||||
|
||||
variables:
|
||||
- name: VSCODE_CLI_ARTIFACTS
|
||||
value:
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32, true) }}:
|
||||
- unsigned_vscode_cli_win32_x64_cli
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
|
||||
- unsigned_vscode_cli_win32_arm64_cli
|
||||
steps:
|
||||
- task: NodeTool@0
|
||||
displayName: "Use Node.js"
|
||||
@@ -30,3 +25,5 @@ steps:
|
||||
- unsigned_vscode_cli_win32_x64_cli
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_ARM64, true) }}:
|
||||
- unsigned_vscode_cli_win32_arm64_cli
|
||||
- ${{ if eq(parameters.VSCODE_BUILD_WIN32_32BIT, true) }}:
|
||||
- unsigned_vscode_cli_win32_ia32_cli
|
||||
|
||||
@@ -199,7 +199,8 @@ steps:
|
||||
. build/azure-pipelines/win32/exec.ps1
|
||||
$ErrorActionPreference = "Stop"
|
||||
$ArtifactName = (gci -Path "$(Build.ArtifactStagingDirectory)/cli" | Select-Object -last 1).FullName
|
||||
Expand-Archive -Path $ArtifactName -DestinationPath "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin"
|
||||
Expand-Archive -Path $ArtifactName -DestinationPath "$(Build.ArtifactStagingDirectory)/cli"
|
||||
Move-Item -Path "$(Build.ArtifactStagingDirectory)/cli/code.exe" -Destination "$(agent.builddirectory)/VSCode-win32-$(VSCODE_ARCH)/bin/code-tunnel.exe"
|
||||
|
||||
if ("$(VSCODE_QUALITY)" -ne "stable")
|
||||
{
|
||||
|
||||
@@ -8,9 +8,6 @@ default-run = "code"
|
||||
name = "cli"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "code-tunnel"
|
||||
|
||||
[[bin]]
|
||||
name = "code"
|
||||
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
use clap::Parser;
|
||||
use cli::{
|
||||
commands::{args, tunnels, CommandContext},
|
||||
constants, log as own_log,
|
||||
state::LauncherPaths,
|
||||
};
|
||||
use opentelemetry::sdk::trace::TracerProvider as SdkTracerProvider;
|
||||
use opentelemetry::trace::TracerProvider;
|
||||
|
||||
use log::{Level, Metadata, Record};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(
|
||||
long_about = None,
|
||||
name = "Visual Studio Code Tunnels CLI",
|
||||
version = match constants::VSCODE_CLI_VERSION { Some(v) => v, None => "dev" },
|
||||
)]
|
||||
pub struct TunnelCli {
|
||||
#[clap(flatten, next_help_heading = Some("GLOBAL OPTIONS"))]
|
||||
pub global_options: args::GlobalOptions,
|
||||
|
||||
#[clap(flatten, next_help_heading = Some("TUNNEL OPTIONS"))]
|
||||
pub tunnel_options: args::TunnelArgs,
|
||||
}
|
||||
|
||||
/// Entrypoint for a standalone "code-tunnel" subcommand. This is a temporary
|
||||
/// artifact until we're ready to do swap to the full "code" CLI, and most
|
||||
/// code in here is duplicated from `src/bin/code/main.rs`
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), std::convert::Infallible> {
|
||||
let parsed = TunnelCli::parse();
|
||||
let context = CommandContext {
|
||||
http: reqwest::Client::new(),
|
||||
paths: LauncherPaths::new(&parsed.global_options.cli_data_dir).unwrap(),
|
||||
log: own_log::Logger::new(
|
||||
SdkTracerProvider::builder().build().tracer("codecli"),
|
||||
if parsed.global_options.verbose {
|
||||
own_log::Level::Trace
|
||||
} else {
|
||||
parsed.global_options.log.unwrap_or(own_log::Level::Info)
|
||||
},
|
||||
),
|
||||
args: args::CliCore {
|
||||
global_options: parsed.global_options,
|
||||
subcommand: Some(args::Commands::Tunnel(parsed.tunnel_options.clone())),
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
|
||||
log::set_logger(Box::leak(Box::new(RustyLogger(context.log.clone()))))
|
||||
.map(|()| log::set_max_level(log::LevelFilter::Debug))
|
||||
.expect("expected to make logger");
|
||||
|
||||
let result = match parsed.tunnel_options.subcommand {
|
||||
Some(args::TunnelSubcommand::Prune) => tunnels::prune(context).await,
|
||||
Some(args::TunnelSubcommand::Unregister) => tunnels::unregister(context).await,
|
||||
Some(args::TunnelSubcommand::Rename(rename_args)) => {
|
||||
tunnels::rename(context, rename_args).await
|
||||
}
|
||||
Some(args::TunnelSubcommand::User(user_command)) => {
|
||||
tunnels::user(context, user_command).await
|
||||
}
|
||||
Some(args::TunnelSubcommand::Service(service_args)) => {
|
||||
tunnels::service(context, service_args).await
|
||||
}
|
||||
None => tunnels::serve(context, parsed.tunnel_options.serve_args).await,
|
||||
};
|
||||
|
||||
match result {
|
||||
Err(e) => print_and_exit(e),
|
||||
Ok(code) => std::process::exit(code),
|
||||
}
|
||||
}
|
||||
|
||||
fn print_and_exit<E>(err: E) -> !
|
||||
where
|
||||
E: std::fmt::Display,
|
||||
{
|
||||
own_log::emit(own_log::Level::Error, "", &format!("{}", err));
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
/// Logger that uses the common rust "log" crate and directs back to one of
|
||||
/// our managed loggers.
|
||||
struct RustyLogger(own_log::Logger);
|
||||
|
||||
impl log::Log for RustyLogger {
|
||||
fn enabled(&self, metadata: &Metadata) -> bool {
|
||||
metadata.level() <= Level::Debug
|
||||
}
|
||||
|
||||
fn log(&self, record: &Record) {
|
||||
if !self.enabled(record.metadata()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// exclude noisy log modules:
|
||||
let src = match record.module_path() {
|
||||
Some("russh::cipher") => return,
|
||||
Some("russh::negotiation") => return,
|
||||
Some(s) => s,
|
||||
None => "<unknown>",
|
||||
};
|
||||
|
||||
self.0.emit(
|
||||
match record.level() {
|
||||
log::Level::Debug => own_log::Level::Debug,
|
||||
log::Level::Error => own_log::Level::Error,
|
||||
log::Level::Info => own_log::Level::Info,
|
||||
log::Level::Trace => own_log::Level::Trace,
|
||||
log::Level::Warn => own_log::Level::Warn,
|
||||
},
|
||||
&format!("[{}] {}", src, record.args()),
|
||||
);
|
||||
}
|
||||
|
||||
fn flush(&self) {}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ pub const CONTROL_PORT: u16 = 31545;
|
||||
pub const PROTOCOL_VERSION: u32 = 1;
|
||||
|
||||
pub const VSCODE_CLI_VERSION: Option<&'static str> = option_env!("VSCODE_CLI_VERSION");
|
||||
pub const VSCODE_CLI_ASSET_NAME: Option<&'static str> = option_env!("VSCODE_CLI_ASSET_NAME");
|
||||
pub const VSCODE_CLI_AI_KEY: Option<&'static str> = option_env!("VSCODE_CLI_AI_KEY");
|
||||
pub const VSCODE_CLI_AI_ENDPOINT: Option<&'static str> = option_env!("VSCODE_CLI_AI_ENDPOINT");
|
||||
pub const VSCODE_CLI_QUALITY: Option<&'static str> = option_env!("VSCODE_CLI_QUALITY");
|
||||
|
||||
+60
-15
@@ -3,20 +3,17 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
use std::{
|
||||
fs::{rename, set_permissions},
|
||||
path::Path,
|
||||
};
|
||||
use std::{fs, path::Path, process::Command};
|
||||
use tempfile::tempdir;
|
||||
|
||||
use crate::{
|
||||
constants::{VSCODE_CLI_COMMIT, VSCODE_CLI_QUALITY},
|
||||
options::Quality,
|
||||
update_service::{Platform, Release, TargetKind, UpdateService},
|
||||
update_service::{unzip_downloaded_release, Platform, Release, TargetKind, UpdateService},
|
||||
util::{
|
||||
errors::{wrap, AnyError, UpdatesNotConfigured},
|
||||
errors::{wrap, AnyError, CorruptDownload, UpdatesNotConfigured},
|
||||
http,
|
||||
io::ReportCopyProgress,
|
||||
io::{ReportCopyProgress, SilentCopyProgress},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -66,32 +63,80 @@ impl<'a> SelfUpdate<'a> {
|
||||
release: &Release,
|
||||
progress: impl ReportCopyProgress,
|
||||
) -> Result<(), AnyError> {
|
||||
// 1. Download the archive into a temporary directory
|
||||
let tempdir = tempdir().map_err(|e| wrap(e, "Failed to create temp dir"))?;
|
||||
let archive_path = tempdir.path().join("archive");
|
||||
let stream = self.update_service.get_download_stream(release).await?;
|
||||
http::download_into_file(&archive_path, progress, stream).await?;
|
||||
|
||||
// 2. Unzip the archive and get the binary
|
||||
let target_path =
|
||||
std::env::current_exe().map_err(|e| wrap(e, "could not get current exe"))?;
|
||||
let staging_path = target_path.with_extension(".update");
|
||||
let archive_contents_path = tempdir.path().join("content");
|
||||
// unzipping the single binary is pretty small and fast--don't bother with passing progress
|
||||
unzip_downloaded_release(&archive_path, &archive_contents_path, SilentCopyProgress())?;
|
||||
copy_updated_cli_to_path(&archive_contents_path, &staging_path)?;
|
||||
|
||||
http::download_into_file(&staging_path, progress, stream).await?;
|
||||
|
||||
// 3. Copy file metadata, make sure the new binary is executable\
|
||||
copy_file_metadata(&target_path, &staging_path)
|
||||
.map_err(|e| wrap(e, "failed to set file permissions"))?;
|
||||
validate_cli_is_good(&staging_path)?;
|
||||
|
||||
// Try to rename the old CLI to a tempdir, where it can get cleaned up by the
|
||||
// Try to rename the old CLI to the tempdir, where it can get cleaned up by the
|
||||
// OS later. However, this can fail if the tempdir is on a different drive
|
||||
// than the installation dir. In this case just rename it to ".old".
|
||||
let disposal_dir = tempdir().map_err(|e| wrap(e, "Failed to create disposal dir"))?;
|
||||
if rename(&target_path, &disposal_dir.path().join("old-code-cli")).is_err() {
|
||||
rename(&target_path, &target_path.with_extension(".old"))
|
||||
if fs::rename(&target_path, &tempdir.path().join("old-code-cli")).is_err() {
|
||||
fs::rename(&target_path, &target_path.with_extension(".old"))
|
||||
.map_err(|e| wrap(e, "failed to rename old CLI"))?;
|
||||
}
|
||||
|
||||
rename(&staging_path, &target_path)
|
||||
fs::rename(&staging_path, &target_path)
|
||||
.map_err(|e| wrap(e, "failed to rename newly installed CLI"))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_cli_is_good(exe_path: &Path) -> Result<(), AnyError> {
|
||||
let o = Command::new(exe_path)
|
||||
.args(["--version"])
|
||||
.output()
|
||||
.map_err(|e| CorruptDownload(format!("could not execute new binary, aborting: {}", e)))?;
|
||||
|
||||
if !o.status.success() {
|
||||
let msg = format!(
|
||||
"could not execute new binary, aborting. Stdout:\r\n\r\n{}\r\n\r\nStderr:\r\n\r\n{}",
|
||||
String::from_utf8_lossy(&o.stdout),
|
||||
String::from_utf8_lossy(&o.stderr),
|
||||
);
|
||||
|
||||
return Err(CorruptDownload(msg).into());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_updated_cli_to_path(unzipped_content: &Path, staging_path: &Path) -> Result<(), AnyError> {
|
||||
let unzipped_files = fs::read_dir(unzipped_content)
|
||||
.map_err(|e| wrap(e, "could not read update contents"))?
|
||||
.collect::<Vec<_>>();
|
||||
if unzipped_files.len() != 1 {
|
||||
let msg = format!(
|
||||
"expected exactly one file in update, got {}",
|
||||
unzipped_files.len()
|
||||
);
|
||||
return Err(CorruptDownload(msg).into());
|
||||
}
|
||||
|
||||
let archive_file = unzipped_files[0]
|
||||
.as_ref()
|
||||
.map_err(|e| wrap(e, "error listing update files"))?;
|
||||
fs::copy(&archive_file.path(), staging_path)
|
||||
.map_err(|e| wrap(e, "error copying to staging file"))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn copy_file_metadata(from: &Path, to: &Path) -> Result<(), std::io::Error> {
|
||||
let permissions = from.metadata()?.permissions();
|
||||
@@ -105,7 +150,7 @@ fn copy_file_metadata(from: &Path, to: &Path) -> Result<(), std::io::Error> {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
|
||||
let metadata = from.metadata()?;
|
||||
set_permissions(&to, metadata.permissions())?;
|
||||
fs::set_permissions(&to, metadata.permissions())?;
|
||||
|
||||
// based on coreutils' chown https://github.com/uutils/coreutils/blob/72b4629916abe0852ad27286f4e307fbca546b6e/src/chown/chown.rs#L266-L281
|
||||
let s = std::ffi::CString::new(to.as_os_str().as_bytes()).unwrap();
|
||||
|
||||
@@ -220,6 +220,7 @@ pub enum Platform {
|
||||
DarwinARM64,
|
||||
WindowsX64,
|
||||
WindowsX86,
|
||||
WindowsARM64
|
||||
}
|
||||
|
||||
impl Platform {
|
||||
@@ -232,6 +233,7 @@ impl Platform {
|
||||
Platform::DarwinARM64 => Some("darwin-arm64".to_owned()),
|
||||
Platform::WindowsX64 => Some("win32-x64-archive".to_owned()),
|
||||
Platform::WindowsX86 => Some("win32-archive".to_owned()),
|
||||
Platform::WindowsARM64 => Some("win32-arm64-archive".to_owned()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -246,6 +248,7 @@ impl Platform {
|
||||
Platform::DarwinARM64 => "server-darwin-arm64",
|
||||
Platform::WindowsX64 => "server-win32-x64",
|
||||
Platform::WindowsX86 => "server-win32",
|
||||
Platform::WindowsARM64 => "server-win32-arm64",
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
@@ -253,14 +256,15 @@ impl Platform {
|
||||
pub fn cli(&self) -> String {
|
||||
match self {
|
||||
Platform::LinuxAlpineARM64 => "cli-alpine-arm64",
|
||||
Platform::LinuxAlpineX64 => "cli-linux-alpine",
|
||||
Platform::LinuxAlpineX64 => "cli-alpine-x64",
|
||||
Platform::LinuxX64 => "cli-linux-x64",
|
||||
Platform::LinuxARM64 => "cli-linux-arm64",
|
||||
Platform::LinuxARM32 => "cli-linux-armhf",
|
||||
Platform::DarwinX64 => "cli-darwin-x64",
|
||||
Platform::DarwinARM64 => "cli-darwin-arm64",
|
||||
Platform::WindowsARM64 => "cli-win32-arm64",
|
||||
Platform::WindowsX64 => "cli-win32-x64",
|
||||
Platform::WindowsX86 => "cli-win32-x84",
|
||||
Platform::WindowsX86 => "cli-win32",
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
|
||||
+11
-1
@@ -362,6 +362,15 @@ impl std::fmt::Display for WindowsNeedsElevation {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct CorruptDownload(pub String);
|
||||
|
||||
impl std::fmt::Display for CorruptDownload {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Error updating the VS Code CLI: {}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
// Makes an "AnyError" enum that contains any of the given errors, in the form
|
||||
// `enum AnyError { FooError(FooError) }` (when given `makeAnyError!(FooError)`).
|
||||
// Useful to easily deal with application error types without making tons of "From"
|
||||
@@ -423,7 +432,8 @@ makeAnyError!(
|
||||
ServerHasClosed,
|
||||
ServiceAlreadyRegistered,
|
||||
WindowsNeedsElevation,
|
||||
UpdatesNotConfigured
|
||||
UpdatesNotConfigured,
|
||||
CorruptDownload
|
||||
);
|
||||
|
||||
impl From<reqwest::Error> for AnyError {
|
||||
|
||||
Reference in New Issue
Block a user