WASM plugins, scripting, i18n, GUI pan/zoom, cargo-dist CI/CD
- WASM plugin host (wasmtime 46, 17 host fns) + example noisemap plugin - Rhai scripting engine (12 API fns, `terrafier run` cmd) - i18n: en/ru translations, auto-detect, t! macro - GUI: pan (click-drag) + zoom (scroll wheel) with viewport transform - cargo-dist 0.31: MSI/pkg/shell installers, both binaries - CI: .github/workflows/ci.yml + release.yml - Security: wasmtime 30→46, bincode 1.3→2.0, quick-xml CVE docs - Code review: SAFETY comments, unwrap→match cleanup - Fixes: clippy approx_constant, needless_borrows, rustfmt
This commit is contained in:
parent
bdd4564240
commit
18613260a8
100 changed files with 4262 additions and 585 deletions
|
|
@ -3,13 +3,26 @@ name = "terrafier-cli"
|
|||
version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
repository.workspace = true
|
||||
authors.workspace = true
|
||||
description = "CLI tool for Terrafier — create, edit, export Minecraft worlds from the command line"
|
||||
|
||||
[package.metadata.wix]
|
||||
upgrade-guid = "351D0A14-B7C2-412B-BEB5-BD394ED35C94"
|
||||
path-guid = "C4FB2FF3-085A-4CDF-B823-B0A2EB5B8220"
|
||||
license = false
|
||||
eula = false
|
||||
|
||||
[dependencies]
|
||||
terrafier-core = { path = "../core" }
|
||||
terrafier-scripting = { path = "../crates/scripting", optional = true }
|
||||
terrafier-i18n = { path = "../crates/i18n" }
|
||||
clap.workspace = true
|
||||
anyhow.workspace = true
|
||||
indicatif.workspace = true
|
||||
log.workspace = true
|
||||
env_logger.workspace = true
|
||||
serde_json.workspace = true
|
||||
|
||||
[features]
|
||||
scripting = ["terrafier-scripting"]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use clap::Args;
|
||||
use std::path::Path;
|
||||
use terrafier_i18n as i18n;
|
||||
|
||||
use crate::util::output::{self, OutputFormat};
|
||||
use crate::util::{load_world, progress};
|
||||
|
|
@ -31,6 +32,9 @@ pub fn cmd_export(
|
|||
let tile_count: usize = world.dimensions.iter().map(|d| d.tiles.len()).sum();
|
||||
|
||||
if validate || dry_run {
|
||||
if dry_run {
|
||||
log::info!("{}", i18n::translate_with("cli.dry_run", &[("action", "export")]));
|
||||
}
|
||||
output::print_result(
|
||||
format,
|
||||
&serde_json::json!({
|
||||
|
|
@ -45,9 +49,10 @@ pub fn cmd_export(
|
|||
}
|
||||
}
|
||||
|
||||
let bar = progress::new_bar(tile_count as u64, "Exporting...");
|
||||
let exporting_msg = i18n::translate_with("cli.export.exporting", &[("path", &args.output)]);
|
||||
let bar = progress::new_bar(tile_count as u64, &exporting_msg);
|
||||
terrafier_core::io::export::export_to_save(&world, Path::new(&args.output))?;
|
||||
progress::finish_with("Export complete", bar);
|
||||
progress::finish_with(i18n::t!("cli.export.complete"), bar);
|
||||
|
||||
log::info!("World exported to: {}", args.output);
|
||||
output::print_result(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use clap::Args;
|
||||
use std::path::Path;
|
||||
use terrafier_i18n as i18n;
|
||||
|
||||
use crate::util::output::{self, OutputFormat};
|
||||
use crate::util::progress;
|
||||
|
|
@ -22,6 +23,9 @@ pub fn cmd_import(
|
|||
log::info!("Importing Minecraft save from: {}", input_path.display());
|
||||
|
||||
if validate || dry_run {
|
||||
if dry_run {
|
||||
log::info!("{}", i18n::translate_with("cli.dry_run", &[("action", "import")]));
|
||||
}
|
||||
terrafier_core::io::import::validate_save(input_path)?;
|
||||
output::print_result(
|
||||
format,
|
||||
|
|
@ -46,9 +50,15 @@ pub fn cmd_import(
|
|||
} else {
|
||||
0
|
||||
};
|
||||
let bar = progress::new_bar(region_count.max(1) as u64, "Importing regions...");
|
||||
let importing_msg = i18n::translate_with("cli.import.importing", &[("path", &args.input)]);
|
||||
let bar = progress::new_bar(region_count.max(1) as u64, &importing_msg);
|
||||
let world = terrafier_core::io::import::import(input_path)?;
|
||||
progress::finish_with("Import complete", bar);
|
||||
let tile_count: usize = world.dimensions.iter().map(|d| d.tiles.len()).sum();
|
||||
let import_msg = i18n::translate_with("cli.import.complete", &[
|
||||
("tiles", &tile_count.to_string()),
|
||||
("dimensions", &world.dimensions.len().to_string()),
|
||||
]);
|
||||
progress::finish_with(&import_msg, bar);
|
||||
|
||||
let output_path = Path::new(&args.output);
|
||||
std::fs::create_dir_all(output_path)?;
|
||||
|
|
@ -56,7 +66,6 @@ pub fn cmd_import(
|
|||
let world_json = serde_json::to_string_pretty(&world)?;
|
||||
std::fs::write(output_path.join("world.tfw"), &world_json)?;
|
||||
|
||||
let tile_count: usize = world.dimensions.iter().map(|d| d.tiles.len()).sum();
|
||||
log::info!(
|
||||
"Import complete: {} dimensions, {} tiles",
|
||||
world.dimensions.len(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use clap::Args;
|
||||
use std::path::PathBuf;
|
||||
use terrafier_i18n as i18n;
|
||||
|
||||
use crate::util::output::{self, OutputFormat};
|
||||
use crate::util::{load_world, progress};
|
||||
|
|
@ -31,6 +32,9 @@ pub fn cmd_render(
|
|||
let tile_count: usize = world.dimensions.iter().map(|d| d.tiles.len()).sum();
|
||||
|
||||
if validate || dry_run {
|
||||
if dry_run {
|
||||
log::info!("{}", i18n::translate_with("cli.dry_run", &[("action", "render")]));
|
||||
}
|
||||
output::print_result(
|
||||
format,
|
||||
&serde_json::json!({
|
||||
|
|
@ -44,9 +48,12 @@ pub fn cmd_render(
|
|||
}
|
||||
}
|
||||
|
||||
let bar = progress::new_bar(tile_count as u64, "Rendering...");
|
||||
let bar = progress::new_bar(tile_count as u64, i18n::t!("cli.render.rendering"));
|
||||
terrafier_core::io::export::render_to_image(&world, &args.output, args.scale)?;
|
||||
progress::finish_with("Render complete", bar);
|
||||
let saved_msg = i18n::translate_with("cli.render.saved", &[
|
||||
("path", &args.output.display().to_string()),
|
||||
]);
|
||||
progress::finish_with(&saved_msg, bar);
|
||||
|
||||
log::info!("Preview rendered to: {}", args.output.display());
|
||||
output::print_result(
|
||||
|
|
|
|||
|
|
@ -5,3 +5,8 @@ pub use io::render;
|
|||
|
||||
pub mod info;
|
||||
pub mod new;
|
||||
|
||||
#[cfg(feature = "scripting")]
|
||||
mod run;
|
||||
#[cfg(feature = "scripting")]
|
||||
pub use run::cmd_run;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use clap::Args;
|
||||
use std::path::PathBuf;
|
||||
use terrafier_core::World;
|
||||
use terrafier_i18n as i18n;
|
||||
|
||||
use crate::util::output::{self, OutputFormat};
|
||||
use crate::util::progress;
|
||||
|
|
@ -42,9 +43,14 @@ pub fn cmd_new(
|
|||
}
|
||||
}
|
||||
|
||||
let spinner = progress::new_spinner("Generating world...");
|
||||
let spinner = progress::new_spinner(i18n::t!("cli.new.creating"));
|
||||
let world = World::new(&args.name, args.seed);
|
||||
progress::finish_with("World generated", spinner);
|
||||
let tile_count = world.dimensions.iter().map(|d| d.tiles.len()).sum::<usize>();
|
||||
let created_msg = i18n::translate_with("cli.new.created", &[
|
||||
("name", &args.name),
|
||||
("tiles", &tile_count.to_string()),
|
||||
]);
|
||||
progress::finish_with(&created_msg, spinner);
|
||||
|
||||
let world_dir = args.output.join(&args.name);
|
||||
std::fs::create_dir_all(&world_dir)?;
|
||||
|
|
@ -52,7 +58,6 @@ pub fn cmd_new(
|
|||
let world_json = serde_json::to_string_pretty(&world)?;
|
||||
std::fs::write(world_dir.join("world.tfw"), &world_json)?;
|
||||
|
||||
let dim = &world.dimensions[0];
|
||||
log::info!("World saved to: {}", world_dir.display());
|
||||
output::print_result(
|
||||
format,
|
||||
|
|
@ -61,7 +66,7 @@ pub fn cmd_new(
|
|||
"name": args.name,
|
||||
"seed": args.seed,
|
||||
"path": world_dir.display().to_string(),
|
||||
"tiles": dim.tiles.len(),
|
||||
"tiles": tile_count,
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
|
|||
8
cli/src/cmds/run.rs
Normal file
8
cli/src/cmds/run.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
use anyhow::Result;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn cmd_run(script: &PathBuf) -> Result<()> {
|
||||
terrafier_scripting::run_script(script)?;
|
||||
println!("Script executed successfully.");
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
use clap::Parser;
|
||||
use std::path::PathBuf;
|
||||
|
||||
mod cmds;
|
||||
mod util;
|
||||
|
|
@ -38,9 +39,18 @@ enum Commands {
|
|||
Info(cmds::info::InfoArgs),
|
||||
/// Render world preview to an image
|
||||
Render(cmds::render::RenderArgs),
|
||||
/// Run a Terrafier script (.rhai)
|
||||
#[cfg(feature = "scripting")]
|
||||
Run {
|
||||
/// Path to .rhai script file
|
||||
script: PathBuf,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() {
|
||||
use terrafier_i18n as i18n;
|
||||
i18n::init();
|
||||
|
||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
|
||||
.format_timestamp(None)
|
||||
.init();
|
||||
|
|
@ -60,6 +70,8 @@ fn main() {
|
|||
Commands::Render(args) => {
|
||||
cmds::render::cmd_render(args, &format, cli.dry_run, cli.validate)
|
||||
}
|
||||
#[cfg(feature = "scripting")]
|
||||
Commands::Run { script } => cmds::cmd_run(&script),
|
||||
};
|
||||
|
||||
if let Err(e) = result {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use serde_json::Value;
|
||||
use terrafier_i18n as i18n;
|
||||
|
||||
pub enum OutputFormat {
|
||||
Json,
|
||||
|
|
@ -17,7 +18,11 @@ impl OutputFormat {
|
|||
pub fn print_result(format: &OutputFormat, result: &Value) {
|
||||
match format {
|
||||
OutputFormat::Json => {
|
||||
println!("{}", serde_json::to_string(result).unwrap());
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string(result)
|
||||
.unwrap_or_else(|e| format!("serialization error: {e}"))
|
||||
);
|
||||
}
|
||||
OutputFormat::Human => print_human(result),
|
||||
}
|
||||
|
|
@ -31,68 +36,116 @@ fn print_human(result: &Value) {
|
|||
let seed = result["seed"].as_u64().unwrap_or(0);
|
||||
let tiles = result["tiles"].as_u64().unwrap_or(0);
|
||||
println!(
|
||||
"Created world '{}' (seed: {}, tiles: {})",
|
||||
name, seed, tiles
|
||||
"{}",
|
||||
i18n::translate_with("cli.new.created", &[
|
||||
("name", name),
|
||||
("tiles", &tiles.to_string()),
|
||||
])
|
||||
);
|
||||
let _ = seed;
|
||||
}
|
||||
"exported" => {
|
||||
let input = result["input"].as_str().unwrap_or("?");
|
||||
let output = result["output"].as_str().unwrap_or("?");
|
||||
let tiles = result["tiles"].as_u64().unwrap_or(0);
|
||||
println!("Exported {} tiles from '{}' to '{}'", tiles, input, output);
|
||||
println!(
|
||||
"{}",
|
||||
i18n::translate_with("cli.export.complete", &[
|
||||
("regions", "?"),
|
||||
("chunks", &tiles.to_string()),
|
||||
])
|
||||
);
|
||||
}
|
||||
"imported" => {
|
||||
let name = result["name"].as_str().unwrap_or("?");
|
||||
let seed = result["seed"].as_u64().unwrap_or(0);
|
||||
let dims = result["dimensions"].as_u64().unwrap_or(0);
|
||||
let tiles = result["tiles"].as_u64().unwrap_or(0);
|
||||
let dims = result["dimensions"].as_u64().unwrap_or(0);
|
||||
println!(
|
||||
"Imported world '{}' (seed: {}, {} dimensions, {} tiles)",
|
||||
name, seed, dims, tiles
|
||||
"{}",
|
||||
i18n::translate_with("cli.import.complete", &[
|
||||
("tiles", &tiles.to_string()),
|
||||
("dimensions", &dims.to_string()),
|
||||
])
|
||||
);
|
||||
let _ = name;
|
||||
}
|
||||
"rendered" => {
|
||||
let world = result["world"].as_str().unwrap_or("?");
|
||||
let output = result["output"].as_str().unwrap_or("?");
|
||||
println!("Rendered world '{}' to '{}'", world, output);
|
||||
println!(
|
||||
"{}",
|
||||
i18n::translate_with("cli.render.saved", &[
|
||||
("path", output),
|
||||
])
|
||||
);
|
||||
}
|
||||
"validated" => {
|
||||
println!("Validation passed: {:?}", result);
|
||||
println!("{}", i18n::t!("cli.validate.ok"));
|
||||
}
|
||||
_ => {
|
||||
println!("{}", serde_json::to_string_pretty(result).unwrap());
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(result)
|
||||
.unwrap_or_else(|e| format!("serialization error: {e}"))
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if result.get("name").is_some() {
|
||||
// Info output
|
||||
println!("World: {}", result["name"].as_str().unwrap_or("?"));
|
||||
if let Some(seed) = result.get("seed").and_then(|v| v.as_u64()) {
|
||||
println!(" Seed: {}", seed);
|
||||
}
|
||||
if let Some(platform) = result.get("platform").and_then(|v| v.as_str()) {
|
||||
println!(" Platform: {}", platform);
|
||||
}
|
||||
if let Some(height) = result.get("height_range") {
|
||||
let min = height["min"].as_i64().unwrap_or(0);
|
||||
let max = height["max"].as_i64().unwrap_or(0);
|
||||
println!(" Height range: {} to {}", min, max);
|
||||
}
|
||||
if let Some(dims) = result.get("dimensions").and_then(|v| v.as_array()) {
|
||||
println!(" Dimensions:");
|
||||
for dim in dims {
|
||||
let name = dim["name"].as_str().unwrap_or("?");
|
||||
let tiles = dim["tiles"].as_u64().unwrap_or(0);
|
||||
println!(" - {} ({} tiles)", name, tiles);
|
||||
}
|
||||
}
|
||||
if let Some(tiles) = result.get("total_tiles").and_then(|v| v.as_u64()) {
|
||||
println!(" Total tiles: {}", tiles);
|
||||
}
|
||||
if let Some(path) = result.get("path").and_then(|v| v.as_str()) {
|
||||
println!(" Path: {}", path);
|
||||
}
|
||||
print_human_info(result);
|
||||
} else {
|
||||
println!("{}", serde_json::to_string_pretty(result).unwrap());
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string_pretty(result)
|
||||
.unwrap_or_else(|e| format!("serialization error: {e}"))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn print_human_info(result: &Value) {
|
||||
let name = result["name"].as_str().unwrap_or("?");
|
||||
println!(
|
||||
"{}",
|
||||
i18n::translate_with("cli.info.title", &[("name", name)])
|
||||
);
|
||||
if let Some(seed) = result.get("seed").and_then(|v| v.as_u64()) {
|
||||
println!(
|
||||
" {}",
|
||||
i18n::translate_with("cli.info.seed", &[("seed", &seed.to_string())])
|
||||
);
|
||||
}
|
||||
if let Some(platform) = result.get("platform").and_then(|v| v.as_str()) {
|
||||
println!(
|
||||
" {}",
|
||||
i18n::translate_with("cli.info.platform", &[("platform", platform)])
|
||||
);
|
||||
}
|
||||
if let Some(height) = result.get("height_range") {
|
||||
let min = height["min"].as_i64().unwrap_or(0);
|
||||
let max = height["max"].as_i64().unwrap_or(0);
|
||||
eprintln!(" Height range: {} to {}", min, max);
|
||||
}
|
||||
if let Some(dims) = result.get("dimensions").and_then(|v| v.as_array()) {
|
||||
println!(
|
||||
" {}",
|
||||
i18n::translate_with("cli.info.dimensions", &[
|
||||
("dimensions", &dims.len().to_string()),
|
||||
])
|
||||
);
|
||||
for dim in dims {
|
||||
let dim_name = dim["name"].as_str().unwrap_or("?");
|
||||
let dim_tiles = dim["tiles"].as_u64().unwrap_or(0);
|
||||
println!(
|
||||
" - {} ({} tiles)",
|
||||
dim_name, dim_tiles
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(tiles) = result.get("total_tiles").and_then(|v| v.as_u64()) {
|
||||
println!(
|
||||
" {}",
|
||||
i18n::translate_with("cli.info.tiles", &[("tiles", &tiles.to_string())])
|
||||
);
|
||||
}
|
||||
if let Some(path) = result.get("path").and_then(|v| v.as_str()) {
|
||||
eprintln!(" Path: {}", path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -101,11 +154,12 @@ pub fn print_error(format: &OutputFormat, error: &anyhow::Error) {
|
|||
OutputFormat::Json => {
|
||||
eprintln!(
|
||||
"{}",
|
||||
serde_json::to_string(&serde_json::json!({"error": error.to_string()})).unwrap()
|
||||
serde_json::to_string(&serde_json::json!({"error": error.to_string()}))
|
||||
.unwrap_or_else(|e| format!("serialization error: {e}"))
|
||||
);
|
||||
}
|
||||
OutputFormat::Human => {
|
||||
eprintln!("Error: {}", error);
|
||||
eprintln!("{}: {}", i18n::t!("cli.status.error"), error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -116,7 +170,8 @@ pub fn print_info(format: &OutputFormat, msg: &str) {
|
|||
OutputFormat::Json => {
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string(&serde_json::json!({"info": msg})).unwrap()
|
||||
serde_json::to_string(&serde_json::json!({"info": msg}))
|
||||
.unwrap_or_else(|e| format!("serialization error: {e}"))
|
||||
);
|
||||
}
|
||||
OutputFormat::Human => {
|
||||
|
|
|
|||
228
cli/wix/main.wxs
Normal file
228
cli/wix/main.wxs
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
<?xml version='1.0' encoding='windows-1252'?>
|
||||
<!--
|
||||
Copyright (C) 2017 Christopher R. Field.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!--
|
||||
The "cargo wix" subcommand provides a variety of predefined variables available
|
||||
for customization of this template. The values for each variable are set at
|
||||
installer creation time. The following variables are available:
|
||||
|
||||
TargetTriple = The rustc target triple name.
|
||||
TargetEnv = The rustc target environment. This is typically either
|
||||
"msvc" or "gnu" depending on the toolchain downloaded and
|
||||
installed.
|
||||
TargetVendor = The rustc target vendor. This is typically "pc", but Rust
|
||||
does support other vendors, like "uwp".
|
||||
CargoTargetBinDir = The complete path to the directory containing the
|
||||
binaries (exes) to include. The default would be
|
||||
"target\release\". If an explicit rustc target triple is
|
||||
used, i.e. cross-compiling, then the default path would
|
||||
be "target\<CARGO_TARGET>\<CARGO_PROFILE>",
|
||||
where "<CARGO_TARGET>" is replaced with the "CargoTarget"
|
||||
variable value and "<CARGO_PROFILE>" is replaced with the
|
||||
value from the "CargoProfile" variable. This can also
|
||||
be overridden manually with the "target-bin-dir" flag.
|
||||
CargoTargetDir = The path to the directory for the build artifacts, i.e.
|
||||
"target".
|
||||
CargoProfile = The cargo profile used to build the binaries
|
||||
(usually "debug" or "release").
|
||||
Version = The version for the installer. The default is the
|
||||
"Major.Minor.Fix" semantic versioning number of the Rust
|
||||
package.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Please do not remove these pre-processor If-Else blocks. These are used with
|
||||
the `cargo wix` subcommand to automatically determine the installation
|
||||
destination for 32-bit versus 64-bit installers. Removal of these lines will
|
||||
cause installation errors.
|
||||
-->
|
||||
<?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
|
||||
<?else ?>
|
||||
<?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
|
||||
<?endif ?>
|
||||
|
||||
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
|
||||
|
||||
<Product
|
||||
Id='*'
|
||||
Name='terrafier-cli'
|
||||
UpgradeCode='351D0A14-B7C2-412B-BEB5-BD394ED35C94'
|
||||
Manufacturer='Loki'
|
||||
Language='1033'
|
||||
Codepage='1252'
|
||||
Version='$(var.Version)'>
|
||||
|
||||
<Package Id='*'
|
||||
Keywords='Installer'
|
||||
Description='CLI tool for Terrafier — create, edit, export Minecraft worlds from the command line'
|
||||
Manufacturer='Loki'
|
||||
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' DiskPrompt='CD-ROM #1'/>
|
||||
<Property Id='DiskPrompt' Value='terrafier-cli Installation'/>
|
||||
|
||||
<Directory Id='TARGETDIR' Name='SourceDir'>
|
||||
<Directory Id='$(var.PlatformProgramFilesFolder)' Name='PFiles'>
|
||||
<Directory Id='APPLICATIONFOLDER' Name='terrafier-cli'>
|
||||
|
||||
<!--
|
||||
Enabling the license sidecar file in the installer is a four step process:
|
||||
|
||||
1. Uncomment the `Component` tag and its contents.
|
||||
2. Change the value for the `Source` attribute in the `File` tag to a path
|
||||
to the file that should be included as the license sidecar file. The path
|
||||
can, and probably should be, relative to this file.
|
||||
3. Change the value for the `Name` attribute in the `File` tag to the
|
||||
desired name for the file when it is installed alongside the `bin` folder
|
||||
in the installation directory. This can be omitted if the desired name is
|
||||
the same as the file name.
|
||||
4. Uncomment the `ComponentRef` tag with the Id attribute value of "License"
|
||||
further down in this file.
|
||||
-->
|
||||
<!--
|
||||
<Component Id='License' Guid='*'>
|
||||
<File Id='LicenseFile' Name='ChangeMe' DiskId='1' Source='C:\Path\To\File' KeyPath='yes'/>
|
||||
</Component>
|
||||
-->
|
||||
|
||||
<Directory Id='Bin' Name='bin'>
|
||||
<Component Id='Path' Guid='C4FB2FF3-085A-4CDF-B823-B0A2EB5B8220' KeyPath='yes'>
|
||||
<Environment
|
||||
Id='PATH'
|
||||
Name='PATH'
|
||||
Value='[Bin]'
|
||||
Permanent='no'
|
||||
Part='last'
|
||||
Action='set'
|
||||
System='yes'/>
|
||||
</Component>
|
||||
<Component Id='binary0' Guid='*'>
|
||||
<File
|
||||
Id='exe0'
|
||||
Name='terrafier-cli.exe'
|
||||
DiskId='1'
|
||||
Source='$(var.CargoTargetBinDir)\terrafier-cli.exe'
|
||||
KeyPath='yes'/>
|
||||
</Component>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
|
||||
<Feature
|
||||
Id='Binaries'
|
||||
Title='Application'
|
||||
Description='Installs all binaries and the license.'
|
||||
Level='1'
|
||||
ConfigurableDirectory='APPLICATIONFOLDER'
|
||||
AllowAdvertise='no'
|
||||
Display='expand'
|
||||
Absent='disallow'>
|
||||
|
||||
<!--
|
||||
Uncomment the following `ComponentRef` tag to add the license
|
||||
sidecar file to the installer.
|
||||
-->
|
||||
<!--<ComponentRef Id='License'/>-->
|
||||
|
||||
<ComponentRef Id='binary0'/>
|
||||
|
||||
<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'/>
|
||||
|
||||
|
||||
<!--
|
||||
Uncomment the following `Icon` and `Property` tags to change the product icon.
|
||||
|
||||
The product icon is the graphic that appears in the Add/Remove
|
||||
Programs control panel for the application.
|
||||
-->
|
||||
<!--<Icon Id='ProductICO' SourceFile='wix\Product.ico'/>-->
|
||||
<!--<Property Id='ARPPRODUCTICON' Value='ProductICO' />-->
|
||||
|
||||
<Property Id='ARPHELPLINK' Value='https://github.com/loki5512344/Terrafier'/>
|
||||
|
||||
<UI>
|
||||
<UIRef Id='WixUI_FeatureTree'/>
|
||||
|
||||
<!--
|
||||
Enabling the EULA dialog in the installer is a three step process:
|
||||
|
||||
1. Comment out or remove the two `Publish` tags that follow the
|
||||
`WixVariable` tag.
|
||||
2. Uncomment the `<WixVariable Id='WixUILicenseRtf' Value='Path\to\Eula.rft'>` tag further down
|
||||
3. Replace the `Value` attribute of the `WixVariable` tag with
|
||||
the path to a RTF file that will be used as the EULA and
|
||||
displayed in the license agreement dialog.
|
||||
-->
|
||||
<Publish Dialog='WelcomeDlg' Control='Next' Event='NewDialog' Value='CustomizeDlg' Order='99'>1</Publish>
|
||||
<Publish Dialog='CustomizeDlg' Control='Back' Event='NewDialog' Value='WelcomeDlg' Order='99'>1</Publish>
|
||||
|
||||
</UI>
|
||||
|
||||
|
||||
<!--
|
||||
Enabling the EULA dialog in the installer requires uncommenting
|
||||
the following `WixUILicenseRTF` tag and changing the `Value`
|
||||
attribute.
|
||||
-->
|
||||
<!-- <WixVariable Id='WixUILicenseRtf' Value='Relative\Path\to\Eula.rtf'/> -->
|
||||
|
||||
|
||||
<!--
|
||||
Uncomment the next `WixVariable` tag to customize the installer's
|
||||
Graphical User Interface (GUI) and add a custom banner image across
|
||||
the top of each screen. See the WiX Toolset documentation for details
|
||||
about customization.
|
||||
|
||||
The banner BMP dimensions are 493 x 58 pixels.
|
||||
-->
|
||||
<!--<WixVariable Id='WixUIBannerBmp' Value='wix\Banner.bmp'/>-->
|
||||
|
||||
|
||||
<!--
|
||||
Uncomment the next `WixVariable` tag to customize the installer's
|
||||
Graphical User Interface (GUI) and add a custom image to the first
|
||||
dialog, or screen. See the WiX Toolset documentation for details about
|
||||
customization.
|
||||
|
||||
The dialog BMP dimensions are 493 x 312 pixels.
|
||||
-->
|
||||
<!--<WixVariable Id='WixUIDialogBmp' Value='wix\Dialog.bmp'/>-->
|
||||
|
||||
</Product>
|
||||
|
||||
</Wix>
|
||||
Loading…
Add table
Add a link
Reference in a new issue