Skip to content

Commit 701da04

Browse files
committed
Merge branch 'release0.4.0'
2 parents 257a1d6 + 31079ec commit 701da04

File tree

10 files changed

+372
-11
lines changed

10 files changed

+372
-11
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
### [0.4.0](https://github.com/befovy/fvm/compare/v0.3.1...v0.4.0) (2020-03-07)
6+
7+
* add import sub command, import flutter outside of fvm into fvm ([2161286](https://github.com/befovy/fvm/commit/21612865b64685165f1c8c33158dd928f4aebb38))
8+
59
### [0.3.1](https://github.com/befovy/fvm/compare/v0.3.0...v0.3.1) (2020-02-18)
610

711
* fix magicfile test [#1](https://github.com/befovy/fvm/issues/1) ([7bdb743](https://github.com/befovy/fvm/commit/7bdb7434c844f5289760bc8620da8dbd42dd0266))

README.md

+12
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ FVM gives you the ability to install many Flutter **releases** or **channels**.
5656

5757
Use `master` to install the Master channel and `v1.8.0` to install the release.
5858

59+
### Import Flutter from previous installation
60+
61+
FVM has subcommand `import` which can import your previous installed flutter into fvm.
62+
63+
```bash
64+
> fvm import <name>
65+
```
66+
67+
If you have installed master channel flutter, just use `fvm import master`.
68+
Or if you have installed a special derived flutter, just use any name you want to import this flutter.
69+
You can use a name from you company, or any other you want. `fvm import xianyu`
70+
5971
### Use a SDK Version
6072

6173
You can use the installed Flutter SDK versions for your computer user account globally. To do that just:

cmd/import.go

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
Copyright © 2020 befovy <[email protected]>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package cmd
18+
19+
import (
20+
"errors"
21+
"github.com/befovy/fvm/fvmgo"
22+
"github.com/spf13/cobra"
23+
"os"
24+
"path/filepath"
25+
"strings"
26+
)
27+
28+
var cop bool
29+
var pos string
30+
31+
func init() {
32+
importCommand.Flags().BoolVarP(&cop, "copy", "c", false, "copy files instead of move")
33+
importCommand.Flags().StringVar(&pos, "path", "", "special the installed flutter path to import")
34+
rootCmd.AddCommand(importCommand)
35+
}
36+
37+
var importCommand = &cobra.Command{
38+
Use: "import <name>",
39+
Short: "Import installed flutter into fvm",
40+
Long: "Import installed flutter into fvm.\n" +
41+
"If there are more than one flutter detected,\n" +
42+
"this sub command use the first one in path by default.\n" +
43+
"Or you can use flags --path to special the path of flutter",
44+
Args: func(cmd *cobra.Command, args []string) error {
45+
if len(args) == 0 {
46+
return errors.New("need to provide a channel or a version or other name as import name, you can use `master` `beta` or `alibaba` `baidu` etc.")
47+
}
48+
if len(args) > 1 {
49+
return errors.New("allows only one argument, the name to be imported as")
50+
}
51+
return nil
52+
},
53+
Run: func(cmd *cobra.Command, args []string) {
54+
dst := args[0]
55+
choices := fvmgo.FlutterListInstalledSdks()
56+
if len(choices) > 0 {
57+
for _, choice := range choices {
58+
if dst == choice {
59+
ins := fvmgo.YellowV("%s", dst)
60+
fvmgo.Errorf("fvm has already installed flutter with channel or version: %v", ins)
61+
return
62+
}
63+
}
64+
}
65+
66+
flutters := fvmgo.FlutterOutOfFvm(pos)
67+
var source string
68+
if flutters == nil || len(flutters) == 0 {
69+
fvmgo.Warnf("fvm did not detect any flutter outside of fvm")
70+
} else if len(flutters) > 1 {
71+
if len(pos) == 0 {
72+
fvmgo.Infof("There are %d flutters outside of fvm, you don't set flag --path, so fvm will import te first one", len(flutters))
73+
source = flutters[0]
74+
} else {
75+
var match string
76+
for _, f := range flutters {
77+
if strings.HasPrefix(f, pos) {
78+
fvmgo.Infof("match %s", f)
79+
if len(match) == 0 {
80+
match = f
81+
source = match
82+
} else if match != f {
83+
fvmgo.Warnf("More than one installed flutter match the path: %v. You should provide a more detailed path", pos)
84+
source = ""
85+
break
86+
}
87+
}
88+
}
89+
}
90+
} else {
91+
source = flutters[0]
92+
}
93+
94+
if len(source) > 0 {
95+
dst = filepath.Join(fvmgo.VersionsDir(), dst)
96+
source = filepath.Dir(filepath.Dir(source))
97+
fvmgo.Infof("%s will be imported into fvm", fvmgo.YellowV("%s", source))
98+
if cop {
99+
fvmgo.Infof("Copy all files from %v to %v, please wait seconds", source, dst)
100+
} else {
101+
fvmgo.Infof("Move all files from %v to %v, please wait seconds", source, dst)
102+
}
103+
err := fvmgo.CopyDir(source, dst)
104+
if err != nil {
105+
fvmgo.Errorf("Failed to copy files, %v", err)
106+
}
107+
if !cop {
108+
err = os.RemoveAll(source)
109+
if err != nil {
110+
fvmgo.Errorf("Failed to delete files, %v", err)
111+
}
112+
}
113+
}
114+
},
115+
}

cmd/install.go

+15
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,21 @@ var installCommand = &cobra.Command{
3939
return nil
4040
},
4141
Run: func(cmd *cobra.Command, args []string) {
42+
43+
flutters := fvmgo.FlutterOutOfFvm("")
44+
if flutters != nil && len(flutters) > 0 {
45+
fvmgo.Errorf("You have installed flutter outside of fvm")
46+
for _, f := range flutters {
47+
fvmgo.Warnf("--> %v", f)
48+
}
49+
ins := fvmgo.YellowV("fvm import")
50+
if len(flutters) == 1 {
51+
fvmgo.Errorf("To import this into fvm, use %v", ins)
52+
} else {
53+
fvmgo.Errorf("To import these into fvm, use %v", ins)
54+
}
55+
}
56+
4257
err := fvmgo.CheckIfGitExists()
4358
if err == nil {
4459
version := args[0]

cmd/list.go

+13
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,18 @@ var listCommand = &cobra.Command{
4747
fvmgo.Infof(c)
4848
}
4949
}
50+
flutters := fvmgo.FlutterOutOfFvm("")
51+
if flutters != nil && len(flutters) > 0 {
52+
fvmgo.Errorf("You have installed flutter outside of fvm")
53+
for _, f := range flutters {
54+
fvmgo.Warnf("--> %v", f)
55+
}
56+
ins := fvmgo.YellowV("fvm import")
57+
if len(flutters) == 1 {
58+
fvmgo.Errorf("To import this into fvm, use %v", ins)
59+
} else {
60+
fvmgo.Errorf("To import these into fvm, use %v", ins)
61+
}
62+
}
5063
},
5164
}

cmd/root.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ var rootCmd = &cobra.Command{
4949
Use: "fvm",
5050
Short: "Flutter Version Management",
5151
Long: "Flutter Version Management: A cli to manage Flutter SDK versions.",
52-
Version: "0.3.1",
52+
Version: "0.4.0",
5353
}
5454

5555
// Execute executes the rootCmd

cmd/use.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
var local bool
2525

2626
func init() {
27-
useCommand.Flags().BoolVar(&local, "local", false, "use SDK locally")
27+
useCommand.Flags().BoolVarP(&local, "local", "l", false, "use SDK locally")
2828
rootCmd.AddCommand(useCommand)
2929
}
3030

fvmgo/file.go

+117-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright © 2019 befovy <[email protected]>
2+
Copyright © 2019-2020 befovy <[email protected]>
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -16,8 +16,11 @@ limitations under the License.
1616
package fvmgo
1717

1818
import (
19+
"fmt"
20+
"io"
1921
"io/ioutil"
2022
"os"
23+
"path/filepath"
2124
)
2225

2326
// IsFileExists checks if a file exists and is not a directory
@@ -57,7 +60,117 @@ func IsSymlink(name string) bool {
5760
return (info.Mode() & os.ModeSymlink) != 0
5861
}
5962

60-
func IsNotFound(path string) bool {
61-
_, err := os.Lstat(path)
62-
return os.IsNotExist(err)
63+
func IsNotFound(name string) bool {
64+
_, err := os.Lstat(name)
65+
return err != nil
66+
}
67+
68+
func IsExecutable(name string) bool {
69+
info, err := os.Stat(name)
70+
if err != nil {
71+
return false
72+
}
73+
return !info.IsDir() && ((info.Mode() & 0111) != 0)
74+
}
75+
76+
// CopyFile copies the contents of the file named src to the file named
77+
// by dst. The file will be created if it does not already exist. If the
78+
// destination file exists, all it's contents will be replaced by the contents
79+
// of the source file. The file mode will be copied from the source and
80+
// the copied data is synced/flushed to stable storage.
81+
func CopyFile(src, dst string) (err error) {
82+
in, err := os.Open(src)
83+
if err != nil {
84+
return
85+
}
86+
defer in.Close()
87+
88+
out, err := os.Create(dst)
89+
if err != nil {
90+
return
91+
}
92+
defer func() {
93+
if e := out.Close(); e != nil {
94+
err = e
95+
}
96+
}()
97+
98+
_, err = io.Copy(out, in)
99+
if err != nil {
100+
return
101+
}
102+
103+
err = out.Sync()
104+
if err != nil {
105+
return
106+
}
107+
108+
si, err := os.Stat(src)
109+
if err != nil {
110+
return
111+
}
112+
err = os.Chmod(dst, si.Mode())
113+
if err != nil {
114+
return
115+
}
116+
117+
return
118+
}
119+
120+
// CopyDir recursively copies a directory tree, attempting to preserve permissions.
121+
// Source directory must exist, destination directory must *not* exist.
122+
// Symlinks are ignored and skipped.
123+
func CopyDir(src string, dst string) (err error) {
124+
src = filepath.Clean(src)
125+
dst = filepath.Clean(dst)
126+
127+
si, err := os.Stat(src)
128+
if err != nil {
129+
return err
130+
}
131+
if !si.IsDir() {
132+
return fmt.Errorf("source is not a directory")
133+
}
134+
135+
_, err = os.Stat(dst)
136+
if err != nil && !os.IsNotExist(err) {
137+
return
138+
}
139+
if err == nil {
140+
return fmt.Errorf("destination already exists")
141+
}
142+
143+
err = os.MkdirAll(dst, si.Mode())
144+
if err != nil {
145+
return
146+
}
147+
148+
entries, err := ioutil.ReadDir(src)
149+
if err != nil {
150+
return
151+
}
152+
153+
for _, entry := range entries {
154+
srcPath := filepath.Join(src, entry.Name())
155+
dstPath := filepath.Join(dst, entry.Name())
156+
157+
if entry.IsDir() {
158+
err = CopyDir(srcPath, dstPath)
159+
if err != nil {
160+
return
161+
}
162+
} else {
163+
// Skip symlinks.
164+
if entry.Mode()&os.ModeSymlink != 0 {
165+
continue
166+
}
167+
168+
err = CopyFile(srcPath, dstPath)
169+
if err != nil {
170+
return
171+
}
172+
}
173+
}
174+
175+
return
63176
}

fvmgo/file_test.go

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright © 2020 befovy <[email protected]>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package fvmgo
18+
19+
import (
20+
"runtime"
21+
"testing"
22+
)
23+
24+
func TestFileExist(t *testing.T) {
25+
if runtime.GOOS == "darwin" {
26+
if !IsFileExists("/bin/bash") {
27+
t.Fail()
28+
}
29+
if IsFileExists("/bin/helloworld") {
30+
t.Fail()
31+
}
32+
}
33+
}
34+
35+
func TestIsDirectory(t *testing.T) {
36+
if runtime.GOOS == "darwin" {
37+
if !IsDirectory("/bin") {
38+
t.Fail()
39+
}
40+
41+
if IsDirectory("bin/bash") {
42+
t.Fail()
43+
}
44+
}
45+
}
46+
47+
func TestIsNotFound(t *testing.T) {
48+
if !IsNotFound("/usr/local/fvm/versions/.DS_Store/.github") {
49+
t.Fail()
50+
}
51+
}

0 commit comments

Comments
 (0)