refactor: add dereference flag (#169)

- Add a `--dereference` flag to use with tar

fix https://github.com/appleboy/drone-scp/issues/112
This commit is contained in:
Bo-Yi Wu 2023-04-09 15:49:32 +08:00 committed by GitHub
parent cf09357b85
commit 6fd87e0460
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 116 additions and 52 deletions

View File

@ -264,6 +264,11 @@ func main() {
Usage: "use --unlink-first flag with tar",
EnvVars: []string{"PLUGIN_UNLINK_FIRST", "SCP_UNLINK_FIRST", "INPUT_UNLINK_FIRST"},
},
&cli.BoolFlag{
Name: "tar.dereference",
Usage: "use --dereference flag with tar",
EnvVars: []string{"PLUGIN_TAR_DEREFERENCE", "SCP_TAR_DEREFERENCE", "INPUT_TAR_DEREFERENCE"},
},
}
// Override a template
@ -342,6 +347,7 @@ func run(c *cli.Context) error {
UnlinkFirst: c.Bool("unlink.first"),
Ciphers: c.StringSlice("ciphers"),
UseInsecureCipher: c.Bool("useInsecureCipher"),
TarDereference: c.Bool("tar.dereference"),
Proxy: easyssh.DefaultConfig{
Key: c.String("proxy.ssh-key"),
Passphrase: c.String("proxy.ssh-passphrase"),

View File

@ -66,6 +66,7 @@ type (
UnlinkFirst bool
Ciphers []string
UseInsecureCipher bool
TarDereference bool
}
// Plugin values.
@ -91,7 +92,7 @@ func globList(paths []string) fileList {
for _, pattern := range paths {
ignore := false
pattern = strings.Trim(pattern, " ")
pattern = strings.TrimSpace(pattern)
if string(pattern[0]) == "!" {
pattern = pattern[1:]
ignore = true
@ -112,21 +113,6 @@ func globList(paths []string) fileList {
return list
}
func buildArgs(tar string, files fileList) []string {
args := []string{}
if len(files.Ignore) > 0 {
for _, v := range files.Ignore {
args = append(args, "--exclude")
args = append(args, v)
}
}
args = append(args, "-zcf")
args = append(args, getRealPath(tar))
args = append(args, files.Source...)
return args
}
func (p Plugin) log(host string, message ...interface{}) {
if count := len(p.Config.Host); count == 1 {
fmt.Printf("%s", fmt.Sprintln(message...))
@ -204,7 +190,28 @@ type fileList struct {
Source []string
}
func (p *Plugin) buildArgs(target string) []string {
func (p *Plugin) buildTarArgs(src string) []string {
files := globList(trimValues(p.Config.Source))
args := []string{}
if len(files.Ignore) > 0 {
for _, v := range files.Ignore {
args = append(args, "--exclude")
args = append(args, v)
}
}
if p.Config.TarDereference {
args = append(args, "--dereference")
}
args = append(args, "-zcf")
args = append(args, getRealPath(src))
args = append(args, files.Source...)
return args
}
func (p *Plugin) buildUnTarArgs(target string) []string {
args := []string{}
args = append(args,
@ -253,16 +260,15 @@ func (p *Plugin) Exec() error {
return errMissingSourceOrTarget
}
files := globList(trimValues(p.Config.Source))
p.DestFile = fmt.Sprintf("%s.tar.gz", random.String(10))
// create a temporary file for the archive
dir := os.TempDir()
tar := filepath.Join(dir, p.DestFile)
src := filepath.Join(dir, p.DestFile)
// run archive command
fmt.Println("tar all files into " + tar)
args := buildArgs(tar, files)
fmt.Println("tar all files into " + src)
args := p.buildTarArgs(src)
cmd := exec.Command(p.Config.TarExec, args...)
if p.Config.Debug {
fmt.Println("$", strings.Join(cmd.Args, " "))
@ -324,7 +330,7 @@ func (p *Plugin) Exec() error {
// Call Scp method with file you want to upload to remote server.
p.log(host, "scp file to server.")
err = ssh.Scp(tar, p.DestFile)
err = ssh.Scp(src, p.DestFile)
if err != nil {
errChannel <- copyError{host, err.Error()}
return
@ -356,7 +362,7 @@ func (p *Plugin) Exec() error {
// untar file
p.log(host, "untar file", p.DestFile)
commamd := strings.Join(p.buildArgs(target), " ")
commamd := strings.Join(p.buildUnTarArgs(target), " ")
if p.Config.Debug {
fmt.Println("$", commamd)
}

View File

@ -572,25 +572,6 @@ func TestGlobList(t *testing.T) {
assert.Equal(t, expectIgnores, result.Ignore)
}
func TestBuildArgs(t *testing.T) {
list := fileList{
Source: []string{"tests/a.txt", "tests/b.txt", "tests/c.txt"},
Ignore: []string{"tests/a.txt", "tests/b.txt"},
}
result := buildArgs("test.tar.gz", list)
expects := []string{"--exclude", "tests/a.txt", "--exclude", "tests/b.txt", "-zcf", "test.tar.gz", "tests/a.txt", "tests/b.txt", "tests/c.txt"}
assert.Equal(t, expects, result)
list = fileList{
Source: []string{"tests/a.txt", "tests/b.txt"},
}
result = buildArgs("test.tar.gz", list)
expects = []string{"-zcf", "test.tar.gz", "tests/a.txt", "tests/b.txt"}
assert.Equal(t, expects, result)
}
func TestRemoveDestFile(t *testing.T) {
ssh := &easyssh.MakeConfig{
Server: "localhost",
@ -629,7 +610,7 @@ func TestRemoveDestFile(t *testing.T) {
assert.Error(t, err)
}
func TestPlugin_buildArgs(t *testing.T) {
func TestPlugin_buildUnTarArgs(t *testing.T) {
type fields struct {
Repo Repo
Build Build
@ -653,12 +634,12 @@ func TestPlugin_buildArgs(t *testing.T) {
UnlinkFirst: false,
TarExec: "tar",
},
DestFile: "foo.tar",
DestFile: "foo.tar.gz",
},
args: args{
target: "foo",
},
want: []string{"tar", "-xf", "foo.tar", "-C", "foo"},
want: []string{"tar", "-zxf", "foo.tar.gz", "-C", "foo"},
},
{
name: "strip components",
@ -669,12 +650,12 @@ func TestPlugin_buildArgs(t *testing.T) {
TarExec: "tar",
StripComponents: 2,
},
DestFile: "foo.tar",
DestFile: "foo.tar.gz",
},
args: args{
target: "foo",
},
want: []string{"tar", "-xf", "foo.tar", "--strip-components", "2", "-C", "foo"},
want: []string{"tar", "-zxf", "foo.tar.gz", "--strip-components", "2", "-C", "foo"},
},
{
name: "overwrite",
@ -685,12 +666,12 @@ func TestPlugin_buildArgs(t *testing.T) {
Overwrite: true,
UnlinkFirst: false,
},
DestFile: "foo.tar",
DestFile: "foo.tar.gz",
},
args: args{
target: "foo",
},
want: []string{"tar", "-xf", "foo.tar", "--strip-components", "2", "--overwrite", "-C", "foo"},
want: []string{"tar", "-zxf", "foo.tar.gz", "--strip-components", "2", "--overwrite", "-C", "foo"},
},
{
name: "unlink first",
@ -701,12 +682,12 @@ func TestPlugin_buildArgs(t *testing.T) {
Overwrite: true,
UnlinkFirst: true,
},
DestFile: "foo.tar",
DestFile: "foo.tar.gz",
},
args: args{
target: "foo",
},
want: []string{"tar", "-xf", "foo.tar", "--strip-components", "2", "--overwrite", "--unlink-first", "-C", "foo"},
want: []string{"tar", "-zxf", "foo.tar.gz", "--strip-components", "2", "--overwrite", "--unlink-first", "-C", "foo"},
},
}
for _, tt := range tests {
@ -717,9 +698,80 @@ func TestPlugin_buildArgs(t *testing.T) {
Config: tt.fields.Config,
DestFile: tt.fields.DestFile,
}
if got := p.buildArgs(tt.args.target); !reflect.DeepEqual(got, tt.want) {
if got := p.buildUnTarArgs(tt.args.target); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Plugin.buildArgs() = %v, want %v", got, tt.want)
}
})
}
}
func TestPlugin_buildTarArgs(t *testing.T) {
type fields struct {
Config Config
}
type args struct {
src string
}
tests := []struct {
name string
fields fields
args args
want []string
}{
{
name: "default command",
fields: fields{
Config: Config{
TarExec: "tar",
},
},
args: args{
src: "foo.tar.gz",
},
want: []string{"-zcf", "foo.tar.gz"},
},
{
name: "ignore list",
fields: fields{
Config: Config{
TarExec: "tar",
Source: []string{
"tests/*.txt",
"!tests/a.txt",
},
},
},
args: args{
src: "foo.tar.gz",
},
want: []string{"--exclude", "tests/a.txt", "-zcf", "foo.tar.gz", "tests/a.txt", "tests/b.txt"},
},
{
name: "dereference flag",
fields: fields{
Config: Config{
TarExec: "tar",
TarDereference: true,
Source: []string{
"tests/*.txt",
"!tests/a.txt",
},
},
},
args: args{
src: "foo.tar.gz",
},
want: []string{"--exclude", "tests/a.txt", "--dereference", "-zcf", "foo.tar.gz", "tests/a.txt", "tests/b.txt"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p := &Plugin{
Config: tt.fields.Config,
}
if got := p.buildTarArgs(tt.args.src); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Plugin.buildTarArgs() = %v, want %v", got, tt.want)
}
})
}
}