@@ -8,13 +8,11 @@ use anyhow::{anyhow, bail, ensure, Result};
8
8
use async_process:: { Command , Stdio } ;
9
9
use async_std:: fs;
10
10
use async_std:: task:: { spawn, spawn_blocking, JoinHandle } ;
11
+ use cargo_metadata:: { MetadataCommand , Metadata , Package } ;
11
12
use console:: Emoji ;
12
13
use futures:: stream:: { FuturesUnordered , StreamExt } ;
13
14
use indicatif:: ProgressBar ;
14
15
use nipper:: Document ;
15
- use serde:: { Serialize , Deserialize } ;
16
-
17
- use crate :: common:: get_cwd;
18
16
19
17
const TRUNK_ID : & str = "__trunk-id" ;
20
18
const HREF_ATTR : & str = "href" ;
@@ -27,7 +25,7 @@ const HREF_ATTR: &str = "href";
27
25
/// build routines can be cleanly abstracted away form any specific CLI endpoints.
28
26
pub struct BuildSystem {
29
27
/// The `Cargo.toml` manifest of the app being built.
30
- manifest : CargoManifest ,
28
+ manifest : CargoMetadata ,
31
29
/// The path to the source HTML document from which the output `index.html` will be built.
32
30
target_html_path : Arc < PathBuf > ,
33
31
/// The parent directory of `target_html_path`.
@@ -56,16 +54,13 @@ impl BuildSystem {
56
54
///
57
55
/// Reducing the number of assumptions here should help us to stay flexible when adding new
58
56
/// commands, rafctoring and the like.
59
- pub async fn new ( manifest : CargoManifest , target_html_path : PathBuf , release : bool , dist : PathBuf , public_url : String ) -> Result < Self > {
57
+ pub async fn new ( manifest : CargoMetadata , target_html_path : PathBuf , release : bool , dist : PathBuf , public_url : String ) -> Result < Self > {
60
58
let mode_segment = if release { "release" } else { "debug" } ;
61
- let cwd = std:: env:: current_dir ( ) . map_err ( |_| anyhow ! ( "failed to determine current working directory" ) ) ?;
62
- let app_target_wasm = cwd
63
- . join ( "target" )
59
+ let app_target_wasm = manifest. metadata . target_directory
64
60
. join ( "wasm32-unknown-unknown" )
65
61
. join ( mode_segment)
66
62
. join ( format ! ( "{}.wasm" , & manifest. package. name) ) ;
67
- let bindgen_out = cwd
68
- . join ( "target" )
63
+ let bindgen_out = manifest. metadata . target_directory
69
64
. join ( "wasm-bindgen" )
70
65
. join ( mode_segment) ;
71
66
let target_html_path = target_html_path. canonicalize ( )
@@ -452,34 +447,43 @@ struct WasmBindgenOutput {
452
447
//////////////////////////////////////////////////////////////////////////////
453
448
//////////////////////////////////////////////////////////////////////////////
454
449
455
- /// A model of the Cargo.toml `package` section.
456
- #[ derive( Serialize , Deserialize ) ]
457
- pub struct CargoPackage {
458
- /// The name of the crate.
450
+ /// A wrapper around the cargo project's metadata.
451
+ pub struct CargoMetadata {
452
+ /// The metadata parsed from the cargo project.
453
+ pub metadata : Metadata ,
454
+ /// The metadata package info on this package.
455
+ pub package : Package ,
456
+ /// The name of the cargo project's build output file.
459
457
pub name : String ,
460
- /// The version of the crate.
461
- pub version : String ,
462
- }
463
-
464
- /// A model of the parts of a `Cargo.toml` file which we actually care about.
465
- #[ derive( Serialize , Deserialize ) ]
466
- pub struct CargoManifest {
467
- /// The package section of `Cargo.toml`.
468
- pub package : CargoPackage ,
469
458
}
470
459
471
- impl CargoManifest {
472
- /// Read the `Cargo.toml` manifest in the CWD.
473
- pub async fn read_cwd_manifest ( ) -> Result < Self > {
474
- let manifest_path = get_cwd ( ) . await ?. join ( "Cargo.toml" ) ;
475
- let manifest_raw = fs:: read_to_string ( & manifest_path) . await
476
- . map_err ( |err| anyhow ! ( "error reading Cargo.toml file: {}" , err) ) ?;
477
- let mut manifest: Self = toml:: from_str ( & manifest_raw)
478
- . map_err ( |err| anyhow ! ( "error parsing Cargo.toml: {}" , err) ) ?;
479
-
480
- // Update the package name to match what its output name will be.
481
- manifest. package . name = manifest. package . name . replace ( "-" , "_" ) ;
460
+ impl CargoMetadata {
461
+ /// Get the project's cargo metadata of the CWD, or of the project specified by the given manifest path.
462
+ pub async fn new ( manifest : & Option < PathBuf > ) -> Result < Self > {
463
+ // Fetch the cargo project's metadata.
464
+ let mut cmd = MetadataCommand :: new ( ) ;
465
+ if let Some ( manifest) = manifest. as_ref ( ) {
466
+ cmd. manifest_path ( manifest) ;
467
+ }
468
+ let metadata = spawn_blocking ( move || {
469
+ cmd. exec ( )
470
+ } ) . await ?;
471
+
472
+ // Get a handle to this project's package info.
473
+ let resolve = match metadata. resolve . as_ref ( ) {
474
+ Some ( resolve) => resolve,
475
+ None => bail ! ( "missing package info from cargo project metadata" ) ,
476
+ } ;
477
+ let pkgid = match resolve. root . as_ref ( ) {
478
+ Some ( pkgid) => pkgid,
479
+ None => bail ! ( "package id missing while processing cargo metadata" ) ,
480
+ } ;
481
+ let package = match metadata. packages . iter ( ) . find ( |pkg| & pkg. id == pkgid) {
482
+ Some ( package) => package. clone ( ) ,
483
+ None => bail ! ( "error finding package info in cargo metadata" ) ,
484
+ } ;
485
+ let name = package. name . replace ( "-" , "_" ) ;
482
486
483
- Ok ( manifest )
487
+ Ok ( Self { metadata , package , name } )
484
488
}
485
489
}
0 commit comments