Add a --symlinks argument to soong_zip
Add a --symlinks argument that defaults to true to soong_zip. Passing --symlinks=false will cause it to follow symlinks instead of storing them in the zip file. Relands I4deb98daa9d4ba9f94e3d7670c117fe00381d2ba with tests. Bug: 112843624 Test: glob_test.go Test: zip_test.go Test: m checkbuild Change-Id: I0eff9c1f2dba79e873fda381ff585df55d5aaaad
This commit is contained in:
@@ -137,6 +137,8 @@ func main() {
|
|||||||
emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
|
emulateJar := flags.Bool("jar", false, "modify the resultant .zip to emulate the output of 'jar'")
|
||||||
writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
|
writeIfChanged := flags.Bool("write_if_changed", false, "only update resultant .zip if it has changed")
|
||||||
|
|
||||||
|
symlinks := flags.Bool("symlinks", true, "store symbolic links in zip instead of following them")
|
||||||
|
|
||||||
parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
|
parallelJobs := flags.Int("parallel", runtime.NumCPU(), "number of parallel threads to use")
|
||||||
cpuProfile := flags.String("cpuprofile", "", "write cpu profile to file")
|
cpuProfile := flags.String("cpuprofile", "", "write cpu profile to file")
|
||||||
traceFile := flags.String("trace", "", "write trace to file")
|
traceFile := flags.String("trace", "", "write trace to file")
|
||||||
@@ -197,9 +199,10 @@ func main() {
|
|||||||
NumParallelJobs: *parallelJobs,
|
NumParallelJobs: *parallelJobs,
|
||||||
NonDeflatedFiles: nonDeflatedFiles,
|
NonDeflatedFiles: nonDeflatedFiles,
|
||||||
WriteIfChanged: *writeIfChanged,
|
WriteIfChanged: *writeIfChanged,
|
||||||
|
StoreSymlinks: *symlinks,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stderr, err.Error())
|
fmt.Fprintln(os.Stderr, "error:", err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
zip/zip.go
36
zip/zip.go
@@ -188,6 +188,8 @@ type ZipWriter struct {
|
|||||||
compressorPool sync.Pool
|
compressorPool sync.Pool
|
||||||
compLevel int
|
compLevel int
|
||||||
|
|
||||||
|
followSymlinks pathtools.ShouldFollowSymlinks
|
||||||
|
|
||||||
fs pathtools.FileSystem
|
fs pathtools.FileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +214,9 @@ type ZipArgs struct {
|
|||||||
NumParallelJobs int
|
NumParallelJobs int
|
||||||
NonDeflatedFiles map[string]bool
|
NonDeflatedFiles map[string]bool
|
||||||
WriteIfChanged bool
|
WriteIfChanged bool
|
||||||
Filesystem pathtools.FileSystem
|
StoreSymlinks bool
|
||||||
|
|
||||||
|
Filesystem pathtools.FileSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
const NOQUOTE = '\x00'
|
const NOQUOTE = '\x00'
|
||||||
@@ -263,13 +267,17 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
|||||||
args.AddDirectoryEntriesToZip = true
|
args.AddDirectoryEntriesToZip = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Have Glob follow symlinks if they are not being stored as symlinks in the zip file.
|
||||||
|
followSymlinks := pathtools.ShouldFollowSymlinks(!args.StoreSymlinks)
|
||||||
|
|
||||||
z := &ZipWriter{
|
z := &ZipWriter{
|
||||||
time: jar.DefaultTime,
|
time: jar.DefaultTime,
|
||||||
createdDirs: make(map[string]string),
|
createdDirs: make(map[string]string),
|
||||||
createdFiles: make(map[string]string),
|
createdFiles: make(map[string]string),
|
||||||
directories: args.AddDirectoryEntriesToZip,
|
directories: args.AddDirectoryEntriesToZip,
|
||||||
compLevel: args.CompressionLevel,
|
compLevel: args.CompressionLevel,
|
||||||
fs: args.Filesystem,
|
followSymlinks: followSymlinks,
|
||||||
|
fs: args.Filesystem,
|
||||||
}
|
}
|
||||||
|
|
||||||
if z.fs == nil {
|
if z.fs == nil {
|
||||||
@@ -288,7 +296,7 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
globbed, _, err := z.fs.Glob(s, nil, pathtools.DontFollowSymlinks)
|
globbed, _, err := z.fs.Glob(s, nil, followSymlinks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -317,7 +325,7 @@ func ZipTo(args ZipArgs, w io.Writer) error {
|
|||||||
Err: syscall.ENOTDIR,
|
Err: syscall.ENOTDIR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, pathtools.DontFollowSymlinks)
|
globbed, _, err := z.fs.Glob(filepath.Join(fa.GlobDir, "**/*"), nil, followSymlinks)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -559,7 +567,15 @@ func (z *ZipWriter) addFile(dest, src string, method uint16, emulateJar bool) er
|
|||||||
var fileSize int64
|
var fileSize int64
|
||||||
var executable bool
|
var executable bool
|
||||||
|
|
||||||
if s, err := z.fs.Lstat(src); err != nil {
|
var s os.FileInfo
|
||||||
|
var err error
|
||||||
|
if z.followSymlinks {
|
||||||
|
s, err = z.fs.Stat(src)
|
||||||
|
} else {
|
||||||
|
s, err = z.fs.Lstat(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if s.IsDir() {
|
} else if s.IsDir() {
|
||||||
if z.directories {
|
if z.directories {
|
||||||
|
@@ -105,6 +105,7 @@ func TestZip(t *testing.T) {
|
|||||||
nonDeflatedFiles map[string]bool
|
nonDeflatedFiles map[string]bool
|
||||||
dirEntries bool
|
dirEntries bool
|
||||||
manifest string
|
manifest string
|
||||||
|
storeSymlinks bool
|
||||||
|
|
||||||
files []zip.FileHeader
|
files []zip.FileHeader
|
||||||
err error
|
err error
|
||||||
@@ -135,6 +136,7 @@ func TestZip(t *testing.T) {
|
|||||||
SourcePrefixToStrip("a").
|
SourcePrefixToStrip("a").
|
||||||
File("a/**/*"),
|
File("a/**/*"),
|
||||||
compressionLevel: 9,
|
compressionLevel: 9,
|
||||||
|
storeSymlinks: true,
|
||||||
|
|
||||||
files: []zip.FileHeader{
|
files: []zip.FileHeader{
|
||||||
fh("a/a", fileA, zip.Deflate),
|
fh("a/a", fileA, zip.Deflate),
|
||||||
@@ -149,6 +151,7 @@ func TestZip(t *testing.T) {
|
|||||||
SourcePrefixToStrip("a").
|
SourcePrefixToStrip("a").
|
||||||
Dir("a"),
|
Dir("a"),
|
||||||
compressionLevel: 9,
|
compressionLevel: 9,
|
||||||
|
storeSymlinks: true,
|
||||||
|
|
||||||
files: []zip.FileHeader{
|
files: []zip.FileHeader{
|
||||||
fh("a/a", fileA, zip.Deflate),
|
fh("a/a", fileA, zip.Deflate),
|
||||||
@@ -179,6 +182,7 @@ func TestZip(t *testing.T) {
|
|||||||
File("a/a/c").
|
File("a/a/c").
|
||||||
File("a/a/d"),
|
File("a/a/d"),
|
||||||
compressionLevel: 9,
|
compressionLevel: 9,
|
||||||
|
storeSymlinks: true,
|
||||||
|
|
||||||
files: []zip.FileHeader{
|
files: []zip.FileHeader{
|
||||||
fh("a/a/a", fileA, zip.Deflate),
|
fh("a/a/a", fileA, zip.Deflate),
|
||||||
@@ -187,6 +191,23 @@ func TestZip(t *testing.T) {
|
|||||||
fhLink("a/a/d", "b"),
|
fhLink("a/a/d", "b"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "follow symlinks",
|
||||||
|
args: fileArgsBuilder().
|
||||||
|
File("a/a/a").
|
||||||
|
File("a/a/b").
|
||||||
|
File("a/a/c").
|
||||||
|
File("a/a/d"),
|
||||||
|
compressionLevel: 9,
|
||||||
|
storeSymlinks: false,
|
||||||
|
|
||||||
|
files: []zip.FileHeader{
|
||||||
|
fh("a/a/a", fileA, zip.Deflate),
|
||||||
|
fh("a/a/b", fileB, zip.Deflate),
|
||||||
|
fh("a/a/c", fileC, zip.Deflate),
|
||||||
|
fh("a/a/d", fileB, zip.Deflate),
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "list",
|
name: "list",
|
||||||
args: fileArgsBuilder().
|
args: fileArgsBuilder().
|
||||||
@@ -359,6 +380,7 @@ func TestZip(t *testing.T) {
|
|||||||
args.AddDirectoryEntriesToZip = test.dirEntries
|
args.AddDirectoryEntriesToZip = test.dirEntries
|
||||||
args.NonDeflatedFiles = test.nonDeflatedFiles
|
args.NonDeflatedFiles = test.nonDeflatedFiles
|
||||||
args.ManifestSourcePath = test.manifest
|
args.ManifestSourcePath = test.manifest
|
||||||
|
args.StoreSymlinks = test.storeSymlinks
|
||||||
args.Filesystem = mockFs
|
args.Filesystem = mockFs
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
Reference in New Issue
Block a user