@@ -48,52 +48,86 @@ pub fn process_package_lock_json(path: &Path) -> Result<Vec<Package>> {
4848 }
4949}
5050
51+ pub fn process_yarn_lock ( path : & Path ) -> Result < Vec < Package > > {
52+ let yarn_lock_file = path. join ( "yarn.lock" ) ;
53+ let yarn_lock_contents = read_to_string ( yarn_lock_file) ?;
54+ let lockfile_packages = yarn_lock_parser:: parse_str ( & yarn_lock_contents) ?;
55+ let package_json_deps = process_package_json ( path) ?;
56+
57+ let mut deps = HashSet :: new ( ) ;
58+
59+ for package_dep in package_json_deps {
60+ let version = lockfile_packages
61+ . binary_search_by ( |p| p. name . cmp ( & package_dep. name ) )
62+ . map_or ( package_dep. version , |dep| {
63+ Some ( lockfile_packages[ dep] . version . to_string ( ) )
64+ } ) ;
65+
66+ deps. insert ( Package {
67+ version,
68+ ..package_dep
69+ } ) ;
70+ }
71+
72+ Ok ( deps. into_iter ( ) . collect ( ) )
73+ }
74+
5175#[ cfg( test) ]
5276mod tests {
5377 use std:: { env, path:: PathBuf } ;
5478
5579 use super :: * ;
5680
81+ thread_local ! {
82+ static EXPECTED_DEPS : Vec <Package > = Vec :: from( [
83+ Package {
84+ language: String :: from( "javascript" ) ,
85+ name: String :: from( "fsevents" ) ,
86+ version: Some ( String :: from( "2.2.2" ) ) ,
87+ } ,
88+ Package {
89+ language: String :: from( "javascript" ) ,
90+ name: String :: from( "react" ) ,
91+ version: Some ( String :: from( "18.2.0" ) ) ,
92+ } ,
93+ Package {
94+ language: String :: from( "javascript" ) ,
95+ name: String :: from( "vite" ) ,
96+ version: Some ( String :: from( "5.1.4" ) ) ,
97+ } ,
98+ Package {
99+ language: String :: from( "javascript" ) ,
100+ name: String :: from( "zustand" ) ,
101+ version: Some ( String :: from( "4.5.1" ) ) ,
102+ } ,
103+ ] ) ;
104+ }
105+
57106 #[ test]
58107 fn it_parses_top_level_deps_from_package_lock ( ) -> Result < ( ) > {
59- let mut expected_deps = Vec :: from ( [
60- Package {
61- language : String :: from ( "javascript" ) ,
62- name : String :: from ( "fsevents" ) ,
63- version : Some ( String :: from ( "2.2.2" ) ) ,
64- } ,
65- Package {
66- language : String :: from ( "javascript" ) ,
67- name : String :: from ( "react" ) ,
68- version : Some ( String :: from ( "18.2.0" ) ) ,
69- } ,
70- Package {
71- language : String :: from ( "javascript" ) ,
72- name : String :: from ( "vite" ) ,
73- version : Some ( String :: from ( "5.1.4" ) ) ,
74- } ,
75- Package {
76- language : String :: from ( "javascript" ) ,
77- name : String :: from ( "zustand" ) ,
78- version : Some ( String :: from ( "4.5.1" ) ) ,
79- } ,
80- ] ) ;
81- let project_path = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) ?) ;
82- let test_fixtures_path = project_path. join ( "testdata" ) ;
83- let mut deps = process_package_lock_json ( test_fixtures_path. as_path ( ) ) ?;
84-
85- deps. sort ( ) ;
86- expected_deps. sort ( ) ;
87-
88- assert_eq ! ( deps, expected_deps) ;
89- Ok ( ( ) )
108+ EXPECTED_DEPS . with ( |expected_deps| {
109+ let project_path = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) ?) ;
110+ let test_fixtures_path = project_path. join ( "testdata" ) ;
111+ let mut deps = process_package_lock_json ( test_fixtures_path. as_path ( ) ) ?;
112+
113+ deps. sort ( ) ;
114+
115+ assert_eq ! ( expected_deps, & deps) ;
116+ Ok ( ( ) )
117+ } )
90118 }
91119
92120 #[ test]
93- fn it_does_not_panic ( ) {
94- let temp_dir = env:: temp_dir ( ) ;
95- let res = process_package_lock_json ( temp_dir. as_path ( ) ) ;
121+ fn it_parses_top_level_deps_from_yarn_lock ( ) -> Result < ( ) > {
122+ EXPECTED_DEPS . with ( |expected_deps| {
123+ let project_path = PathBuf :: from ( env:: var ( "CARGO_MANIFEST_DIR" ) ?) ;
124+ let test_fixtures_path = project_path. join ( "testdata" ) ;
125+ let mut deps = process_yarn_lock ( test_fixtures_path. as_path ( ) ) ?;
96126
97- assert ! ( res. is_err( ) ) ;
127+ deps. sort ( ) ;
128+
129+ assert_eq ! ( expected_deps, & deps) ;
130+ Ok ( ( ) )
131+ } )
98132 }
99133}
0 commit comments