1
1
use std:: borrow:: Cow ;
2
2
use std:: fmt:: Write as _;
3
- use std:: io;
4
3
use std:: io:: Write as _;
5
4
use std:: path:: { Path , PathBuf } ;
5
+ use std:: { fmt, io} ;
6
6
7
- use anyhow:: { bail , Context , Result } ;
7
+ use anyhow:: { Context , Result } ;
8
8
use owo_colors:: OwoColorize ;
9
+ use thiserror:: Error ;
9
10
use tracing:: { debug, instrument, trace} ;
10
11
12
+ use crate :: commands:: pip:: operations;
13
+ use crate :: commands:: project:: find_requires_python;
14
+ use crate :: commands:: reporters:: PythonDownloadReporter ;
15
+ use crate :: commands:: ExitStatus ;
16
+ use crate :: printer:: Printer ;
17
+ use crate :: settings:: { ResolverSettings , ResolverSettingsRef } ;
11
18
use uv_auth:: store_credentials;
12
19
use uv_build_backend:: PyProjectToml ;
13
20
use uv_cache:: { Cache , CacheBucket } ;
@@ -34,12 +41,42 @@ use uv_settings::PythonInstallMirrors;
34
41
use uv_types:: { BuildContext , BuildIsolation , HashStrategy } ;
35
42
use uv_workspace:: { DiscoveryOptions , Workspace , WorkspaceError } ;
36
43
37
- use crate :: commands:: pip:: operations;
38
- use crate :: commands:: project:: find_requires_python;
39
- use crate :: commands:: reporters:: PythonDownloadReporter ;
40
- use crate :: commands:: ExitStatus ;
41
- use crate :: printer:: Printer ;
42
- use crate :: settings:: { ResolverSettings , ResolverSettingsRef } ;
44
+ #[ derive( Debug , Error ) ]
45
+ enum Error {
46
+ #[ error( transparent) ]
47
+ Io ( #[ from] io:: Error ) ,
48
+ #[ error( transparent) ]
49
+ FindOrDownloadPython ( #[ from] uv_python:: Error ) ,
50
+ #[ error( transparent) ]
51
+ HashStrategy ( #[ from] uv_types:: HashStrategyError ) ,
52
+ #[ error( transparent) ]
53
+ FlatIndex ( #[ from] uv_client:: FlatIndexError ) ,
54
+ #[ error( transparent) ]
55
+ BuildPlan ( anyhow:: Error ) ,
56
+ #[ error( transparent) ]
57
+ Extract ( #[ from] uv_extract:: Error ) ,
58
+ #[ error( transparent) ]
59
+ Operations ( #[ from] operations:: Error ) ,
60
+ #[ error( transparent) ]
61
+ Join ( #[ from] tokio:: task:: JoinError ) ,
62
+ #[ error( transparent) ]
63
+ BuildBackend ( #[ from] uv_build_backend:: Error ) ,
64
+ #[ error( transparent) ]
65
+ BuildDispatch ( anyhow:: Error ) ,
66
+ #[ error( transparent) ]
67
+ BuildFrontend ( #[ from] uv_build_frontend:: Error ) ,
68
+ #[ error( "Failed to write message" ) ]
69
+ Fmt ( #[ from] fmt:: Error ) ,
70
+ #[ error( "Can't use `--force-pep517` with `--list`" ) ]
71
+ ListForcePep517 ,
72
+ #[ error( "Can only use `--list` with the uv backend" ) ]
73
+ ListNonUv ,
74
+ #[ error(
75
+ "`{0}` is not a valid build source. Expected to receive a source directory, or a source \
76
+ distribution ending in one of: {1}."
77
+ ) ]
78
+ InvalidSourceDistExt ( String , uv_distribution_filename:: ExtensionError ) ,
79
+ }
43
80
44
81
/// Build source distributions and wheels.
45
82
#[ allow( clippy:: fn_params_excessive_bools) ]
@@ -334,7 +371,7 @@ async fn build_impl(
334
371
335
372
let report = miette:: Report :: new ( Diagnostic {
336
373
source : source. to_string ( ) ,
337
- cause : err,
374
+ cause : err. into ( ) ,
338
375
} ) ;
339
376
anstream:: eprint!( "{report:?}" ) ;
340
377
@@ -386,7 +423,7 @@ async fn build_package(
386
423
link_mode : LinkMode ,
387
424
config_setting : & ConfigSettings ,
388
425
preview : PreviewMode ,
389
- ) -> Result < Vec < BuildMessage > > {
426
+ ) -> Result < Vec < BuildMessage > , Error > {
390
427
let output_dir = if let Some ( output_dir) = output_dir {
391
428
Cow :: Owned ( std:: path:: absolute ( output_dir) ?)
392
429
} else {
@@ -534,18 +571,18 @@ async fn build_package(
534
571
prepare_output_directory ( & output_dir) . await ?;
535
572
536
573
// Determine the build plan.
537
- let plan = BuildPlan :: determine ( & source, sdist, wheel) ?;
574
+ let plan = BuildPlan :: determine ( & source, sdist, wheel) . map_err ( Error :: BuildPlan ) ?;
538
575
539
576
// Check if the build backend is matching uv version that allows calling in the uv build backend
540
577
// directly.
541
578
let build_action = if list {
542
579
if force_pep517 {
543
- bail ! ( "Can't use `--force-pep517` with `--list`" ) ;
580
+ return Err ( Error :: ListForcePep517 ) ;
544
581
}
545
582
546
583
if !check_fast_path ( source. path ( ) ) {
547
584
// TODO(konsti): Provide more context on what mismatched
548
- bail ! ( "Can only use `--list` with the uv backend" ) ;
585
+ return Err ( Error :: ListNonUv ) ;
549
586
}
550
587
551
588
BuildAction :: List
@@ -614,9 +651,8 @@ async fn build_package(
614
651
// Extract the source distribution into a temporary directory.
615
652
let path = output_dir. join ( sdist_build. filename ( ) ) ;
616
653
let reader = fs_err:: tokio:: File :: open ( & path) . await ?;
617
- let ext = SourceDistExtension :: from_path ( path. as_path ( ) ) . map_err ( |err| {
618
- anyhow:: anyhow!( "`{}` is not a valid source distribution, as it ends with an unsupported extension. Expected one of: {err}." , path. user_display( ) )
619
- } ) ?;
654
+ let ext = SourceDistExtension :: from_path ( path. as_path ( ) )
655
+ . map_err ( |err| Error :: InvalidSourceDistExt ( path. user_display ( ) . to_string ( ) , err) ) ?;
620
656
let temp_dir = tempfile:: tempdir_in ( cache. bucket ( CacheBucket :: SourceDistributions ) ) ?;
621
657
uv_extract:: stream:: archive ( reader, ext, temp_dir. path ( ) ) . await ?;
622
658
@@ -719,10 +755,7 @@ async fn build_package(
719
755
// Extract the source distribution into a temporary directory.
720
756
let reader = fs_err:: tokio:: File :: open ( source. path ( ) ) . await ?;
721
757
let ext = SourceDistExtension :: from_path ( source. path ( ) ) . map_err ( |err| {
722
- anyhow:: anyhow!(
723
- "`{}` is not a valid build source. Expected to receive a source directory, or a source distribution ending in one of: {err}." ,
724
- source. path( ) . user_display( )
725
- )
758
+ Error :: InvalidSourceDistExt ( source. path ( ) . user_display ( ) . to_string ( ) , err)
726
759
} ) ?;
727
760
let temp_dir = tempfile:: tempdir_in ( & output_dir) ?;
728
761
uv_extract:: stream:: archive ( reader, ext, temp_dir. path ( ) ) . await ?;
@@ -794,7 +827,7 @@ async fn build_sdist(
794
827
subdirectory : Option < & Path > ,
795
828
version_id : Option < & str > ,
796
829
build_output : BuildOutput ,
797
- ) -> Result < BuildMessage > {
830
+ ) -> Result < BuildMessage , Error > {
798
831
let build_result = match action {
799
832
BuildAction :: List => {
800
833
let source_tree_ = source_tree. to_path_buf ( ) ;
@@ -859,7 +892,8 @@ async fn build_sdist(
859
892
BuildKind :: Sdist ,
860
893
build_output,
861
894
)
862
- . await ?;
895
+ . await
896
+ . map_err ( Error :: BuildDispatch ) ?;
863
897
let filename = builder. build ( output_dir) . await ?;
864
898
BuildMessage :: Build {
865
899
filename,
@@ -886,7 +920,7 @@ async fn build_wheel(
886
920
subdirectory : Option < & Path > ,
887
921
version_id : Option < & str > ,
888
922
build_output : BuildOutput ,
889
- ) -> Result < BuildMessage > {
923
+ ) -> Result < BuildMessage , Error > {
890
924
let build_message = match action {
891
925
BuildAction :: List => {
892
926
let source_tree_ = source_tree. to_path_buf ( ) ;
@@ -951,7 +985,8 @@ async fn build_wheel(
951
985
BuildKind :: Wheel ,
952
986
build_output,
953
987
)
954
- . await ?;
988
+ . await
989
+ . map_err ( Error :: BuildDispatch ) ?;
955
990
let filename = builder. build ( output_dir) . await ?;
956
991
BuildMessage :: Build {
957
992
filename,
@@ -963,7 +998,7 @@ async fn build_wheel(
963
998
}
964
999
965
1000
/// Create the output directory and add a `.gitignore`.
966
- async fn prepare_output_directory ( output_dir : & Path ) -> Result < ( ) > {
1001
+ async fn prepare_output_directory ( output_dir : & Path ) -> Result < ( ) , Error > {
967
1002
// Create the output directory.
968
1003
fs_err:: tokio:: create_dir_all ( & output_dir) . await ?;
969
1004
0 commit comments