@@ -24,7 +24,8 @@ use std::path::{PathBuf, Path};
2424use std:: process:: Command ;
2525
2626use { Build , Compiler } ;
27- use util:: { cp_r, libdir, is_dylib} ;
27+ use util:: { cp_r, libdir, is_dylib, cp_filtered, copy} ;
28+ use regex:: { RegexSet , quote} ;
2829
2930fn package_vers ( build : & Build ) -> & str {
3031 match & build. config . channel [ ..] {
@@ -284,6 +285,119 @@ pub fn std(build: &Build, compiler: &Compiler, target: &str) {
284285 t ! ( fs:: remove_dir_all( & image) ) ;
285286}
286287
288+ /// Creates the `rust-src` installer component and the plain source tarball
289+ pub fn rust_src ( build : & Build ) {
290+ println ! ( "Dist src" ) ;
291+ let plain_name = format ! ( "rustc-{}-src" , package_vers( build) ) ;
292+ let name = format ! ( "rust-src-{}" , package_vers( build) ) ;
293+ let image = tmpdir ( build) . join ( format ! ( "{}-image" , name) ) ;
294+ let _ = fs:: remove_dir_all ( & image) ;
295+
296+ let dst = image. join ( "lib/rustlib/src" ) ;
297+ let dst_src = dst. join ( "rust" ) ;
298+ let plain_dst_src = dst. join ( & plain_name) ;
299+ t ! ( fs:: create_dir_all( & dst_src) ) ;
300+
301+ // This is the set of root paths which will become part of the source package
302+ let src_files = [
303+ "COPYRIGHT" ,
304+ "LICENSE-APACHE" ,
305+ "LICENSE-MIT" ,
306+ "CONTRIBUTING.md" ,
307+ "README.md" ,
308+ "RELEASES.md" ,
309+ "configure" ,
310+ "Makefile.in"
311+ ] ;
312+ let src_dirs = [
313+ "man" ,
314+ "src" ,
315+ "mk"
316+ ] ;
317+
318+ // Exclude paths matching these wildcard expressions
319+ let excludes = [
320+ // exclude-vcs
321+ "CVS" , "RCS" , "SCCS" , ".git" , ".gitignore" , ".gitmodules" , ".gitattributes" , ".cvsignore" ,
322+ ".svn" , ".arch-ids" , "{arch}" , "=RELEASE-ID" , "=meta-update" , "=update" , ".bzr" ,
323+ ".bzrignore" , ".bzrtags" , ".hg" , ".hgignore" , ".hgrags" , "_darcs" ,
324+ // extensions
325+ "*~" , "*.pyc" ,
326+ // misc
327+ "llvm/test/*/*.ll" ,
328+ "llvm/test/*/*.td" ,
329+ "llvm/test/*/*.s" ,
330+ "llvm/test/*/*/*.ll" ,
331+ "llvm/test/*/*/*.td" ,
332+ "llvm/test/*/*/*.s"
333+ ] ;
334+
335+ // Construct a set of regexes for efficiently testing whether paths match one of the above
336+ // expressions.
337+ let regex_set = t ! ( RegexSet :: new(
338+ // This converts a wildcard expression to a regex
339+ excludes. iter( ) . map( |& s| {
340+ // Prefix ensures that matching starts on a path separator boundary
341+ r"^(.*[\\/])?" . to_owned( ) + (
342+ // Escape the expression to produce a regex matching exactly that string
343+ & quote( s)
344+ // Replace slashes with a pattern matching either forward or backslash
345+ . replace( r"/" , r"[\\/]" )
346+ // Replace wildcards with a pattern matching a single path segment, ie. containing
347+ // no slashes.
348+ . replace( r"\*" , r"[^\\/]*" )
349+ // Suffix anchors to the end of the path
350+ ) + "$"
351+ } )
352+ ) ) ;
353+
354+ // Create a filter which skips files which match the regex set or contain invalid unicode
355+ let filter_fn = move |path : & Path | {
356+ if let Some ( path) = path. to_str ( ) {
357+ !regex_set. is_match ( path)
358+ } else {
359+ false
360+ }
361+ } ;
362+
363+ // Copy the directories using our filter
364+ for item in & src_dirs {
365+ let dst = & dst_src. join ( item) ;
366+ t ! ( fs:: create_dir( dst) ) ;
367+ cp_filtered ( & build. src . join ( item) , dst, & filter_fn) ;
368+ }
369+ // Copy the files normally
370+ for item in & src_files {
371+ copy ( & build. src . join ( item) , & dst_src. join ( item) ) ;
372+ }
373+
374+ // Create source tarball in rust-installer format
375+ let mut cmd = Command :: new ( "sh" ) ;
376+ cmd. arg ( sanitize_sh ( & build. src . join ( "src/rust-installer/gen-installer.sh" ) ) )
377+ . arg ( "--product-name=Rust" )
378+ . arg ( "--rel-manifest-dir=rustlib" )
379+ . arg ( "--success-message=Awesome-Source." )
380+ . arg ( format ! ( "--image-dir={}" , sanitize_sh( & image) ) )
381+ . arg ( format ! ( "--work-dir={}" , sanitize_sh( & tmpdir( build) ) ) )
382+ . arg ( format ! ( "--output-dir={}" , sanitize_sh( & distdir( build) ) ) )
383+ . arg ( format ! ( "--package-name={}" , name) )
384+ . arg ( "--component-name=rust-src" )
385+ . arg ( "--legacy-manifest-dirs=rustlib,cargo" ) ;
386+ build. run ( & mut cmd) ;
387+
388+ // Rename directory, so that root folder of tarball has the correct name
389+ t ! ( fs:: rename( & dst_src, & plain_dst_src) ) ;
390+
391+ // Create plain source tarball
392+ let mut cmd = Command :: new ( "tar" ) ;
393+ cmd. arg ( "-czf" ) . arg ( sanitize_sh ( & distdir ( build) . join ( & format ! ( "{}.tar.gz" , plain_name) ) ) )
394+ . arg ( & plain_name)
395+ . current_dir ( & dst) ;
396+ build. run ( & mut cmd) ;
397+
398+ t ! ( fs:: remove_dir_all( & image) ) ;
399+ }
400+
287401fn install ( src : & Path , dstdir : & Path , perms : u32 ) {
288402 let dst = dstdir. join ( src. file_name ( ) . unwrap ( ) ) ;
289403 t ! ( fs:: create_dir_all( dstdir) ) ;
0 commit comments