Pārlūkot izejas kodu

added installation commands for MVP

tensor-programming 6 gadi atpakaļ
vecāks
revīzija
b0e70e74ae

+ 49 - 0
tools/rust/cargo-proton-bundle/Cargo.lock

@@ -214,6 +214,7 @@ dependencies = [
  "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog-term 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "target_build_utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1364,6 +1365,27 @@ dependencies = [
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "rand"
+version = "0.3.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rand"
 version = "0.6.5"
@@ -1784,6 +1806,18 @@ name = "slog"
 version = "2.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "slog-term"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "smallvec"
 version = "0.6.10"
@@ -1886,6 +1920,16 @@ dependencies = [
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "term"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dirs 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "textwrap"
 version = "0.11.0"
@@ -2138,6 +2182,7 @@ name = "uuid"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
+ "rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
  "sha1 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2517,6 +2562,8 @@ dependencies = [
 "checksum publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5afecba86dcf1e4fd610246f89899d1924fe12e1e89f555eb7c7f710f3c5ad1d"
 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
 "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
+"checksum rand 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)" = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
+"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
 "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
 "checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
 "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
@@ -2564,6 +2611,7 @@ dependencies = [
 "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac"
 "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
 "checksum slog 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1cc9c640a4adbfbcc11ffb95efe5aa7af7309e002adab54b185507dbf2377b99"
+"checksum slog-term 2.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cb9b3fd9a3c2c86580fce3558a98ed7c69039da0288b08a3f15b371635254e08"
 "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
 "checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
 "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
@@ -2577,6 +2625,7 @@ dependencies = [
 "checksum target_build_utils 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "013d134ae4a25ee744ad6129db589018558f620ddfa44043887cdd45fa08e75c"
 "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
 "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
+"checksum term 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
 "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
 "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"

+ 2 - 1
tools/rust/cargo-proton-bundle/Cargo.toml

@@ -28,9 +28,10 @@ tar = "0.4"
 target_build_utils = "0.3"
 term = "0.4"
 toml = "0.4"
-uuid = { version = "0.5", features = ["v5"] }
+uuid = { version = "0.5", features = ["v5", "v4"] }
 walkdir = "2"
 
+slog-term = "2.4.1"
 sha2 = "0.8"
 lazy_static = "1.3"
 handlebars = "1.1"

+ 3 - 0
tools/rust/cargo-proton-bundle/src/bundle/build_msi.rs

@@ -0,0 +1,3 @@
+use semver::Version;
+use Platform;
+use WIX;

+ 39 - 29
tools/rust/cargo-proton-bundle/src/bundle/msi_bundle.rs

@@ -1,10 +1,14 @@
 use super::common;
 use super::settings::Settings;
+use super::wix;
 use crate::ResultExt;
 use cab;
 use msi;
+use slog::Drain;
+use slog_term;
 use std;
 use std::collections::{BTreeMap, HashMap, HashSet};
+use std::env;
 use std::ffi::OsStr;
 use std::fs;
 use std::io::{self, Write};
@@ -90,39 +94,45 @@ pub fn bundle_project(settings: &Settings) -> crate::Result<Vec<PathBuf>> {
   let cabinets = divide_resources_into_cabinets(resources);
   generate_resource_cabinets(&mut package, &cabinets)
     .chain_err(|| "Failed to generate resource cabinets")?;
+  let decorator = slog_term::TermDecorator::new().build();
+  let drain = slog_term::CompactFormat::new(decorator).build();
+  let drain = std::sync::Mutex::new(drain).fuse();
+  let logger = slog::Logger::root(drain, o!());
+
+  wix::get_and_extract_wix(&logger, &env::home_dir().unwrap());
 
   // Set up installer database tables:
-  create_directory_table(&mut package, &directories)
-    .chain_err(|| "Failed to generate Directory table")?;
-  create_feature_table(&mut package, settings).chain_err(|| "Failed to generate Feature table")?;
-  create_component_table(&mut package, guid, &directories)
-    .chain_err(|| "Failed to generate Component table")?;
-  create_feature_components_table(&mut package, &directories)
-    .chain_err(|| "Failed to generate FeatureComponents table")?;
-  create_media_table(&mut package, &cabinets).chain_err(|| "Failed to generate Media table")?;
-  create_file_table(&mut package, &cabinets).chain_err(|| "Failed to generate File table")?;
-  // TODO: Create other needed tables.
+  // create_directory_table(&mut package, &directories)
+  //   .chain_err(|| "Failed to generate Directory table")?;
+  // create_feature_table(&mut package, settings).chain_err(|| "Failed to generate Feature table")?;
+  // create_component_table(&mut package, guid, &directories)
+  //   .chain_err(|| "Failed to generate Component table")?;
+  // create_feature_components_table(&mut package, &directories)
+  //   .chain_err(|| "Failed to generate FeatureComponents table")?;
+  // create_media_table(&mut package, &cabinets).chain_err(|| "Failed to generate Media table")?;
+  // create_file_table(&mut package, &cabinets).chain_err(|| "Failed to generate File table")?;
+  // // TODO: Create other needed tables.
 
-  // Create app icon:
-  package.create_table(
-    "Icon",
-    vec![
-      msi::Column::build("Name").primary_key().id_string(72),
-      msi::Column::build("Data").binary(),
-    ],
-  )?;
-  let icon_name = format!("{}.ico", settings.binary_name());
-  {
-    let stream_name = format!("Icon.{}", icon_name);
-    let mut stream = package.write_stream(&stream_name)?;
-    create_app_icon(&mut stream, settings)?;
-  }
-  package.insert_rows(msi::Insert::into("Icon").row(vec![
-    msi::Value::Str(icon_name.clone()),
-    msi::Value::from("Name"),
-  ]))?;
+  // // Create app icon:
+  // package.create_table(
+  //   "Icon",
+  //   vec![
+  //     msi::Column::build("Name").primary_key().id_string(72),
+  //     msi::Column::build("Data").binary(),
+  //   ],
+  // )?;
+  // let icon_name = format!("{}.ico", settings.binary_name());
+  // {
+  //   let stream_name = format!("Icon.{}", icon_name);
+  //   let mut stream = package.write_stream(&stream_name)?;
+  //   create_app_icon(&mut stream, settings)?;
+  // }
+  // package.insert_rows(msi::Insert::into("Icon").row(vec![
+  //   msi::Value::Str(icon_name.clone()),
+  //   msi::Value::from("Name"),
+  // ]))?;
 
-  package.flush()?;
+  // package.flush()?;
   Ok(vec![msi_path])
 }
 

+ 1 - 1
tools/rust/cargo-proton-bundle/src/bundle/settings.rs

@@ -252,7 +252,7 @@ impl Settings {
           - Stop at the first one found.
           - If one is found before reaching "/" then this folder belongs to that parent workspace
   */
-  fn get_workspace_dir(current_dir: &PathBuf) -> PathBuf {
+  pub fn get_workspace_dir(current_dir: &PathBuf) -> PathBuf {
     let mut dir = current_dir.clone();
     while dir.pop() {
       let set = CargoSettings::load(&dir);

+ 67 - 1
tools/rust/cargo-proton-bundle/src/bundle/templates/main.wxs

@@ -9,5 +9,71 @@
 <?endif?>
 
 <Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
-    
+    <Product
+            Id="*"
+            Name="{{{product_name}}}"
+            UpgradeCode="{{{upgrade_code}}}"
+            Language="1033"
+            Codepage="1252"
+            Manufacturer="{{{manufacturer}}}"
+            Version="{{{version}}}">
+
+        <Package Id="*"
+                 Keywords="Installer"
+                 InstallerVersion="450"
+                 Languages="1033"
+                 Compressed="yes"
+                 InstallScope="perMachine"
+                 SummaryCodepage="1252"/>
+
+        <MajorUpgrade
+                Schedule="afterInstallInitialize"
+                DowngradeErrorMessage="A newer version of [ProductName] is already installed. Setup will now exit."/>
+
+        <Media Id="1" Cabinet="media1.cab" EmbedCab="yes"/>
+
+        <Directory Id="TARGETDIR" Name="SourceDir">
+            <Directory Id="$(var.PlatformProgramFilesFolder)" Name="PFiles">
+                <Directory Id="APPLICATIONFOLDER" Name="{{{product_name}}}">
+                    <Component Id="Path" Guid="{{{path_component_guid}}}" Win64="$(var.Win64)" KeyPath="yes">
+                        <Environment
+                                Id="PATH"
+                                Name="PATH"
+                                Value="[Bin]"
+                                Permanent="no"
+                                Part="last"
+                                Action="set"
+                                System="yes"/>
+                    </Component>
+                </Directory>
+            </Directory>
+        </Directory>
+
+        <Feature
+                Id="MainProgram"
+                Title="Application"
+                Description="Installs the executable."
+                Level="1"
+                ConfigurableDirectory="APPLICATIONFOLDER"
+                AllowAdvertise="no"
+                Display="expand"
+                Absent="disallow">
+            <ComponentGroupRef Id="AppFiles"/>
+            <Feature
+                    Id="Environment"
+                    Title="PATH Environment Variable"
+                    Description="Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location."
+                    Level="1"
+                    Absent="allow">
+                <ComponentRef Id="Path"/>
+            </Feature>
+        </Feature>
+
+        <SetProperty Id="ARPINSTALLLOCATION" Value="[APPLICATIONFOLDER]" After="CostFinalize"/>
+
+        <UI>
+            <UIRef Id="WixUI_FeatureTree"/>
+        </UI>
+
+    </Product>
 </Wix>

+ 116 - 4
tools/rust/cargo-proton-bundle/src/bundle/wix.rs

@@ -1,18 +1,20 @@
+use super::settings::Settings;
 use handlebars::Handlebars;
 use lazy_static::lazy_static;
 use sha2::Digest;
 use slog::info;
 use slog::Logger;
 use std::collections::BTreeMap;
-use std::fs::{create_dir_all, File};
+use std::fs::{create_dir_all, remove_dir_all, write, File};
 use std::io::{BufRead, BufReader, Cursor, Read, Write};
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
+use uuid::Uuid;
 use zip::ZipArchive;
 
-const WIX_URL: &str =
+pub const WIX_URL: &str =
   "https://github.com/wixtoolset/wix3/releases/download/wix3111rtm/wix311-binaries.zip";
-const WIX_SHA256: &str = "37f0a533b0978a454efb5dc3bd3598becf9660aaf4287e55bf68ca6b527d051d";
+pub const WIX_SHA256: &str = "37f0a533b0978a454efb5dc3bd3598becf9660aaf4287e55bf68ca6b527d051d";
 
 const VC_REDIST_X86_URL: &str =
     "https://download.visualstudio.microsoft.com/download/pr/c8edbb87-c7ec-4500-a461-71e8912d25e9/99ba493d660597490cbb8b3211d2cae4/vc_redist.x86.exe";
@@ -63,6 +65,20 @@ fn download_and_verify(logger: &Logger, url: &str, hash: &str) -> Result<Vec<u8>
   }
 }
 
+fn app_installer_dir(settings: &Settings) -> PathBuf {
+  let arch = match settings.binary_arch() {
+    "i686-pc-windows-msvc" => "x86",
+    "x86_64-pc-windows-msvc" => "amd64",
+    target => panic!("unsupported target: {}", target),
+  };
+
+  settings.project_out_directory().to_path_buf().join(format!(
+    "{}.{}.msi",
+    settings.bundle_name(),
+    arch
+  ))
+}
+
 fn extract_zip(data: &Vec<u8>, path: &Path) -> Result<(), String> {
   let cursor = Cursor::new(data);
 
@@ -89,7 +105,7 @@ fn extract_zip(data: &Vec<u8>, path: &Path) -> Result<(), String> {
   Ok(())
 }
 
-fn get_and_extract_wix(logger: &Logger, path: &Path) -> Result<(), String> {
+pub fn get_and_extract_wix(logger: &Logger, path: &Path) -> Result<(), String> {
   info!(logger, "downloading WIX Toolkit...");
 
   let data = download_and_verify(logger, WIX_URL, WIX_SHA256)?;
@@ -151,6 +167,7 @@ fn run_heat_exe(
 }
 
 fn run_candle(
+  settings: &Settings,
   logger: &Logger,
   wix_toolset_path: &Path,
   build_path: &Path,
@@ -159,9 +176,14 @@ fn run_candle(
   let arch = "x64";
 
   let args = vec![
+    "-ext".to_string(),
+    "WixBalExtension".to_string(),
+    "-ext".to_string(),
+    "WixUtilExtension".to_string(),
     "-arch".to_string(),
     arch.to_string(),
     wxs_file_name.to_string(),
+    format!("-dSourceDir={}", settings.binary_path().display()),
   ];
 
   let candle_exe = wix_toolset_path.join("candle.exe");
@@ -229,3 +251,93 @@ fn run_light(
     Err("error running light.exe".to_string())
   }
 }
+
+pub fn build_wix_app_installer(
+  logger: &Logger,
+  settings: &Settings,
+  wix_toolset_path: &Path,
+  current_dir: PathBuf,
+) -> Result<(), String> {
+  let arch = match settings.binary_arch() {
+    "i686-pc-windows-msvc" => "x86",
+    "x86_64-pc-windows-msvc" => "amd64",
+    target => return Err(format!("unsupported target: {}", target)),
+  };
+
+  let output_path = settings.project_out_directory().join("wix").join(arch);
+
+  let mut data = BTreeMap::new();
+
+  data.insert("product_name", settings.bundle_name());
+  data.insert("version", settings.version_string());
+  let upgrade_code = if arch == "x86" {
+    Uuid::new_v5(
+      &uuid::NAMESPACE_DNS,
+      format!("{}.app.x64", &settings.bundle_name()).as_str(),
+    )
+    .to_string()
+  } else if arch == "x64" {
+    Uuid::new_v5(
+      &uuid::NAMESPACE_DNS,
+      format!("{}.app.x64", &settings.bundle_name()).as_str(),
+    )
+    .to_string()
+  } else {
+    panic!("unsupported target: {}");
+  };
+
+  data.insert("upgrade_code", &upgrade_code);
+
+  let path_guid = Uuid::new_v4().to_string();
+  data.insert("path_component_guid", &path_guid);
+
+  let app_exe_name = settings
+    .binary_path()
+    .file_name()
+    .unwrap()
+    .to_string_lossy()
+    .to_string();
+  data.insert("app_exe_name", &app_exe_name);
+
+  let app_exe_source = settings.binary_path().display().to_string();
+  data.insert("app_exe_source", &app_exe_source);
+
+  let temp = HANDLEBARS
+    .render("main.wxs", &data)
+    .or_else(|e| Err(e.to_string()))?;
+
+  if output_path.exists() {
+    remove_dir_all(&output_path).or_else(|e| Err(e.to_string()))?;
+  }
+
+  create_dir_all(&output_path).or_else(|e| Err(e.to_string()))?;
+
+  let main_wxs_path = output_path.join("main.wxs");
+  write(&main_wxs_path, temp).or_else(|e| Err(e.to_string()))?;
+
+  run_heat_exe(
+    logger,
+    &wix_toolset_path,
+    &output_path,
+    &Settings::get_workspace_dir(&current_dir),
+    arch,
+  )?;
+
+  let input_basenames = vec!["main", "appdir"];
+
+  for basename in &input_basenames {
+    let wxs = format!("{}.wxs", basename);
+    run_candle(settings, logger, &wix_toolset_path, &output_path, &wxs)?;
+  }
+
+  let wixobjs = vec!["main.wixobj", "appdir.wixobj"];
+  run_light(
+    logger,
+    &wix_toolset_path,
+    &output_path,
+    &wixobjs,
+    &app_installer_dir(settings),
+  )?;
+
+  Ok(())
+}

+ 3 - 0
tools/rust/cargo-proton-bundle/src/main.rs

@@ -10,6 +10,9 @@ extern crate serde_derive;
 #[cfg(test)]
 extern crate tempfile;
 
+#[macro_use]
+extern crate slog;
+
 mod bundle;
 
 use crate::bundle::{bundle_project, BuildArtifact, PackageType, Settings};