Skip to content

Commit

Permalink
Add structured output
Browse files Browse the repository at this point in the history
  • Loading branch information
jkelleyrtp committed Nov 9, 2024
1 parent 2b1adac commit d6cee7c
Show file tree
Hide file tree
Showing 29 changed files with 394 additions and 259 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,7 @@ node_modules/
/packages/playwright-report/
/packages/playwright/.cache/


# ignore the output of tmps
tmp/
bundle/
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ brotli = "6.0.0"
ignore = "0.4.22"
env_logger = { workspace = true }

tracing-subscriber = { version = "0.3.18", features = ["std", "env-filter"] }
tracing-subscriber = { version = "0.3.18", features = ["std", "env-filter", "json"] }
console-subscriber = { version = "0.3.0", optional = true }
tracing = { workspace = true }
wasm-opt = { version = "0.116.1", optional = true }
Expand Down
1 change: 0 additions & 1 deletion packages/cli/src/builder/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ impl BuildRequest {
.arg("--message-format")
.arg("json-diagnostic-rendered-ansi")
.args(self.build_arguments());
// .env("RUSTFLAGS", self.rust_flags());

if let Some(target_dir) = self.custom_target_dir.as_ref() {
cmd.env("CARGO_TARGET_DIR", target_dir);
Expand Down
11 changes: 0 additions & 11 deletions packages/cli/src/builder/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,6 @@ impl BuildRequest {
stage: BuildStage::RunningBindgen {},
});
}
pub(crate) fn status_wasm_opt_start(&self) {
_ = self.progress.unbounded_send(BuildUpdate::Progress {
stage: BuildStage::RunningBindgen {},
});
}

pub(crate) fn status_bundle_finished(&self) {
_ = self.progress.unbounded_send(BuildUpdate::Progress {
stage: BuildStage::Bundling {},
});
}

