@@ -5,6 +5,7 @@ use super::listing::{list_dir_sync, ListedEntry};
55use super :: types:: { CrawledPackage , CrawlerOptions } ;
66use crate :: patch:: path_safety;
77use crate :: utils:: fs:: { is_dir_sync, run_blocking} ;
8+ use crate :: vendor:: go_mod_edit;
89use crate :: vendor:: go_sum_edit:: go_sum_lines;
910
1011#[ cfg( test) ]
@@ -280,21 +281,35 @@ fn locate_module(
280281}
281282
282283/// The `(module, version)` of every module-zip line of `<cwd>/go.sum`
283- /// (`/go.mod` lines hash only a manifest and are skipped), in file order.
284- /// `None` when a Go workspace is in effect ([`workspace_in_effect`]: its
285- /// build list spans other modules' `go.sum` and `go.work.sum`) or there is
286- /// no readable `go.sum`; the crawl then walks the whole cache.
284+ /// (`/go.mod` lines hash only a manifest and are skipped), in file order,
285+ /// then every `require` of `<cwd>/go.mod` not already listed, sorted. The
286+ /// requires keep a module the project still builds against when its own
287+ /// go.sum lines are gone: a `replace`d module's go.sum records only the
288+ /// replacement (the hosted rewrite drops the original's lines, as
289+ /// `go mod tidy` does). `None` when a Go workspace is in effect
290+ /// ([`workspace_in_effect`]: its build list spans other modules' `go.sum`
291+ /// and `go.work.sum`) or there is no readable `go.sum`; the crawl then
292+ /// walks the whole cache.
287293fn go_sum_scope ( cwd : & Path ) -> Option < Vec < ( String , String ) > > {
288294 if workspace_in_effect ( cwd) {
289295 return None ;
290296 }
291297 let text = crate :: utils:: fs:: read_regular_to_string_sync ( & cwd. join ( "go.sum" ) ) . ok ( ) ?;
292- Some (
293- go_sum_lines ( & text)
294- . filter ( |line| !line. go_mod )
295- . map ( |line| ( line. module . to_string ( ) , line. version . to_string ( ) ) )
296- . collect ( ) ,
297- )
298+ let mut scope: Vec < ( String , String ) > = go_sum_lines ( & text)
299+ . filter ( |line| !line. go_mod )
300+ . map ( |line| ( line. module . to_string ( ) , line. version . to_string ( ) ) )
301+ . collect ( ) ;
302+ if let Ok ( go_mod) = crate :: utils:: fs:: read_regular_to_string_sync ( & cwd. join ( "go.mod" ) ) {
303+ let listed: HashSet < ( String , String ) > = scope. iter ( ) . cloned ( ) . collect ( ) ;
304+ let mut required: Vec < ( String , String ) > =
305+ go_mod_edit:: parse_required_versions ( & go_mod_edit:: normalize_for_read ( & go_mod) )
306+ . into_iter ( )
307+ . filter ( |pair| !listed. contains ( pair) )
308+ . collect ( ) ;
309+ required. sort ( ) ;
310+ scope. extend ( required) ;
311+ }
312+ Some ( scope)
298313}
299314
300315/// Whether the go command would build `cwd` in workspace mode: `GOWORK`
@@ -1467,6 +1482,31 @@ mod tests {
14671482 ) ;
14681483 }
14691484
1485+ /// A `replace`d module's go.sum records only its replacement (the
1486+ /// hosted rewrite drops the original's lines, as `go mod tidy`
1487+ /// does), but go.mod still requires it: its cached copy is still
1488+ /// crawled, as the whole-cache walk did.
1489+ #[ tokio:: test]
1490+ #[ serial_test:: serial]
1491+ async fn a_required_module_without_go_sum_lines_is_still_crawled ( ) {
1492+ let f = Fixture :: new ( ) ;
1493+ f. stage ( "github.com/gin-gonic/gin" , "v1.9.1" )
1494+ . stage ( "github.com/Azure/azure-sdk-for-go" , "v1.0.0-RC1" )
1495+ . stage ( "example.com/unrelated" , "v0.1.0" )
1496+ . go_sum ( & [ ( "github.com/gin-gonic/gin" , "v1.9.1" ) ] , & [ ] ) ;
1497+ write (
1498+ & f. project . join ( "go.mod" ) ,
1499+ "\u{feff} module example.com/app\n \n require (\n \t \" github.com/gin-gonic/gin\" v1.9.1\n \t github.com/Azure/azure-sdk-for-go v1.0.0-RC1 // indirect\n )\n \n replace github.com/Azure/azure-sdk-for-go v1.0.0-RC1 => patch.socket.dev/gopatch/x v1.0.0-RC1-socketpatch.1\n " ,
1500+ ) ;
1501+ assert_eq ! (
1502+ f. crawl( ) . await ,
1503+ sorted( & [
1504+ "pkg:golang/github.com/Azure/azure-sdk-for-go@v1.0.0-RC1" ,
1505+ "pkg:golang/github.com/gin-gonic/gin@v1.9.1" ,
1506+ ] )
1507+ ) ;
1508+ }
1509+
14701510 /// A duplicated go.sum line (a union merge) yields one package.
14711511 #[ tokio:: test]
14721512 #[ serial_test:: serial]
0 commit comments