@@ -16,9 +16,6 @@ use anyhow::anyhow;
16
16
use anyhow:: Context ;
17
17
use anyhow:: Error ;
18
18
use anyhow:: Result ;
19
- use resiter:: AndThen ;
20
- use resiter:: FilterMap ;
21
- use resiter:: Map ;
22
19
use tracing:: trace;
23
20
24
21
use crate :: package:: Package ;
@@ -52,30 +49,6 @@ impl Repository {
52
49
trace ! ( "Loading files from filesystem" ) ;
53
50
let fsr = FileSystemRepresentation :: load ( path. to_path_buf ( ) ) ?;
54
51
55
- // Helper function to extract the `patches` array from a package config/definition:
56
- fn get_patches (
57
- config : & config:: ConfigBuilder < config:: builder:: DefaultState > ,
58
- path : & Path ,
59
- ) -> Result < Vec < PathBuf > > {
60
- // TODO: Avoid unnecessary config building (inefficient):
61
- let config = config. build_cloned ( ) . context ( anyhow ! (
62
- "Failed to load the following TOML file: {}" ,
63
- path. display( )
64
- ) ) ?;
65
- match config. get_array ( "patches" ) {
66
- Ok ( v) => v
67
- . into_iter ( )
68
- . map ( config:: Value :: into_string)
69
- . map_err ( Error :: from)
70
- . map_err ( |e| e. context ( "patches must be strings" ) )
71
- . map_err ( Error :: from)
72
- . map_ok ( PathBuf :: from)
73
- . collect ( ) ,
74
- Err ( config:: ConfigError :: NotFound ( _) ) => Ok ( Vec :: with_capacity ( 0 ) ) ,
75
- Err ( e) => Err ( Error :: from ( e) ) ,
76
- }
77
- }
78
-
79
52
let leaf_files = fsr
80
53
. files ( )
81
54
. par_iter ( )
@@ -86,74 +59,69 @@ impl Repository {
86
59
Err ( e) => Some ( Err ( e) ) ,
87
60
} ) ;
88
61
progress. set_length ( leaf_files. clone ( ) . count ( ) . try_into ( ) ?) ;
89
- leaf_files. inspect ( |r| trace ! ( "Loading files for {:?}" , r) )
62
+ leaf_files
63
+ . inspect ( |r| trace ! ( "Loading files for {:?}" , r) )
90
64
. map ( |path| {
91
65
progress. inc ( 1 ) ;
92
66
let path = path?;
93
- fsr. get_files_for ( path) ?
67
+ let config = fsr. get_files_for ( path) ?
94
68
. iter ( )
69
+ // Load all "layers":
95
70
. inspect ( |( path, _) | trace ! ( "Loading layer at {}" , path. display( ) ) )
96
- . fold ( Ok ( Config :: builder ( ) ) as Result < _ > , |config, ( path, content) | {
97
- let mut config = config?;
98
-
99
- let patches_before_merge = get_patches ( & config, path) ?;
100
- config = config. add_source ( config:: File :: from_str ( content, config:: FileFormat :: Toml ) ) ;
101
- let patches_after_merge = get_patches ( & config, path) ?;
102
-
103
- // TODO: Get rid of the unnecessarily complex handling of the `patches` configuration setting:
104
- // Ideally this would be handled by the `config` crate (this is
105
- // already the case for all other "settings" but in this case we also need
106
- // to prepend the corresponding directory path).
107
- let patches = if patches_before_merge == patches_after_merge {
108
- patches_before_merge
109
- } else {
110
- // The patches have changed since the `config.merge()` of the next
111
- // `pkg.toml` file so we have to build the paths to the patch files
112
- // by prepending the path to the directory of the `pkg.toml` file since
113
- // `path` is only available in this "iteration".
114
- patches_after_merge
115
- . into_iter ( )
116
- // Prepend the path of the directory of the `pkg.toml` file to the name of the patch:
117
- . map ( |p| if let Some ( current_dir) = path. parent ( ) {
118
- Ok ( current_dir. join ( p) )
119
- } else {
120
- Err ( anyhow ! ( "Path should point to path with parent, but doesn't: {}" , path. display( ) ) )
121
- } )
122
- . inspect ( |patch| trace ! ( "Patch: {:?}" , patch) )
123
- // If the patch file exists, use it (as config::Value).
124
- // Otherwise we have an error here, because we're referring to a non-existing file:
125
- . and_then_ok ( |patch| if patch. exists ( ) {
126
- Ok ( Some ( patch) )
127
- } else {
128
- Err ( anyhow ! ( "Patch does not exist: {}" , patch. display( ) ) )
129
- . with_context ( || anyhow ! ( "The patch is declared here: {}" , path. display( ) ) )
130
- } )
131
- . filter_map_ok ( |o| o)
132
- . collect :: < Result < Vec < _ > > > ( ) ?
133
- } ;
134
-
135
- trace ! ( "Patches after postprocessing merge: {:?}" , patches) ;
136
- let patches = patches
137
- . into_iter ( )
138
- . map ( |p| p. display ( ) . to_string ( ) )
139
- . map ( config:: Value :: from)
140
- . collect :: < Vec < _ > > ( ) ;
141
- {
142
- // Update the `patches` configuration setting:
143
- let mut builder = Config :: builder ( ) ;
144
- builder = builder. set_default ( "patches" , config:: Value :: from ( patches) ) ?;
145
- config = config. add_source ( builder. build ( ) ?) ;
146
- // Ideally we'd use `config.set()` but that is a permanent override (so
147
- // subsequent `config.merge()` merges won't have an effect on
148
- // "patches"). There's also `config.set_once()` but that only lasts
149
- // until the next `config.merge()` and `config.set_default()` only sets
150
- // a default value.
151
- }
152
- Ok ( config)
71
+ . fold ( Config :: builder ( ) , |config_builder, ( path, content) | {
72
+ use crate :: repository:: pkg_toml_source:: PkgTomlSource ;
73
+ config_builder. add_source ( PkgTomlSource :: new ( path, ( * content) . to_string ( ) ) )
153
74
} )
154
- . and_then ( |c| c. build ( ) ?. try_deserialize :: < Package > ( ) . map_err ( Error :: from)
155
- . with_context ( || anyhow ! ( "Could not load package configuration: {}" , path. display( ) ) ) )
156
- . map ( |pkg| ( ( pkg. name ( ) . clone ( ) , pkg. version ( ) . clone ( ) ) , pkg) )
75
+ . build ( ) ?;
76
+
77
+ let patches_value = config. get_array ( "patches" ) ;
78
+ let mut pkg = config
79
+ . try_deserialize :: < Package > ( )
80
+ . map_err ( Error :: from)
81
+ . with_context ( || {
82
+ anyhow ! ( "Could not load package configuration: {}" , path. display( ) )
83
+ } ) ?;
84
+
85
+ if !pkg. patches ( ) . is_empty ( ) {
86
+ // We have to build the full relative paths to the patch files by
87
+ // prepending the path to the directory of the `pkg.toml` file they've
88
+ // been defined in so that they can be found later.
89
+ let patches = patches_value. context ( anyhow ! (
90
+ "Bug: Could not get the \" patches\" value for: {}" ,
91
+ path. display( )
92
+ ) ) ?;
93
+ let first_patch_value = patches. first ( ) . ok_or ( anyhow ! (
94
+ "Bug: Could not get the first \" patches\" entry for: {}" ,
95
+ path. display( )
96
+ ) ) ?;
97
+ // Get the origin (path to the `pkg.toml` file) for the "patches"
98
+ // setting (it must currently be the same for all array entries):
99
+ let origin_path = first_patch_value. origin ( ) . map ( PathBuf :: from) . ok_or ( anyhow ! (
100
+ "Bug: Could not get the origin of the first \" patches\" entry for: {}" ,
101
+ path. display( )
102
+ ) ) ?;
103
+ // Note: `parent()` only "Returns None if the path terminates in a root
104
+ // or prefix, or if it’s the empty string." so this should never happen:
105
+ let origin_dir_path = origin_path. parent ( ) . ok_or ( anyhow ! (
106
+ "Bug: Could not get the origin's parent of the first \" patches\" entry for: {}" ,
107
+ path. display( )
108
+ ) ) ?;
109
+ pkg. set_patches_base_dir ( origin_dir_path) ;
110
+ // Check if the patches exist:
111
+ for patch in pkg. patches ( ) {
112
+ if !patch. exists ( ) {
113
+ return Err ( anyhow ! (
114
+ "Patch does not exist: {}" ,
115
+ patch. display( )
116
+ ) )
117
+ . with_context ( || {
118
+ anyhow ! ( "The patch is declared here: {}" , path. display( ) )
119
+ } ) ;
120
+ }
121
+ }
122
+ }
123
+
124
+ Ok ( ( ( pkg. name ( ) . clone ( ) , pkg. version ( ) . clone ( ) ) , pkg) )
157
125
} )
158
126
. collect :: < Result < BTreeMap < _ , _ > > > ( )
159
127
. map ( Repository :: new)
0 commit comments