Skip to content

Commit

Permalink
Merge branch 'release0.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
befovy committed Mar 7, 2020
2 parents 257a1d6 + 31079ec commit 701da04
Show file tree
Hide file tree
Showing 10 changed files with 372 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

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.

### [0.4.0](https://github.com/befovy/fvm/compare/v0.3.1...v0.4.0) (2020-03-07)

* add import sub command, import flutter outside of fvm into fvm ([2161286](https://github.com/befovy/fvm/commit/21612865b64685165f1c8c33158dd928f4aebb38))

### [0.3.1](https://github.com/befovy/fvm/compare/v0.3.0...v0.3.1) (2020-02-18)

* fix magicfile test [#1](https://github.com/befovy/fvm/issues/1) ([7bdb743](https://github.com/befovy/fvm/commit/7bdb7434c844f5289760bc8620da8dbd42dd0266))
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ FVM gives you the ability to install many Flutter **releases** or **channels**.

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

### Import Flutter from previous installation

FVM has subcommand `import` which can import your previous installed flutter into fvm.

```bash
> fvm import <name>
```

If you have installed master channel flutter, just use `fvm import master`.
Or if you have installed a special derived flutter, just use any name you want to import this flutter.
You can use a name from you company, or any other you want. `fvm import xianyu`

### Use a SDK Version

You can use the installed Flutter SDK versions for your computer user account globally. To do that just:
Expand Down
115 changes: 115 additions & 0 deletions cmd/import.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/*
Copyright © 2020 befovy <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
"errors"
"github.com/befovy/fvm/fvmgo"
"github.com/spf13/cobra"
"os"
"path/filepath"
"strings"
)

var cop bool
var pos string

func init() {
importCommand.Flags().BoolVarP(&cop, "copy", "c", false, "copy files instead of move")
importCommand.Flags().StringVar(&pos, "path", "", "special the installed flutter path to import")
rootCmd.AddCommand(importCommand)
}

var importCommand = &cobra.Command{
Use: "import <name>",
Short: "Import installed flutter into fvm",
Long: "Import installed flutter into fvm.\n" +
"If there are more than one flutter detected,\n" +
"this sub command use the first one in path by default.\n" +
"Or you can use flags --path to special the path of flutter",
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
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.")
}
if len(args) > 1 {
return errors.New("allows only one argument, the name to be imported as")
}
return nil
},
Run: func(cmd *cobra.Command, args []string) {
dst := args[0]
choices := fvmgo.FlutterListInstalledSdks()
if len(choices) > 0 {
for _, choice := range choices {
if dst == choice {
ins := fvmgo.YellowV("%s", dst)
fvmgo.Errorf("fvm has already installed flutter with channel or version: %v", ins)
return
}
}
}

flutters := fvmgo.FlutterOutOfFvm(pos)
var source string
if flutters == nil || len(flutters) == 0 {
fvmgo.Warnf("fvm did not detect any flutter outside of fvm")
} else if len(flutters) > 1 {
if len(pos) == 0 {
fvmgo.Infof("There are %d flutters outside of fvm, you don't set flag --path, so fvm will import te first one", len(flutters))
source = flutters[0]
} else {
var match string
for _, f := range flutters {
if strings.HasPrefix(f, pos) {
fvmgo.Infof("match %s", f)
if len(match) == 0 {
match = f
source = match
} else if match != f {
fvmgo.Warnf("More than one installed flutter match the path: %v. You should provide a more detailed path", pos)
source = ""
break
}
}
}
}
} else {
source = flutters[0]
}

if len(source) > 0 {
dst = filepath.Join(fvmgo.VersionsDir(), dst)
source = filepath.Dir(filepath.Dir(source))
fvmgo.Infof("%s will be imported into fvm", fvmgo.YellowV("%s", source))
if cop {
fvmgo.Infof("Copy all files from %v to %v, please wait seconds", source, dst)
} else {
fvmgo.Infof("Move all files from %v to %v, please wait seconds", source, dst)
}
err := fvmgo.CopyDir(source, dst)
if err != nil {
fvmgo.Errorf("Failed to copy files, %v", err)
}
if !cop {
err = os.RemoveAll(source)
if err != nil {
fvmgo.Errorf("Failed to delete files, %v", err)
}
}
}
},
}
15 changes: 15 additions & 0 deletions cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ var installCommand = &cobra.Command{
return nil
},
Run: func(cmd *cobra.Command, args []string) {

flutters := fvmgo.FlutterOutOfFvm("")
if flutters != nil && len(flutters) > 0 {
fvmgo.Errorf("You have installed flutter outside of fvm")
for _, f := range flutters {
fvmgo.Warnf("--> %v", f)
}
ins := fvmgo.YellowV("fvm import")
if len(flutters) == 1 {
fvmgo.Errorf("To import this into fvm, use %v", ins)
} else {
fvmgo.Errorf("To import these into fvm, use %v", ins)
}
}

err := fvmgo.CheckIfGitExists()
if err == nil {
version := args[0]
Expand Down
13 changes: 13 additions & 0 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,18 @@ var listCommand = &cobra.Command{
fvmgo.Infof(c)
}
}
flutters := fvmgo.FlutterOutOfFvm("")
if flutters != nil && len(flutters) > 0 {
fvmgo.Errorf("You have installed flutter outside of fvm")
for _, f := range flutters {
fvmgo.Warnf("--> %v", f)
}
ins := fvmgo.YellowV("fvm import")
if len(flutters) == 1 {
fvmgo.Errorf("To import this into fvm, use %v", ins)
} else {
fvmgo.Errorf("To import these into fvm, use %v", ins)
}
}
},
}
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ var rootCmd = &cobra.Command{
Use: "fvm",
Short: "Flutter Version Management",
Long: "Flutter Version Management: A cli to manage Flutter SDK versions.",
Version: "0.3.1",
Version: "0.4.0",
}

// Execute executes the rootCmd
Expand Down
2 changes: 1 addition & 1 deletion cmd/use.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import (
var local bool

func init() {
useCommand.Flags().BoolVar(&local, "local", false, "use SDK locally")
useCommand.Flags().BoolVarP(&local, "local", "l", false, "use SDK locally")
rootCmd.AddCommand(useCommand)
}

Expand Down
121 changes: 117 additions & 4 deletions fvmgo/file.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright © 2019 befovy <[email protected]>
Copyright © 2019-2020 befovy <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -16,8 +16,11 @@ limitations under the License.
package fvmgo

import (
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
)

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

func IsNotFound(path string) bool {
_, err := os.Lstat(path)
return os.IsNotExist(err)
func IsNotFound(name string) bool {
_, err := os.Lstat(name)
return err != nil
}

func IsExecutable(name string) bool {
info, err := os.Stat(name)
if err != nil {
return false
}
return !info.IsDir() && ((info.Mode() & 0111) != 0)
}

// CopyFile copies the contents of the file named src to the file named
// by dst. The file will be created if it does not already exist. If the
// destination file exists, all it's contents will be replaced by the contents
// of the source file. The file mode will be copied from the source and
// the copied data is synced/flushed to stable storage.
func CopyFile(src, dst string) (err error) {
in, err := os.Open(src)
if err != nil {
return
}
defer in.Close()

out, err := os.Create(dst)
if err != nil {
return
}
defer func() {
if e := out.Close(); e != nil {
err = e
}
}()

_, err = io.Copy(out, in)
if err != nil {
return
}

err = out.Sync()
if err != nil {
return
}

si, err := os.Stat(src)
if err != nil {
return
}
err = os.Chmod(dst, si.Mode())
if err != nil {
return
}

return
}

// CopyDir recursively copies a directory tree, attempting to preserve permissions.
// Source directory must exist, destination directory must *not* exist.
// Symlinks are ignored and skipped.
func CopyDir(src string, dst string) (err error) {
src = filepath.Clean(src)
dst = filepath.Clean(dst)

si, err := os.Stat(src)
if err != nil {
return err
}
if !si.IsDir() {
return fmt.Errorf("source is not a directory")
}

_, err = os.Stat(dst)
if err != nil && !os.IsNotExist(err) {
return
}
if err == nil {
return fmt.Errorf("destination already exists")
}

err = os.MkdirAll(dst, si.Mode())
if err != nil {
return
}

entries, err := ioutil.ReadDir(src)
if err != nil {
return
}

for _, entry := range entries {
srcPath := filepath.Join(src, entry.Name())
dstPath := filepath.Join(dst, entry.Name())

if entry.IsDir() {
err = CopyDir(srcPath, dstPath)
if err != nil {
return
}
} else {
// Skip symlinks.
if entry.Mode()&os.ModeSymlink != 0 {
continue
}

err = CopyFile(srcPath, dstPath)
if err != nil {
return
}
}
}

return
}
51 changes: 51 additions & 0 deletions fvmgo/file_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright © 2020 befovy <[email protected]>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package fvmgo

import (
"runtime"
"testing"
)

func TestFileExist(t *testing.T) {
if runtime.GOOS == "darwin" {
if !IsFileExists("/bin/bash") {
t.Fail()
}
if IsFileExists("/bin/helloworld") {
t.Fail()
}
}
}

func TestIsDirectory(t *testing.T) {
if runtime.GOOS == "darwin" {
if !IsDirectory("/bin") {
t.Fail()
}

if IsDirectory("bin/bash") {
t.Fail()
}
}
}

func TestIsNotFound(t *testing.T) {
if !IsNotFound("/usr/local/fvm/versions/.DS_Store/.github") {
t.Fail()
}
}
Loading

0 comments on commit 701da04

Please sign in to comment.