Merge branch 'main' into jk/new-readmes

This commit is contained in:
Jonathan Kelley 2024-11-17 17:49:19 -05:00
commit 219e936b05
No known key found for this signature in database
GPG key ID: 1FBB50F7EB0A08BE
10 changed files with 83 additions and 34 deletions

View file

@ -24,8 +24,8 @@ impl AssetManifest {
}
/// Fill this manifest with a file object/rlib files, typically extracted from the linker intercepted
pub(crate) fn add_from_object_path(&mut self, path: PathBuf) -> anyhow::Result<()> {
let data = std::fs::read(path.clone())?;
pub(crate) fn add_from_object_path(&mut self, path: &Path) -> anyhow::Result<()> {
let data = std::fs::read(path)?;
match path.extension().and_then(|ext| ext.to_str()) {
// Parse an rlib as a collection of objects

View file

@ -6,7 +6,11 @@ use crate::{link::LinkAction, BuildArgs};
use crate::{AppBundle, Platform};
use anyhow::Context;
use serde::Deserialize;
use std::{path::PathBuf, process::Stdio, time::Instant};
use std::{
path::{Path, PathBuf},
process::Stdio,
time::Instant,
};
use tokio::{io::AsyncBufReadExt, process::Command};
#[derive(Clone, Debug)]
@ -60,7 +64,7 @@ impl BuildRequest {
let start = Instant::now();
self.prepare_build_dir()?;
let exe = self.build_cargo().await?;
let assets = self.collect_assets().await?;
let assets = self.collect_assets(&exe).await?;
Ok(BuildArtifacts {
exe,
@ -102,9 +106,6 @@ impl BuildRequest {
.args(self.build_arguments())
.envs(self.env_vars()?);
// todo(jon): save the temps into a file that we use for asset extraction instead of the weird double compile.
// .args(["--", "-Csave-temps=y"]);
if let Some(target_dir) = self.custom_target_dir.as_ref() {
cmd.env("CARGO_TARGET_DIR", target_dir);
}
@ -203,19 +204,30 @@ impl BuildRequest {
Ok(out_location)
}
/// Run the linker intercept and then fill in our AssetManifest from the incremental artifacts
/// Traverse the target directory and collect all assets from the incremental cache
///
/// This will execute `dx` with an env var set to force `dx` to operate as a linker, and then
/// traverse the .o and .rlib files rustc passes that new `dx` instance, collecting the link
/// tables marked by manganis and parsing them as a ResourceAsset.
pub(crate) async fn collect_assets(&self) -> Result<AssetManifest> {
/// This uses "known paths" that have stayed relatively stable during cargo's lifetime.
/// One day this system might break and we might need to go back to using the linker approach.
pub(crate) async fn collect_assets(&self, exe: &Path) -> Result<AssetManifest> {
tracing::debug!("Collecting assets ...");
if self.build.skip_assets {
return Ok(AssetManifest::default());
}
self.deep_linker_asset_extract().await
// Experimental feature for testing - if the env var is set, we'll use the deeplinker
if std::env::var("DEEPLINK").is_ok() {
tracing::debug!("Using deeplinker instead of incremental cache");
return self.deep_linker_asset_extract().await;
}
// walk every file in the incremental cache dir, reading and inserting items into the manifest.
let mut manifest = AssetManifest::default();
// And then add from the exe directly, just in case it's LTO compiled and has no incremental cache
_ = manifest.add_from_object_path(exe);
Ok(manifest)
}
/// Create a list of arguments for cargo builds
@ -408,6 +420,7 @@ impl BuildRequest {
///
/// There's a chance that's not actually true, so this function is kept around in case we do
/// need to revert to "deep extraction".
#[allow(unused)]
async fn deep_linker_asset_extract(&self) -> Result<AssetManifest> {
// Create a temp file to put the output of the args
// We need to do this since rustc won't actually print the link args to stdout, so we need to
@ -619,9 +632,7 @@ impl BuildRequest {
/// a final build output somewhere. Some platforms have basically no build command, and can simply
/// be ran by executing the exe directly.
pub(crate) fn root_dir(&self) -> PathBuf {
let platform_dir = self
.krate
.build_dir(self.build.platform(), self.build.release);
let platform_dir = self.platform_dir();
match self.build.platform() {
Platform::Web => platform_dir.join("public"),
@ -639,6 +650,11 @@ impl BuildRequest {
}
}
pub(crate) fn platform_dir(&self) -> PathBuf {
self.krate
.build_dir(self.build.platform(), self.build.release)
}
pub fn asset_dir(&self) -> PathBuf {
match self.build.platform() {
Platform::MacOS => self

View file

@ -16,8 +16,8 @@ pub struct Create {
name: Option<String>,
/// Template path
#[clap(default_value = DEFAULT_TEMPLATE, short, long)]
template: String,
#[clap(short, long)]
template: Option<String>,
/// Branch to select when using `template` from a git repository.
/// Mutually exclusive with: `--revision`, `--tag`.
@ -55,6 +55,9 @@ impl Create {
self.name = Some(create::name_from_path(&self.path)?);
}
// If no template is specified, use the default one and set the branch to the latest release.
resolve_template_and_branch(&mut self.template, &mut self.branch);
let args = GenerateArgs {
define: self.option,
destination: Some(self.path),
@ -67,7 +70,7 @@ impl Create {
name: self.name,
silent: self.yes,
template_path: TemplatePath {
auto_path: Some(self.template),
auto_path: self.template,
branch: self.branch,
revision: self.revision,
subfolder: self.subtemplate,
@ -83,6 +86,23 @@ impl Create {
}
}
/// If no template is specified, use the default one and set the branch to the latest release.
///
/// Allows us to version templates under the v0.5/v0.6 scheme on the templates repo.
pub(crate) fn resolve_template_and_branch(
template: &mut Option<String>,
branch: &mut Option<String>,
) {
if template.is_none() {
use crate::dx_build_info::{PKG_VERSION_MAJOR, PKG_VERSION_MINOR};
*template = Some(DEFAULT_TEMPLATE.to_string());
if branch.is_none() {
*branch = Some(format!("v{PKG_VERSION_MAJOR}.{PKG_VERSION_MINOR}"));
}
};
}
/// Prevent hidden cursor if Ctrl+C is pressed when interacting
/// with cargo-generate's prompts.
///
@ -230,14 +250,7 @@ pub(crate) mod tests {
pub(crate) fn subcommand(name: &str) -> Command {
let mut command = BINARY.command();
command
.arg(name)
.arg("--yes") // Skip any questions by choosing default answers.
.arg("--subtemplate")
// Probably should use some template that doesn't require specifying
// either `--subtemplate` or `--option`.
// Maybe a simple template in tests/ dir?
.arg("Fullstack");
command.arg(name).arg("--yes"); // Skip any questions by choosing default answers.
command
}

View file

@ -1,5 +1,4 @@
use super::*;
use crate::cli::create::DEFAULT_TEMPLATE;
use cargo_generate::{GenerateArgs, TemplatePath};
#[derive(Clone, Debug, Default, Deserialize, Parser)]
@ -14,8 +13,8 @@ pub struct Init {
name: Option<String>,
/// Template path
#[clap(default_value = DEFAULT_TEMPLATE, short, long)]
template: String,
#[clap(short, long)]
template: Option<String>,
/// Branch to select when using `template` from a git repository.
/// Mutually exclusive with: `--revision`, `--tag`.
@ -53,6 +52,9 @@ impl Init {
self.name = Some(create::name_from_path(&self.path)?);
}
// If no template is specified, use the default one and set the branch to the latest release.
create::resolve_template_and_branch(&mut self.template, &mut self.branch);
let args = GenerateArgs {
define: self.option,
destination: Some(self.path),
@ -60,7 +62,7 @@ impl Init {
name: self.name,
silent: self.yes,
template_path: TemplatePath {
auto_path: Some(self.template),
auto_path: self.template,
branch: self.branch,
revision: self.revision,
subfolder: self.subtemplate,

View file

@ -92,7 +92,7 @@ impl LinkAction {
if item.ends_with(".o") || item.ends_with(".rlib") {
let path_to_item = PathBuf::from(item);
if let Ok(path) = path_to_item.canonicalize() {
_ = manifest.add_from_object_path(path);
_ = manifest.add_from_object_path(&path);
}
}
}

View file

@ -159,8 +159,14 @@ impl LaunchBuilder {
{
use dioxus_fullstack::prelude::server_fn::client::{get_server_url, set_server_url};
if get_server_url().is_empty() {
let ip = if cfg!(target_os = "android") {
"10.0.2.2"
} else {
"127.0.0.1"
};
let serverurl = format!(
"http://127.0.0.1:{}",
"http://{ip}:{}",
std::env::var("PORT").unwrap_or_else(|_| "8080".to_string())
)
.leak();

View file

@ -104,6 +104,8 @@ impl ToTokens for AssetParser {
// "/blahcss123.css"
bundled: #bundled,
metadata: __volatile_reader as fn() -> u8,
}
}
) #option_source

View file

@ -17,5 +17,9 @@ pub fn generate_link_section(asset: &impl Serialize) -> TokenStream2 {
#[link_section = #section_name]
#[used]
static ASSET: [u8; #len] = * #asset_bytes;
fn __volatile_reader() -> u8 {
unsafe { std::ptr::read_volatile(ASSET.as_ptr()) }
}
}
}

View file

@ -14,6 +14,9 @@ pub struct Asset {
///
/// `blah-123.css``
pub bundled: &'static str,
/// The metadata for this asset plumbed by the compiler
pub metadata: fn() -> u8,
}
impl Asset {
@ -47,6 +50,9 @@ impl Asset {
/// Attempts to resolve it against an `assets` folder in the current directory.
/// If that doesn't exist, it will resolve against the cargo manifest dir
pub fn resolve(&self) -> PathBuf {
// Force a volatile read of the metadata to ensure the symbol makes it into the binary
(self.metadata)();
// If the asset is relative, we resolve the asset at the current directory
if !dioxus_core_types::is_bundled_app() {
return PathBuf::from(self.local);

View file

@ -18,7 +18,7 @@ impl WebEventExt for dioxus_html::FormData {
#[inline(always)]
fn try_as_web_event(&self) -> Option<Self::WebEvent> {
self.downcast::<WebFormData>().map(|e| e.raw.clone())
self.downcast::<Event>().cloned()
}
}