Compare commits

..

4 Commits

Author SHA1 Message Date
Bo-Yi.Wu 0745e13d39 test: refactor plugin_test.go file and optimize code
- Remove the `TestSetPasswordAndKey` function from `plugin_test.go`

Signed-off-by: Bo-Yi.Wu <appleboy.tw@gmail.com>
2023-04-09 17:06:03 +08:00
Bo-Yi.Wu f1301199ca fix: refactor error handling and panic statements
- Remove error message for setting password and key at the same time
- Replace `errMissingHost` error check with a panic statement

ref: https://github.com/appleboy/scp-action/issues/86

Signed-off-by: Bo-Yi.Wu <appleboy.tw@gmail.com>
2023-04-09 17:03:48 +08:00
Bo-Yi Wu 6fd87e0460 refactor: add dereference flag (#169)
- Add a `--dereference` flag to use with tar

fix https://github.com/appleboy/drone-scp/issues/112
2023-04-09 15:49:32 +08:00
Bo-Yi.Wu cf09357b85 build: refactor buildArgs function argument
- Change argument from `-xf` to `-zxf` in `buildArgs` function

Signed-off-by: Bo-Yi.Wu <appleboy.tw@gmail.com>
2023-04-09 13:39:39 +08:00
3 changed files with 116 additions and 106 deletions
+6
View File
@@ -264,6 +264,11 @@ func main() {
Usage: "use --unlink-first flag with tar", Usage: "use --unlink-first flag with tar",
EnvVars: []string{"PLUGIN_UNLINK_FIRST", "SCP_UNLINK_FIRST", "INPUT_UNLINK_FIRST"}, 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 // Override a template
@@ -342,6 +347,7 @@ func run(c *cli.Context) error {
UnlinkFirst: c.Bool("unlink.first"), UnlinkFirst: c.Bool("unlink.first"),
Ciphers: c.StringSlice("ciphers"), Ciphers: c.StringSlice("ciphers"),
UseInsecureCipher: c.Bool("useInsecureCipher"), UseInsecureCipher: c.Bool("useInsecureCipher"),
TarDereference: c.Bool("tar.dereference"),
Proxy: easyssh.DefaultConfig{ Proxy: easyssh.DefaultConfig{
Key: c.String("proxy.ssh-key"), Key: c.String("proxy.ssh-key"),
Passphrase: c.String("proxy.ssh-passphrase"), Passphrase: c.String("proxy.ssh-passphrase"),
+35 -34
View File
@@ -19,7 +19,6 @@ import (
var ( var (
errMissingHost = errors.New("Error: missing server host") errMissingHost = errors.New("Error: missing server host")
errMissingPasswordOrKey = errors.New("Error: can't connect without a private SSH key or password") errMissingPasswordOrKey = errors.New("Error: can't connect without a private SSH key or password")
errSetPasswordandKey = errors.New("can't set password and key at the same time")
errMissingSourceOrTarget = errors.New("missing source or target config") errMissingSourceOrTarget = errors.New("missing source or target config")
) )
@@ -66,6 +65,7 @@ type (
UnlinkFirst bool UnlinkFirst bool
Ciphers []string Ciphers []string
UseInsecureCipher bool UseInsecureCipher bool
TarDereference bool
} }
// Plugin values. // Plugin values.
@@ -91,7 +91,7 @@ func globList(paths []string) fileList {
for _, pattern := range paths { for _, pattern := range paths {
ignore := false ignore := false
pattern = strings.Trim(pattern, " ") pattern = strings.TrimSpace(pattern)
if string(pattern[0]) == "!" { if string(pattern[0]) == "!" {
pattern = pattern[1:] pattern = pattern[1:]
ignore = true ignore = true
@@ -112,21 +112,6 @@ func globList(paths []string) fileList {
return list 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{}) { func (p Plugin) log(host string, message ...interface{}) {
if count := len(p.Config.Host); count == 1 { if count := len(p.Config.Host); count == 1 {
fmt.Printf("%s", fmt.Sprintln(message...)) fmt.Printf("%s", fmt.Sprintln(message...))
@@ -204,12 +189,33 @@ type fileList struct {
Source []string 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 := []string{}
args = append(args, args = append(args,
p.Config.TarExec, p.Config.TarExec,
"-xf", "-zxf",
p.DestFile, p.DestFile,
) )
@@ -236,33 +242,28 @@ func (p *Plugin) buildArgs(target string) []string {
// Exec executes the plugin. // Exec executes the plugin.
func (p *Plugin) Exec() error { func (p *Plugin) Exec() error {
hosts := trimValues(p.Config.Host)
if len(hosts) == 0 {
return errMissingHost
}
if len(p.Config.Key) == 0 && len(p.Config.Password) == 0 && len(p.Config.KeyPath) == 0 { if len(p.Config.Key) == 0 && len(p.Config.Password) == 0 && len(p.Config.KeyPath) == 0 {
return errMissingPasswordOrKey return errMissingPasswordOrKey
} }
if len(p.Config.Key) != 0 && len(p.Config.Password) != 0 {
return errSetPasswordandKey
}
if len(p.Config.Source) == 0 || len(p.Config.Target) == 0 { if len(p.Config.Source) == 0 || len(p.Config.Target) == 0 {
return errMissingSourceOrTarget return errMissingSourceOrTarget
} }
files := globList(trimValues(p.Config.Source)) hosts := trimValues(p.Config.Host)
if len(hosts) == 0 {
return errMissingHost
}
p.DestFile = fmt.Sprintf("%s.tar.gz", random.String(10)) p.DestFile = fmt.Sprintf("%s.tar.gz", random.String(10))
// create a temporary file for the archive // create a temporary file for the archive
dir := os.TempDir() dir := os.TempDir()
tar := filepath.Join(dir, p.DestFile) src := filepath.Join(dir, p.DestFile)
// run archive command // run archive command
fmt.Println("tar all files into " + tar) fmt.Println("tar all files into " + src)
args := buildArgs(tar, files) args := p.buildTarArgs(src)
cmd := exec.Command(p.Config.TarExec, args...) cmd := exec.Command(p.Config.TarExec, args...)
if p.Config.Debug { if p.Config.Debug {
fmt.Println("$", strings.Join(cmd.Args, " ")) fmt.Println("$", strings.Join(cmd.Args, " "))
@@ -324,7 +325,7 @@ func (p *Plugin) Exec() error {
// Call Scp method with file you want to upload to remote server. // Call Scp method with file you want to upload to remote server.
p.log(host, "scp file to server.") p.log(host, "scp file to server.")
err = ssh.Scp(tar, p.DestFile) err = ssh.Scp(src, p.DestFile)
if err != nil { if err != nil {
errChannel <- copyError{host, err.Error()} errChannel <- copyError{host, err.Error()}
return return
@@ -356,7 +357,7 @@ func (p *Plugin) Exec() error {
// untar file // untar file
p.log(host, "untar file", p.DestFile) p.log(host, "untar file", p.DestFile)
commamd := strings.Join(p.buildArgs(target), " ") commamd := strings.Join(p.buildUnTarArgs(target), " ")
if p.Config.Debug { if p.Config.Debug {
fmt.Println("$", commamd) fmt.Println("$", commamd)
} }
+75 -72
View File
@@ -51,23 +51,6 @@ func TestMissingSourceConfig(t *testing.T) {
assert.NotNil(t, err) assert.NotNil(t, err)
} }
func TestSetPasswordAndKey(t *testing.T) {
plugin := Plugin{
Config: Config{
Host: []string{"example.com"},
Username: "ubuntu",
Port: "443",
Password: "1234",
Key: "test",
},
}
err := plugin.Exec()
assert.NotNil(t, err)
assert.Equal(t, errSetPasswordandKey, err)
}
func TestTrimElement(t *testing.T) { func TestTrimElement(t *testing.T) {
var input, result []string var input, result []string
@@ -572,25 +555,6 @@ func TestGlobList(t *testing.T) {
assert.Equal(t, expectIgnores, result.Ignore) 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) { func TestRemoveDestFile(t *testing.T) {
ssh := &easyssh.MakeConfig{ ssh := &easyssh.MakeConfig{
Server: "localhost", Server: "localhost",
@@ -629,7 +593,7 @@ func TestRemoveDestFile(t *testing.T) {
assert.Error(t, err) assert.Error(t, err)
} }
func TestPlugin_buildArgs(t *testing.T) { func TestPlugin_buildUnTarArgs(t *testing.T) {
type fields struct { type fields struct {
Repo Repo Repo Repo
Build Build Build Build
@@ -653,12 +617,12 @@ func TestPlugin_buildArgs(t *testing.T) {
UnlinkFirst: false, UnlinkFirst: false,
TarExec: "tar", TarExec: "tar",
}, },
DestFile: "foo.tar", DestFile: "foo.tar.gz",
}, },
args: args{ args: args{
target: "foo", target: "foo",
}, },
want: []string{"tar", "-xf", "foo.tar", "-C", "foo"}, want: []string{"tar", "-zxf", "foo.tar.gz", "-C", "foo"},
}, },
{ {
name: "strip components", name: "strip components",
@@ -669,12 +633,12 @@ func TestPlugin_buildArgs(t *testing.T) {
TarExec: "tar", TarExec: "tar",
StripComponents: 2, StripComponents: 2,
}, },
DestFile: "foo.tar", DestFile: "foo.tar.gz",
}, },
args: args{ args: args{
target: "foo", 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", name: "overwrite",
@@ -685,12 +649,12 @@ func TestPlugin_buildArgs(t *testing.T) {
Overwrite: true, Overwrite: true,
UnlinkFirst: false, UnlinkFirst: false,
}, },
DestFile: "foo.tar", DestFile: "foo.tar.gz",
}, },
args: args{ args: args{
target: "foo", 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", name: "unlink first",
@@ -701,12 +665,12 @@ func TestPlugin_buildArgs(t *testing.T) {
Overwrite: true, Overwrite: true,
UnlinkFirst: true, UnlinkFirst: true,
}, },
DestFile: "foo.tar", DestFile: "foo.tar.gz",
}, },
args: args{ args: args{
target: "foo", 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 { for _, tt := range tests {
@@ -717,41 +681,80 @@ func TestPlugin_buildArgs(t *testing.T) {
Config: tt.fields.Config, Config: tt.fields.Config,
DestFile: tt.fields.DestFile, 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) t.Errorf("Plugin.buildArgs() = %v, want %v", got, tt.want)
} }
}) })
} }
} }
func TestCheckTargetFolderExist(t *testing.T) { func TestPlugin_buildTarArgs(t *testing.T) {
if os.Getenv("SSH_AUTH_SOCK") != "" { type fields struct {
if err := exec.Command("eval", "`ssh-agent -k`").Run(); err != nil { Config Config
t.Fatalf("exec: %v", err)
}
} }
type args struct {
u, err := user.Lookup("drone-scp") src string
if err != nil {
t.Fatalf("Lookup: %v", err)
} }
tests := []struct {
plugin := Plugin{ name string
Config: Config{ fields fields
Host: []string{"localhost"}, args args
Username: "drone-scp", want []string
Port: "22", }{
KeyPath: "tests/.ssh/id_rsa", {
Source: []string{"tests/global/*"}, name: "default command",
Target: []string{filepath.Join(u.HomeDir, "__test__")}, fields: fields{
CommandTimeout: 60 * time.Second, Config: Config{
TarExec: "tar", 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 {
err = plugin.Exec() t.Run(tt.name, func(t *testing.T) {
assert.Nil(t, err) p := &Plugin{
Config: tt.fields.Config,
err = plugin.Exec() }
assert.Nil(t, err) if got := p.buildTarArgs(tt.args.src); !reflect.DeepEqual(got, tt.want) {
t.Errorf("Plugin.buildTarArgs() = %v, want %v", got, tt.want)
}
})
}
} }