@@ -316,36 +316,30 @@ pub fn fetchAndAddDependencies(
316
316
317
317
// Directories do not provide a hash in build.zig.zon.
318
318
// Hash the path to the module rather than its contents.
319
- if (fetch_location == .directory ) {
320
- if (dep .hash != null ) {
321
- return report .fail (dep .hash_tok , "hash not allowed for directory package" , .{});
322
- }
323
- const hex_digest = Manifest .hexDigest (try computePathHash (gpa , directory , fetch_location .directory ));
324
- dep .hash = try gpa .dupe (u8 , & hex_digest );
325
- }
326
-
327
- const sub_mod , const found_existing = try getCachedPackage (
328
- arena ,
329
- fetch_location ,
330
- global_cache_directory ,
331
- dep .* ,
332
- all_modules ,
333
- root_prog_node ,
334
- ) orelse .{
335
- try fetchAndUnpack (
336
- fetch_location ,
337
- thread_pool ,
338
- http_client ,
339
- directory ,
319
+ const sub_mod , const found_existing = if (fetch_location == .directory )
320
+ try getDirectoryModule (gpa , fetch_location , directory , all_modules , dep , report )
321
+ else
322
+ try getCachedPackage (
323
+ gpa ,
340
324
global_cache_directory ,
341
325
dep .* ,
342
- report ,
343
326
all_modules ,
344
327
root_prog_node ,
345
- name ,
346
- ),
347
- false ,
348
- };
328
+ ) orelse .{
329
+ try fetchAndUnpack (
330
+ fetch_location ,
331
+ thread_pool ,
332
+ http_client ,
333
+ directory ,
334
+ global_cache_directory ,
335
+ dep .* ,
336
+ report ,
337
+ all_modules ,
338
+ root_prog_node ,
339
+ name ,
340
+ ),
341
+ false ,
342
+ };
349
343
350
344
assert (dep .hash != null );
351
345
@@ -576,14 +570,6 @@ const FetchLocation = union(enum) {
576
570
.resource = .{ .file = try root_dir .handle .openFile (file , .{}) },
577
571
};
578
572
},
579
- .directory = > | dir | {
580
- const owned_path = try gpa .dupe (u8 , dir );
581
- errdefer gpa .free (owned_path );
582
- return .{
583
- .path = owned_path ,
584
- .resource = .{ .directory = try root_dir .handle .openIterableDir (dir , .{}) },
585
- };
586
- },
587
573
.http_request = > | uri | {
588
574
var h = std.http.Headers { .allocator = gpa };
589
575
defer h .deinit ();
@@ -606,6 +592,7 @@ const FetchLocation = union(enum) {
606
592
.resource = .{ .http_request = req },
607
593
};
608
594
},
595
+ .directory = > unreachable , // Directories do not require fetching
609
596
}
610
597
}
611
598
};
@@ -614,7 +601,6 @@ const ReadableResource = struct {
614
601
path : []const u8 ,
615
602
resource : union (enum ) {
616
603
file : fs.File ,
617
- directory : fs.IterableDir ,
618
604
http_request : std.http.Client.Request ,
619
605
},
620
606
@@ -625,20 +611,12 @@ const ReadableResource = struct {
625
611
rr : * ReadableResource ,
626
612
allocator : Allocator ,
627
613
thread_pool : * ThreadPool ,
628
- root_dir : Compilation.Directory ,
629
614
global_cache_directory : Compilation.Directory ,
630
615
dep : Manifest.Dependency ,
631
616
report : Report ,
632
617
pkg_prog_node : * std.Progress.Node ,
633
618
) ! PackageLocation {
634
619
switch (rr .resource ) {
635
- .directory = > {
636
- return .{
637
- .hash = try computePathHash (allocator , root_dir , rr .path ),
638
- .root_src_dir_path = try allocator .dupe (u8 , rr .path ),
639
- .root_dir = root_dir ,
640
- };
641
- },
642
620
inline .file , .http_request = > | * r | {
643
621
const s = fs .path .sep_str ;
644
622
const rand_int = std .crypto .random .int (u64 );
@@ -710,8 +688,7 @@ const ReadableResource = struct {
710
688
711
689
return .{
712
690
.hash = actual_hash ,
713
- .root_src_dir_path = relative_unpacked_path ,
714
- .root_dir = global_cache_directory ,
691
+ .relative_unpacked_path = relative_unpacked_path ,
715
692
};
716
693
},
717
694
}
@@ -727,7 +704,6 @@ const ReadableResource = struct {
727
704
// TODO: Handle case of chunked content-length
728
705
.http_request = > | req | return req .response .content_length ,
729
706
.file = > | f | return (try f .metadata ()).size (),
730
- .directory = > unreachable ,
731
707
}
732
708
}
733
709
@@ -737,7 +713,6 @@ const ReadableResource = struct {
737
713
return fileTypeFromPath (rr .path ) orelse
738
714
return report .fail (dep .location_tok , "Unknown file type" , .{});
739
715
},
740
- .directory = > return error .IsDir ,
741
716
.http_request = > | req | {
742
717
const content_type = req .response .headers .getFirstValue ("Content-Type" ) orelse
743
718
return report .fail (dep .location_tok , "Missing 'Content-Type' header" , .{});
@@ -793,7 +768,6 @@ const ReadableResource = struct {
793
768
gpa .free (rr .path );
794
769
switch (rr .resource ) {
795
770
.file = > | file | file .close (),
796
- .directory = > | * dir | dir .close (),
797
771
.http_request = > | * req | req .deinit (),
798
772
}
799
773
rr .* = undefined ;
@@ -804,11 +778,10 @@ pub const PackageLocation = struct {
804
778
/// For packages that require unpacking, this is the hash of the package contents.
805
779
/// For directories, this is the hash of the absolute file path.
806
780
hash : [Manifest .Hash .digest_length ]u8 ,
807
- root_src_dir_path : []const u8 ,
808
- root_dir : Compilation.Directory ,
781
+ relative_unpacked_path : []const u8 ,
809
782
810
783
pub fn deinit (pl : * PackageLocation , allocator : Allocator ) void {
811
- allocator .free (pl .root_src_dir_path );
784
+ allocator .free (pl .relative_unpacked_path );
812
785
pl .* = undefined ;
813
786
}
814
787
};
@@ -874,19 +847,11 @@ fn ProgressReader(comptime ReaderType: type) type {
874
847
/// (i.e. whether or not its transitive dependencies have been fetched).
875
848
fn getCachedPackage (
876
849
gpa : Allocator ,
877
- fetch_location : FetchLocation ,
878
850
global_cache_directory : Compilation.Directory ,
879
851
dep : Manifest.Dependency ,
880
852
all_modules : * AllModules ,
881
853
root_prog_node : * std.Progress.Node ,
882
854
) ! ? struct { DependencyModule , bool } {
883
- // There is no fixed location to check for directory modules.
884
- // Instead, check whether it is already listed in all_modules.
885
- if (fetch_location == .directory ) {
886
- const hex_digest = dep .hash .? [0.. hex_multihash_len ];
887
- return if (all_modules .get (hex_digest .* )) | mod | .{ mod .? , true } else null ;
888
- }
889
-
890
855
const s = fs .path .sep_str ;
891
856
// Check if the expected_hash is already present in the global package
892
857
// cache, and thereby avoid both fetching and unpacking.
@@ -912,34 +877,60 @@ fn getCachedPackage(
912
877
root_prog_node .completeOne ();
913
878
914
879
const is_zig_mod = if (pkg_dir .access (build_zig_basename , .{})) | _ | true else | _ | false ;
880
+ const basename = if (is_zig_mod ) build_zig_basename else "" ;
881
+ const pkg = try createWithDir (gpa , global_cache_directory , pkg_dir_sub_path , basename );
915
882
916
- const build_root = try global_cache_directory .join (gpa , &.{pkg_dir_sub_path });
917
- errdefer gpa .free (build_root );
918
-
919
- const ptr = try gpa .create (Package );
920
- errdefer gpa .destroy (ptr );
883
+ const module : DependencyModule = if (is_zig_mod )
884
+ .{ .zig_pkg = pkg }
885
+ else
886
+ .{ .non_zig_pkg = pkg };
921
887
922
- const owned_src_path = if (is_zig_mod ) try gpa .dupe (u8 , build_zig_basename ) else "" ;
923
- errdefer gpa .free (owned_src_path );
888
+ try all_modules .put (gpa , hex_digest .* , module );
889
+ return .{ module , false };
890
+ }
924
891
925
- ptr .* = .{
926
- .root_src_directory = .{
927
- .path = build_root ,
928
- .handle = pkg_dir ,
929
- },
930
- .root_src_directory_owned = true ,
931
- .root_src_path = owned_src_path ,
932
- };
892
+ return null ;
893
+ }
933
894
934
- gop .value_ptr .* = if (is_zig_mod )
935
- .{ .zig_pkg = ptr }
936
- else
937
- .{ .non_zig_pkg = ptr };
895
+ fn getDirectoryModule (
896
+ gpa : Allocator ,
897
+ fetch_location : FetchLocation ,
898
+ directory : Compilation.Directory ,
899
+ all_modules : * AllModules ,
900
+ dep : * Manifest.Dependency ,
901
+ report : Report ,
902
+ ) ! struct { DependencyModule , bool } {
903
+ assert (fetch_location == .directory );
938
904
939
- return .{ gop .value_ptr .*.? , false };
905
+ if (dep .hash != null ) {
906
+ return report .fail (dep .hash_tok , "hash not allowed for directory package" , .{});
940
907
}
941
908
942
- return null ;
909
+ const hash = try computePathHash (gpa , directory , fetch_location .directory );
910
+ const hex_digest = Manifest .hexDigest (hash );
911
+ dep .hash = try gpa .dupe (u8 , & hex_digest );
912
+
913
+ // There is no fixed location to check for directory modules.
914
+ // Instead, check whether it is already listed in all_modules.
915
+ if (all_modules .get (hex_digest )) | mod | return .{ mod .? , true };
916
+
917
+ var pkg_dir = directory .handle .openDir (fetch_location .directory , .{}) catch | err | switch (err ) {
918
+ error .FileNotFound = > return report .fail (dep .location_tok , "File not found: {s}" , .{fetch_location .directory }),
919
+ else = > | e | return e ,
920
+ };
921
+ defer pkg_dir .close ();
922
+
923
+ const is_zig_mod = if (pkg_dir .access (build_zig_basename , .{})) | _ | true else | _ | false ;
924
+ const basename = if (is_zig_mod ) build_zig_basename else "" ;
925
+
926
+ const pkg = try createWithDir (gpa , directory , fetch_location .directory , basename );
927
+ const module : DependencyModule = if (is_zig_mod )
928
+ .{ .zig_pkg = pkg }
929
+ else
930
+ .{ .non_zig_pkg = pkg };
931
+
932
+ try all_modules .put (gpa , hex_digest , module );
933
+ return .{ module , false };
943
934
}
944
935
945
936
fn fetchAndUnpack (
@@ -956,6 +947,8 @@ fn fetchAndUnpack(
956
947
/// is only intended to be human-readable for progress reporting.
957
948
name_for_prog : []const u8 ,
958
949
) ! DependencyModule {
950
+ assert (fetch_location == .file or fetch_location == .http_request );
951
+
959
952
const gpa = http_client .allocator ;
960
953
961
954
var pkg_prog_node = root_prog_node .start (name_for_prog , 0 );
@@ -966,51 +959,47 @@ fn fetchAndUnpack(
966
959
var readable_resource = try fetch_location .fetch (gpa , directory , http_client , dep , report );
967
960
defer readable_resource .deinit (gpa );
968
961
969
- var package_location = try readable_resource .unpack (gpa , thread_pool , directory , global_cache_directory , dep , report , & pkg_prog_node );
962
+ var package_location = try readable_resource .unpack (gpa , thread_pool , global_cache_directory , dep , report , & pkg_prog_node );
970
963
defer package_location .deinit (gpa );
971
964
972
965
const actual_hex = Manifest .hexDigest (package_location .hash );
973
- if (readable_resource .resource != .directory ) {
974
- if (dep .hash ) | h | {
975
- if (! mem .eql (u8 , h , & actual_hex )) {
976
- return report .fail (dep .hash_tok , "hash mismatch: expected: {s}, found: {s}" , .{
977
- h , actual_hex ,
978
- });
979
- }
980
- } else {
981
- const file_path = try report .directory .join (gpa , &.{Manifest .basename });
982
- defer gpa .free (file_path );
983
-
984
- const eb = report .error_bundle ;
985
- const notes_len = 1 ;
986
- try Report .addErrorMessage (report .ast .* , file_path , eb , notes_len , .{
987
- .tok = dep .location_tok ,
988
- .off = 0 ,
989
- .msg = "dependency is missing hash field" ,
966
+ if (dep .hash ) | h | {
967
+ if (! mem .eql (u8 , h , & actual_hex )) {
968
+ return report .fail (dep .hash_tok , "hash mismatch: expected: {s}, found: {s}" , .{
969
+ h , actual_hex ,
990
970
});
991
- const notes_start = try eb .reserveNotes (notes_len );
992
- eb .extra .items [notes_start ] = @intFromEnum (try eb .addErrorMessage (.{
993
- .msg = try eb .printString ("expected .hash = \" {s}\" ," , .{& actual_hex }),
994
- }));
995
- return error .PackageFetchFailed ;
996
971
}
972
+ } else {
973
+ const file_path = try report .directory .join (gpa , &.{Manifest .basename });
974
+ defer gpa .free (file_path );
975
+
976
+ const eb = report .error_bundle ;
977
+ const notes_len = 1 ;
978
+ try Report .addErrorMessage (report .ast .* , file_path , eb , notes_len , .{
979
+ .tok = dep .location_tok ,
980
+ .off = 0 ,
981
+ .msg = "dependency is missing hash field" ,
982
+ });
983
+ const notes_start = try eb .reserveNotes (notes_len );
984
+ eb .extra .items [notes_start ] = @intFromEnum (try eb .addErrorMessage (.{
985
+ .msg = try eb .printString ("expected .hash = \" {s}\" ," , .{& actual_hex }),
986
+ }));
987
+ return error .PackageFetchFailed ;
997
988
}
998
989
999
- const build_zig_path = try std . fs .path .join (gpa , &.{ package_location .root_src_dir_path , build_zig_basename });
990
+ const build_zig_path = try fs .path .join (gpa , &.{ package_location .relative_unpacked_path , build_zig_basename });
1000
991
defer gpa .free (build_zig_path );
1001
992
1002
- package_location .root_dir .handle .access (build_zig_path , .{}) catch | err | switch (err ) {
1003
- error .FileNotFound = > {
1004
- const module = try createWithDir (gpa , package_location .root_dir , package_location .root_src_dir_path , "" );
1005
- try all_modules .put (gpa , actual_hex , .{ .non_zig_pkg = module });
1006
- return .{ .non_zig_pkg = module };
1007
- },
1008
- else = > return err ,
1009
- };
993
+ const is_zig_mod = if (global_cache_directory .handle .access (build_zig_path , .{})) | _ | true else | _ | false ;
994
+ const basename = if (is_zig_mod ) build_zig_basename else "" ;
995
+ const pkg = try createWithDir (gpa , global_cache_directory , package_location .relative_unpacked_path , basename );
996
+ const module : DependencyModule = if (is_zig_mod )
997
+ .{ .zig_pkg = pkg }
998
+ else
999
+ .{ .non_zig_pkg = pkg };
1010
1000
1011
- const module = try createWithDir (gpa , package_location .root_dir , package_location .root_src_dir_path , build_zig_basename );
1012
- try all_modules .put (gpa , actual_hex , .{ .zig_pkg = module });
1013
- return .{ .zig_pkg = module };
1001
+ try all_modules .put (gpa , actual_hex , module );
1002
+ return module ;
1014
1003
}
1015
1004
1016
1005
fn unpackTarball (
0 commit comments