pub(crate) fn status_start_bundle(&self) {
_ = self.progress.unbounded_send(BuildUpdate::Progress {
Expand Down
24 changes: 12 additions & 12 deletions packages/cli/src/builder/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,21 @@ impl BuildRequest {
/// should be installing the x86 versions.
pub(crate) async fn verify_ios_tooling(&self, _rustup: RustupShow) -> Result<()> {
// open the simulator
_ = tokio::process::Command::new("open")
.arg("/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app")
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.status()
.await;
// _ = tokio::process::Command::new("open")
// .arg("/Applications/Xcode.app/Contents/Developer/Applications/Simulator.app")
// .stderr(Stdio::piped())
// .stdout(Stdio::piped())
// .status()
// .await;

// Now xcrun to open the device
// todo: we should try and query the device list and/or parse it rather than hardcode this simulator
_ = tokio::process::Command::new("xcrun")
.args(["simctl", "boot", "83AE3067-987F-4F85-AE3D-7079EF48C967"])
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.status()
.await;
// _ = tokio::process::Command::new("xcrun")
// .args(["simctl", "boot", "83AE3067-987F-4F85-AE3D-7079EF48C967"])
// .stderr(Stdio::piped())
// .stdout(Stdio::piped())
// .status()
// .await;

// if !rustup
// .installed_toolchains
Expand Down
1 change: 1 addition & 0 deletions packages/cli/src/bundle_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ impl From<PackageType> for tauri_bundler::PackageType {
PackageType::AppImage => Self::AppImage,
PackageType::Dmg => Self::Dmg,
PackageType::Updater => Self::Updater,
PackageType::Nsis => Self::Nsis,
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/cli/autoformat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ pub(crate) struct Autoformat {
}

impl Autoformat {
pub(crate) fn autoformat(self) -> Result<()> {
pub(crate) fn autoformat(self) -> Result<StructuredOutput> {
let Autoformat {
check,
raw,
Expand Down Expand Up @@ -88,7 +88,7 @@ impl Autoformat {
}
}

Ok(())
Ok(StructuredOutput::GenericSuccess)
}
}

Expand Down
7 changes: 4 additions & 3 deletions packages/cli/src/cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,10 @@ pub(crate) struct BuildArgs {
}

impl BuildArgs {
pub async fn build_it(mut self) -> Result<()> {
self.build().await?;
Ok(())
pub async fn run_cmd(mut self) -> Result<StructuredOutput> {
let _bundle = self.build().await?;

Ok(StructuredOutput::GenericSuccess)
}

pub(crate) async fn build(&mut self) -> Result<AppBundle> {
Expand Down
154 changes: 108 additions & 46 deletions packages/cli/src/cli/bundle.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use crate::Builder;
use crate::DioxusCrate;
use crate::{build::BuildArgs, PackageType};
use crate::{build::BuildArgs, AppBundle, Builder, DioxusCrate, Platform};
use anyhow::Context;
use itertools::Itertools;
use std::{collections::HashMap, str::FromStr};
use std::collections::HashMap;
use tauri_bundler::{BundleBinary, BundleSettings, PackageSettings, SettingsBuilder};

use super::*;
Expand All @@ -13,16 +10,36 @@ use super::*;
#[clap(name = "bundle")]
pub struct Bundle {
/// The package types to bundle
///
/// Any of:
/// - macos: The macOS application bundle (.app).
/// - ios: The iOS app bundle.
/// - msi: The Windows bundle (.msi).
/// - nsis: The NSIS bundle (.exe).
/// - deb: The Linux Debian package bundle (.deb).
/// - rpm: The Linux RPM bundle (.rpm).
/// - appimage: The Linux AppImage bundle (.AppImage).
/// - dmg: The macOS DMG bundle (.dmg).
/// - updater: The Updater bundle.
#[clap(long)]
pub packages: Option<Vec<PackageType>>,
pub package_types: Option<Vec<crate::PackageType>>,

/// The directory in which the final bundle will be placed.
///
/// Relative paths will be placed relative to the current working directory.
///
/// We will flatten the artifacts into this directory - there will be no differentiation between
/// artifacts produced by different platforms.
#[clap(long)]
pub outdir: Option<PathBuf>,

/// The arguments for the dioxus build
#[clap(flatten)]
pub(crate) build_arguments: BuildArgs,
}

impl Bundle {
pub(crate) async fn bundle(mut self) -> Result<()> {
pub(crate) async fn bundle(mut self) -> Result<StructuredOutput> {
tracing::info!("Bundling project...");

let krate = DioxusCrate::new(&self.build_arguments.target_args)
Expand All @@ -38,15 +55,89 @@ impl Bundle {

tracing::info!("Copying app to output directory...");

// If we're building for iOS, we need to bundle the iOS bundle
if self.build_arguments.platform() == Platform::Ios && self.package_types.is_none() {
self.package_types = Some(vec![crate::PackageType::IosBundle]);
}

let mut cmd_result = StructuredOutput::GenericSuccess;

match self.build_arguments.platform() {
// By default, mac/win/linux work with tauri bundle
Platform::MacOS | Platform::Linux | Platform::Windows => {
let bundles = self.bundle_desktop(krate, bundle)?;

tracing::info!("Bundled app successfully!");
tracing::info!("App produced {} outputs:", bundles.len());
tracing::debug!("Bundling produced bundles: {:#?}", bundles);

// Copy the bundles to the output directory and log their locations
let mut bundle_paths = vec![];
for bundle in bundles {
for src in bundle.bundle_paths {
let src = if let Some(outdir) = &self.outdir {
let dest = outdir.join(src.file_name().unwrap());
crate::fastfs::copy_asset(&src, &dest)?;
dest
} else {
src.clone()
};

tracing::info!(
"{} - [{}]",
bundle.package_type.short_name(),
src.display()
);

bundle_paths.push(src);
}
}

cmd_result = StructuredOutput::BundleOutput {
platform: self.build_arguments.platform(),
bundles: bundle_paths,
};
}

Platform::Web => {
tracing::info!("App available at: {}", bundle.app_dir().display());
}

Platform::Ios => {
tracing::warn!("Signed iOS bundles are not yet supported");
tracing::info!("The bundle is available at: {}", bundle.app_dir().display());
}

Platform::Server => {
tracing::info!("Server available at: {}", bundle.app_dir().display())
}
Platform::Liveview => tracing::info!(
"Liveview server available at: {}",
bundle.app_dir().display()
),

Platform::Android => {
return Err(Error::UnsupportedFeature(
"Android bundles are not yet supported".into(),
));
}
};

Ok(cmd_result)
}

fn bundle_desktop(
&self,
krate: DioxusCrate,
bundle: AppBundle,
) -> Result<Vec<tauri_bundler::Bundle>, Error> {
_ = std::fs::remove_dir_all(krate.bundle_dir(self.build_arguments.platform()));

let package = krate.package();
let mut name: PathBuf = krate.executable_name().into();
if cfg!(windows) {
name.set_extension("exe");
}

// Make sure we copy the exe to the bundle dir so the bundler can find it
std::fs::create_dir_all(krate.bundle_dir(self.build_arguments.platform()))?;
std::fs::copy(
&bundle.app.exe,
Expand Down Expand Up @@ -83,7 +174,8 @@ impl Bundle {

for entry in std::fs::read_dir(bundle.asset_dir())?.flatten() {
let old = entry.path().canonicalize()?;
let new = PathBuf::from("assets").join(old.file_name().unwrap());
let new = PathBuf::from("/assets").join(old.file_name().unwrap());
tracing::debug!("Bundled asset: {old:?} -> {new:?}");

bundle_settings
.resources_map
Expand All @@ -92,8 +184,6 @@ impl Bundle {
.insert(old.display().to_string(), new.display().to_string());
}

// Drain any resources set in the config into the resources map. Tauri bundle doesn't let
// you set both resources and resources_map https://github.com/DioxusLabs/dioxus/issues/2941
for resource_path in bundle_settings.resources.take().into_iter().flatten() {
bundle_settings
.resources_map
Expand All @@ -116,19 +206,20 @@ impl Bundle {
.binaries(binaries)
.bundle_settings(bundle_settings);

if let Some(packages) = &self.packages {
if let Some(packages) = &self.package_types {
settings = settings.package_types(packages.iter().map(|p| (*p).into()).collect());
}

if let Some(target) = self.build_arguments.target_args.target.as_ref() {
settings = settings.target(target.to_string());
}

let settings = settings.build()?;
if self.build_arguments.platform() == Platform::Ios {
settings = settings.target("aarch64-apple-ios".to_string());
}

let settings = settings.build()?;
tracing::debug!("Bundling project with settings: {:#?}", settings);

// on macos we need to set CI=true (https://github.com/tauri-apps/tauri/issues/2567)
if cfg!(target_os = "macos") {
std::env::set_var("CI", "true");
}
Expand All @@ -140,35 +231,6 @@ impl Bundle {
}
})?;

tracing::info!("Bundled app successfully!");
tracing::info!("App produced {} outputs:", bundles.len());

for bundle in bundles {
tracing::info!(
"{} - [{}]",
bundle.package_type.short_name(),
bundle.bundle_paths.iter().map(|p| p.display()).join(", ")
);
}

Ok(())
}
}

impl FromStr for PackageType {
type Err = String;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"macos" => Ok(PackageType::MacOsBundle),
"ios" => Ok(PackageType::IosBundle),
"msi" => Ok(PackageType::WindowsMsi),
"deb" => Ok(PackageType::Deb),
"rpm" => Ok(PackageType::Rpm),
"appimage" => Ok(PackageType::AppImage),
"dmg" => Ok(PackageType::Dmg),
"updater" => Ok(PackageType::Updater),
_ => Err(format!("{} is not a valid package type", s)),
}
Ok(bundles)
}
}
4 changes: 2 additions & 2 deletions packages/cli/src/cli/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ pub(crate) struct Check {

impl Check {
// Todo: check the entire crate
pub(crate) async fn check(self) -> Result<()> {
pub(crate) async fn check(self) -> Result<StructuredOutput> {
match self.file {
// Default to checking the project
None => {
Expand All @@ -38,7 +38,7 @@ impl Check {
}
}

Ok(())
Ok(StructuredOutput::GenericSuccess)
}
}

Expand Down
Loading

0 comments on commit d6cee7c

Please sign in to comment.