1- use bullet_stream:: { Print , style} ;
1+ use bullet_stream:: { global :: print , style} ;
22use clap:: Parser ;
33use fs_err:: PathExt ;
44use gem_version:: GemVersion ;
@@ -14,6 +14,7 @@ use shared::{
1414use std:: convert:: From ;
1515use std:: error:: Error ;
1616use std:: str:: FromStr ;
17+ use std:: time:: Instant ;
1718
1819static S3_BASE_URL : & str = "https://heroku-buildpack-ruby.s3.us-east-1.amazonaws.com" ;
1920
@@ -32,7 +33,8 @@ fn jruby_build(args: &Args) -> Result<(), Box<dyn Error>> {
3233 base_image,
3334 } = args;
3435
35- let mut log = Print :: new ( std:: io:: stderr ( ) ) . h1 ( "Building JRuby" ) ;
36+ let start = Instant :: now ( ) ;
37+ print:: h2 ( "Building JRuby" ) ;
3638 let inventory = source_dir ( ) . join ( "jruby_inventory.toml" ) ;
3739 let volume_cache_dir = source_dir ( ) . join ( "cache" ) ;
3840 let volume_output_dir = source_dir ( ) . join ( "output" ) ;
@@ -48,161 +50,137 @@ fn jruby_build(args: &Args) -> Result<(), Box<dyn Error>> {
4850 TarDownloadPath ( volume_cache_dir. join ( format ! ( "jruby-dist-{version}-bin.tar.gz" ) ) ) ;
4951
5052 if download_path. as_ref ( ) . fs_err_try_exists ( ) ? {
51- log = log
52- . bullet ( format ! (
53- "Using cached JRuby archive {}" ,
54- download_path. as_ref( ) . display( )
55- ) )
56- . done ( ) ;
53+ print:: bullet ( format ! (
54+ "Using cached JRuby archive {}" ,
55+ download_path. as_ref( ) . display( )
56+ ) ) ;
5757 } else {
5858 let url = format ! (
5959 "https://repo1.maven.org/maven2/org/jruby/jruby-dist/{version}/jruby-dist-{version}-bin.tar.gz"
6060 ) ;
61- let timer = log
62- . bullet ( "Download JRuby" )
63- . sub_bullet ( format ! ( "To {}" , download_path. as_ref( ) . to_string_lossy( ) ) )
64- . sub_bullet ( format ! ( "From {}" , style:: url( & url) ) )
65- . start_timer ( "Downloading" ) ;
66- download_tar ( & url, & download_path) ?;
61+ print:: bullet ( "Download JRuby" ) ;
62+ print:: sub_bullet ( format ! ( "To {}" , download_path. as_ref( ) . to_string_lossy( ) ) ) ;
63+ print:: sub_bullet ( format ! ( "From {}" , style:: url( & url) ) ) ;
6764
68- log = timer. done ( ) . done ( ) ;
65+ let timer = print:: sub_start_timer ( "Downloading" ) ;
66+ download_tar ( & url, & download_path) ?;
67+ timer. done ( ) ;
6968 }
7069
7170 untar_to_dir ( & download_path, & extracted_path) ?;
7271
7372 let jruby_dir = extracted_path. join ( format ! ( "jruby-{version}" ) ) ;
7473
75- log = {
76- let mut bullet = log. bullet ( "Removing unnecessary files" ) ;
77- for pattern in & [ "*.bat" , "*.dll" , "*.exe" ] {
78- for path in glob:: glob ( & jruby_dir. join ( "bin" ) . join ( pattern) . to_string_lossy ( ) ) ?
79- . collect :: < Result < Vec < _ > , _ > > ( ) ?
80- {
81- bullet = bullet. sub_bullet ( format ! ( "Remove {}" , path. display( ) ) ) ;
82- fs_err:: remove_file ( path) ?;
83- }
74+ print:: bullet ( "Removing unnecessary files" ) ;
75+ for pattern in & [ "*.bat" , "*.dll" , "*.exe" ] {
76+ for path in glob:: glob ( & jruby_dir. join ( "bin" ) . join ( pattern) . to_string_lossy ( ) ) ?
77+ . collect :: < Result < Vec < _ > , _ > > ( ) ?
78+ {
79+ print:: sub_bullet ( format ! ( "Remove {}" , path. display( ) ) ) ;
80+ fs_err:: remove_file ( path) ?;
8481 }
82+ }
8583
86- let path = jruby_dir. join ( "lib" ) . join ( "target" ) ;
87- if path. fs_err_try_exists ( ) ? {
88- bullet = bullet . sub_bullet ( format ! ( "Remove recursive {}" , path. display( ) ) ) ;
89- fs_err:: remove_dir_all ( & path) ?;
90- }
84+ let path = jruby_dir. join ( "lib" ) . join ( "target" ) ;
85+ if path. fs_err_try_exists ( ) ? {
86+ print :: sub_bullet ( format ! ( "Remove recursive {}" , path. display( ) ) ) ;
87+ fs_err:: remove_dir_all ( & path) ?;
88+ }
9189
92- bullet. done ( )
93- } ;
94-
95- log = {
96- let bullet = log. bullet ( "Checking for `ruby` binstub" ) ;
97- let ruby_bin = jruby_dir. join ( "bin" ) . join ( "ruby" ) ;
98- if ruby_bin. fs_err_try_exists ( ) ? {
99- bullet. sub_bullet ( "File exists" )
100- } else {
101- let sub = bullet. sub_bullet ( "Create ruby symlink to jruby" ) ;
102- fs_err:: os:: unix:: fs:: symlink ( "jruby" , ruby_bin) ?;
103- sub
104- }
105- . done ( )
106- } ;
90+ print:: bullet ( "Checking for `ruby` binstub" ) ;
91+ let ruby_bin = jruby_dir. join ( "bin" ) . join ( "ruby" ) ;
92+ if ruby_bin. fs_err_try_exists ( ) ? {
93+ print:: sub_bullet ( "File exists" )
94+ } else {
95+ print:: sub_bullet ( "Create ruby symlink to jruby" ) ;
96+ fs_err:: os:: unix:: fs:: symlink ( "jruby" , ruby_bin) ?;
97+ }
10798
10899 let tgz_name = format ! ( "ruby-{ruby_stdlib_version}-jruby-{version}.tgz" ) ;
109100
110- log = {
111- let mut bullet = log. bullet ( "Creating tgz archives" ) ;
112- bullet = bullet. sub_bullet ( format ! (
113- "Inventory file {}" ,
114- style:: value( inventory. to_string_lossy( ) )
115- ) ) ;
116- let tar_dir = volume_output_dir. join ( base_image. to_string ( ) ) ;
117-
118- fs_err:: create_dir_all ( & tar_dir) ?;
119-
120- let tar_file = fs_err:: File :: create ( tar_dir. join ( & tgz_name) ) ?;
121-
122- let timer = bullet. start_timer ( format ! ( "Write {}" , tar_file. path( ) . display( ) ) ) ;
123- tar_dir_to_file ( & jruby_dir, & tar_file) ?;
124- bullet = timer. done ( ) ;
125-
126- let tar_path = tar_file. path ( ) ;
127- let sha = sha256_from_path ( tar_path) ?;
128- let sha_seven = sha. chars ( ) . take ( 7 ) . collect :: < String > ( ) ;
129- let sha_seven_path = append_filename_with ( tar_path, & format ! ( "-{sha_seven}" ) , ".tgz" ) ?;
130-
131- bullet = bullet. sub_bullet ( format ! ( "Write {}" , sha_seven_path. display( ) , ) ) ;
132- fs_err:: copy ( tar_file. path ( ) , & sha_seven_path) ?;
133-
134- let timestamp = chrono:: Utc :: now ( ) ;
135- for cpu_arch in [ Arch :: Amd64 , Arch :: Arm64 ] {
136- let distro_version = base_image. distro_version ( ) ;
137- let artifact = Artifact {
138- version : GemVersion :: from_str ( version) ?,
139- os : inventory:: artifact:: Os :: Linux ,
140- arch : cpu_arch,
141- url : format ! (
142- "{S3_BASE_URL}/{}" ,
143- sha_seven_path. strip_prefix( & volume_output_dir) ?. display( )
144- ) ,
145- checksum : format ! ( "sha256:{sha}" ) . parse ( ) ?,
146- metadata : ArtifactMetadata {
147- distro_version,
148- timestamp,
149- } ,
150- } ;
151- atomic_inventory_update ( & inventory, |inventory| {
152- for prior in & inventory. artifacts {
153- if let Err ( error) = artifact_same_url_different_checksum ( prior, & artifact) {
154- // TODO: Investigate bullet stream ownership
155- println ! (
156- "{}" ,
157- style:: important( format!(
158- "!!!!!!!!!! Error updating inventory: {error}"
159- ) )
160- ) ;
161-
162- fs_err:: remove_file ( & sha_seven_path) ?;
163- return Err ( error) ;
164- } ;
165- }
166-
167- inventory
168- . artifacts
169- . retain ( |a| artifact_is_different ( a, & artifact) ) ;
170-
171- inventory. push ( artifact) ;
172- Ok ( ( ) )
173- } ) ?
174- }
101+ print:: bullet ( "Creating tgz archives" ) ;
102+ print:: sub_bullet ( format ! (
103+ "Inventory file {}" ,
104+ style:: value( inventory. to_string_lossy( ) )
105+ ) ) ;
106+ let tar_dir = volume_output_dir. join ( base_image. to_string ( ) ) ;
107+
108+ fs_err:: create_dir_all ( & tar_dir) ?;
109+
110+ let tar_file = fs_err:: File :: create ( tar_dir. join ( & tgz_name) ) ?;
111+
112+ let timer = print:: sub_start_timer ( format ! ( "Write {}" , tar_file. path( ) . display( ) ) ) ;
113+ tar_dir_to_file ( & jruby_dir, & tar_file) ?;
114+ timer. done ( ) ;
115+
116+ let tar_path = tar_file. path ( ) ;
117+ let sha = sha256_from_path ( tar_path) ?;
118+ let sha_seven = sha. chars ( ) . take ( 7 ) . collect :: < String > ( ) ;
119+ let sha_seven_path = append_filename_with ( tar_path, & format ! ( "-{sha_seven}" ) , ".tgz" ) ?;
120+
121+ print:: sub_bullet ( format ! ( "Write {}" , sha_seven_path. display( ) , ) ) ;
122+ fs_err:: copy ( tar_file. path ( ) , & sha_seven_path) ?;
123+
124+ let timestamp = chrono:: Utc :: now ( ) ;
125+ for cpu_arch in [ Arch :: Amd64 , Arch :: Arm64 ] {
126+ let distro_version = base_image. distro_version ( ) ;
127+ let artifact = Artifact {
128+ version : GemVersion :: from_str ( version) ?,
129+ os : inventory:: artifact:: Os :: Linux ,
130+ arch : cpu_arch,
131+ url : format ! (
132+ "{S3_BASE_URL}/{}" ,
133+ sha_seven_path. strip_prefix( & volume_output_dir) ?. display( )
134+ ) ,
135+ checksum : format ! ( "sha256:{sha}" ) . parse ( ) ?,
136+ metadata : ArtifactMetadata {
137+ distro_version,
138+ timestamp,
139+ } ,
140+ } ;
141+ atomic_inventory_update ( & inventory, |inventory| {
142+ for prior in & inventory. artifacts {
143+ if let Err ( error) = artifact_same_url_different_checksum ( prior, & artifact) {
144+ print:: error ( format ! ( "Error updating inventory\n \n Error: {error}" ) ) ;
145+
146+ fs_err:: remove_file ( & sha_seven_path) ?;
147+ return Err ( error) ;
148+ } ;
149+ }
175150
176- // Can be removed once manifest file support is fully rolled out
177- for cpu_arch in [ Arch :: Amd64 , Arch :: Arm64 ] {
178- let dir = volume_output_dir
179- . join ( base_image. to_string ( ) )
180- . join ( cpu_arch. to_string ( ) ) ;
181- fs_err:: create_dir_all ( & dir) ?;
151+ inventory
152+ . artifacts
153+ . retain ( |a| artifact_is_different ( a, & artifact) ) ;
182154
183- let path = dir . join ( & tgz_name ) ;
184- bullet = bullet . sub_bullet ( format ! ( "Write {}" , path . display ( ) ) ) ;
185- fs_err :: copy ( tar_file . path ( ) , & path ) ? ;
186- }
155+ inventory . push ( artifact ) ;
156+ Ok ( ( ) )
157+ } ) ?
158+ }
187159
188- bullet. done ( )
189- } ;
160+ // Can be removed once manifest file support is fully rolled out
161+ for cpu_arch in [ Arch :: Amd64 , Arch :: Arm64 ] {
162+ let dir = volume_output_dir
163+ . join ( base_image. to_string ( ) )
164+ . join ( cpu_arch. to_string ( ) ) ;
165+ fs_err:: create_dir_all ( & dir) ?;
190166
191- log. done ( ) ;
167+ let path = dir. join ( & tgz_name) ;
168+ print:: sub_bullet ( format ! ( "Write {}" , path. display( ) ) ) ;
169+ fs_err:: copy ( tar_file. path ( ) , & path) ?;
170+ }
192171
172+ print:: all_done ( & Some ( start) ) ;
193173 Ok ( ( ) )
194174}
195175
196176fn main ( ) {
197177 let args = Args :: parse ( ) ;
198178 if let Err ( error) = jruby_build ( & args) {
199- Print :: new ( std:: io:: stderr ( ) )
200- . without_header ( )
201- . error ( formatdoc ! { "
202- ❌ Command failed ❌
179+ print:: error ( formatdoc ! { "
180+ ❌ Command failed ❌
203181
204- {error}
205- " } ) ;
182+ {error}
183+ " } ) ;
206184 std:: process:: exit ( 1 ) ;
207185 }
208186}
0 commit comments