|
1 | 1 | use std::{io::Seek, path::PathBuf}; |
2 | 2 |
|
3 | | -use anyhow::{ensure, Context}; |
| 3 | +use anyhow::{Context, ensure}; |
4 | 4 | use clap::{Args, Parser, Subcommand, ValueEnum}; |
5 | 5 | use futures_util::TryStreamExt; |
6 | 6 | use tokio::io::AsyncWriteExt; |
7 | 7 | use tracing::level_filters::LevelFilter; |
8 | 8 | use wasm_pkg_client::{ |
9 | | - caching::{CachingClient, FileCache}, |
10 | 9 | Client, PublishOpts, |
| 10 | + caching::{CachingClient, FileCache}, |
11 | 11 | }; |
12 | 12 | use wasm_pkg_common::{ |
13 | 13 | self, |
@@ -358,28 +358,34 @@ impl GetArgs { |
358 | 358 | tracing::debug!(?release, "Fetched release details"); |
359 | 359 |
|
360 | 360 | let output_trailing_slash = self.output.as_os_str().to_string_lossy().ends_with('/'); |
361 | | - let parent_dir = if output_trailing_slash { |
362 | | - let parent_dir = self.output.as_path(); |
363 | | - if !tokio::fs::try_exists(parent_dir).await? { |
364 | | - tokio::fs::create_dir_all(parent_dir).await |
365 | | - .context("Failed to create output dir")? |
| 361 | + let parent_dir_path = if output_trailing_slash { |
| 362 | + // TODO(fix): TOCTOU on directory, requires platform open dir flags |
| 363 | + let parent_dir_path = self.output.as_path(); |
| 364 | + if !tokio::fs::try_exists(parent_dir_path).await? { |
| 365 | + tokio::fs::create_dir_all(parent_dir_path) |
| 366 | + .await |
| 367 | + .with_context(|| { |
| 368 | + format!( |
| 369 | + "failed to create output dir @ [{}]", |
| 370 | + parent_dir_path.display() |
| 371 | + ) |
| 372 | + })?; |
366 | 373 | } |
367 | | - parent_dir |
| 374 | + parent_dir_path |
368 | 375 | } else { |
369 | 376 | self.output |
370 | 377 | .parent() |
371 | | - .context("Failed to resolve output parent dir")? |
| 378 | + .context("Failed to resolve non-trailing-slash output parent dir")? |
372 | 379 | }; |
373 | 380 |
|
374 | | - if !parent_dir.exists() { |
375 | | - anyhow::bail!( |
376 | | - "output directory {:?} does not exist; create it first or choose a different path", |
377 | | - parent_dir |
378 | | - ); |
379 | | - } |
| 381 | + anyhow::ensure!( |
| 382 | + parent_dir_path.exists(), |
| 383 | + "output directory {:?} does not exist; create it first or choose a different path", |
| 384 | + parent_dir_path |
| 385 | + ); |
380 | 386 |
|
381 | 387 | let (tmp_file, tmp_path) = |
382 | | - tempfile::NamedTempFile::with_prefix_in(".wkg-get", parent_dir)?.into_parts(); |
| 388 | + tempfile::NamedTempFile::with_prefix_in(".wkg-get", parent_dir_path)?.into_parts(); |
383 | 389 | tracing::debug!(?tmp_path, "Created temporary file"); |
384 | 390 |
|
385 | 391 | let mut content_stream = client.get_content(&package, &release).await?; |
|
0 commit comments