Compare commits

..

5 Commits

Author SHA1 Message Date
Minghe Huang
05523aceb4 add JavaScript deps parser 2020-03-01 14:44:07 +08:00
Minghe
5f811693f1 bump up version 2020-02-21 17:28:07 +08:00
Minghe
0068fb92eb support 'format' option in 'fx list' (#462) 2020-02-21 17:26:39 +08:00
dependabot-preview[bot]
71174ead45 Bump github.com/stretchr/testify from 1.4.0 to 1.5.1 (#459)
Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.4.0 to 1.5.1.
- [Release notes](https://github.com/stretchr/testify/releases)
- [Commits](https://github.com/stretchr/testify/compare/v1.4.0...v1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-21 15:10:47 +08:00
dependabot-preview[bot]
43c18caceb Bump github.com/briandowns/spinner from 1.7.0 to 1.9.0 (#457)
Bumps [github.com/briandowns/spinner](https://github.com/briandowns/spinner) from 1.7.0 to 1.9.0.
- [Release notes](https://github.com/briandowns/spinner/releases)
- [Commits](https://github.com/briandowns/spinner/compare/v1.7.0...v1.9.0)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-02-18 11:03:24 +08:00
13 changed files with 214 additions and 61 deletions

9
fx.go
View File

@@ -17,7 +17,7 @@ import (
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
)
const version = "0.9.0"
const version = "0.9.1"
func init() {
go checkForUpdate()
@@ -179,6 +179,13 @@ func main() {
Name: "list",
Aliases: []string{"ls"},
Usage: "list deployed services",
Flags: []cli.Flag{
cli.StringFlag{
Name: "format, f",
Value: "table",
Usage: "output format, 'table' and 'JSON' supported",
},
},
Action: handle(
middlewares.Parse("list"),
middlewares.LoadConfig,

4
go.mod
View File

@@ -6,7 +6,7 @@ require (
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/Microsoft/go-winio v0.4.14 // indirect
github.com/apex/log v1.1.2
github.com/briandowns/spinner v1.7.0
github.com/briandowns/spinner v1.9.0
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v0.0.0-20190313072916-46036c230805
github.com/docker/go-connections v0.4.0
@@ -38,7 +38,7 @@ require (
github.com/rogpeppe/go-internal v1.5.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.6.2
github.com/stretchr/testify v1.4.0
github.com/stretchr/testify v1.5.1
github.com/ugorji/go v1.1.7 // indirect
github.com/urfave/cli v1.22.2
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect

4
go.sum
View File

@@ -35,6 +35,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/briandowns/spinner v1.7.0 h1:aan1hBBOoscry2TXAkgtxkJiq7Se0+9pt+TUWaPrB4g=
github.com/briandowns/spinner v1.7.0/go.mod h1://Zf9tMcxfRUA36V23M6YGEAv+kECGfvpnLTnb8n4XQ=
github.com/briandowns/spinner v1.9.0 h1:+OMAisemaHar1hjuJ3Z2hIvNhQl9Y7GLPWUwwz2Pxo8=
github.com/briandowns/spinner v1.9.0/go.mod h1://Zf9tMcxfRUA36V23M6YGEAv+kECGfvpnLTnb8n4XQ=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
@@ -332,6 +334,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0=

View File

@@ -3,19 +3,19 @@ package handlers
import (
"github.com/metrue/fx/context"
"github.com/metrue/fx/infra"
"github.com/metrue/fx/pkg/render"
"github.com/metrue/fx/pkg/renderrer"
)
// List command handle
func List(ctx context.Contexter) (err error) {
cli := ctx.GetCliContext()
deployer := ctx.Get("deployer").(infra.Deployer)
format := ctx.Get("format").(string)
services, err := deployer.List(ctx.GetContext(), cli.Args().First())
if err != nil {
return err
}
render.Table(services)
return nil
return renderrer.Render(services, format)
}

View File

@@ -4,7 +4,7 @@ import (
"github.com/apex/log"
"github.com/metrue/fx/context"
"github.com/metrue/fx/infra"
"github.com/metrue/fx/pkg/render"
"github.com/metrue/fx/pkg/renderrer"
"github.com/metrue/fx/types"
)
@@ -42,6 +42,5 @@ func Up(ctx context.Contexter) (err error) {
if err != nil {
return err
}
render.Table([]types.Service{service})
return nil
return renderrer.Render([]types.Service{service}, "table")
}

View File

@@ -86,12 +86,6 @@ func (d *Deployer) Ping(ctx context.Context) error {
// List services
func (d *Deployer) List(ctx context.Context, name string) (svcs []types.Service, err error) {
const task = "listing"
spinner.Start(task)
defer func() {
spinner.Stop(task, err)
}()
// FIXME support remote host
return d.cli.ListContainer(ctx, name)
}

View File

@@ -42,6 +42,8 @@ func Parse(action string) func(ctx context.Contexter) (err error) {
case "list":
name := cli.Args().First()
ctx.Set("filter", name)
format := cli.String("format")
ctx.Set("format", format)
case "image_build":
sources := []string{}
for _, s := range cli.Args() {

53
packer/deps.go Normal file
View File

@@ -0,0 +1,53 @@
package packer
import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
)
// JavaScriptExt extension of JavaScript source file
const JavaScriptExt = ".js"
func depsJavaScript(src string) ([]string, error) {
deps := []string{}
file, err := os.Open(src)
if err != nil {
return nil, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if strings.HasPrefix(line, "import") || strings.HasPrefix(line, "require") {
reg, err := regexp.Compile(`(\'.*\'|\".*\")`)
if err != nil {
return nil, err
}
str := reg.FindString(line)
if str != "" {
deps = append(deps, strings.ReplaceAll(strings.ReplaceAll(str, "\"", ""), "'", ""))
}
}
}
if err := scanner.Err(); err != nil {
return nil, err
}
return deps, nil
}
// Deps to get the dependencies required from a source code in a file
func Deps(src string) ([]string, error) {
switch filepath.Ext(src) {
case JavaScriptExt:
{
return depsJavaScript(src)
}
}
return nil, fmt.Errorf("not support language: %s", filepath.Ext(src))
}

63
packer/deps_test.go Normal file
View File

@@ -0,0 +1,63 @@
package packer
import (
"io/ioutil"
"os"
"reflect"
"testing"
)
func TestDeps(t *testing.T) {
cases := []struct {
name string
content string
expect []string
}{
{name: "import with singe quote", content: "import 'pkg1'", expect: []string{"pkg1"}},
{name: "import with double quote", content: `import "pkg1"`, expect: []string{"pkg1"}},
{name: "require with singe quote", content: "require 'pkg1'", expect: []string{"pkg1"}},
{name: "require with double quote", content: `require "pkg1"`, expect: []string{"pkg1"}},
{
name: "require and import with singe quote",
content: `
require 'pkg1'
import 'pkg2'`,
expect: []string{"pkg1", "pkg2"},
},
{
name: "require and import with double quote",
content: `
require "pkg1"
import "pkg2"`,
expect: []string{"pkg1", "pkg2"},
},
{
name: "require and import with double quote and single quote",
content: `
require 'pkg1'
import "pkg2"`,
expect: []string{"pkg1", "pkg2"},
},
}
for _, c := range cases {
fd, err := ioutil.TempFile("", "dep_pkg_*.js")
if err != nil {
t.Fatal(err)
}
defer os.Remove(fd.Name())
err = ioutil.WriteFile(fd.Name(), []byte(c.content), 0666)
if err != nil {
t.Fatal(err)
}
deps, err := Deps(fd.Name())
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(deps, c.expect) {
t.Fatalf("%s: should get %s but got %s", c.name, c.expect, deps)
}
}
}

View File

@@ -1,27 +0,0 @@
package render
import (
"fmt"
"os"
"github.com/metrue/fx/types"
"github.com/olekukonko/tablewriter"
)
// Table output services as table format
func Table(services []types.Service) {
data := [][]string{}
for _, s := range services {
col := []string{
s.ID,
s.Name,
fmt.Sprintf("%s:%d", s.Host, +s.Port),
}
data = append(data, col)
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"ID", "Name", "Endpoint"})
table.AppendBulk(data)
table.Render()
}

View File

@@ -1,19 +0,0 @@
package render
import (
"testing"
"github.com/metrue/fx/types"
)
func TestTable(t *testing.T) {
services := []types.Service{
types.Service{
ID: "id-1",
Name: "name-1",
Host: "127.0.0.1",
Port: 1000,
},
}
Table(services)
}

View File

@@ -0,0 +1,53 @@
package renderrer
import (
"encoding/json"
"fmt"
"os"
"strings"
"github.com/metrue/fx/types"
"github.com/olekukonko/tablewriter"
)
const formatJSON = "json"
//nolint:unused,varcheck,deadcode
const formatTable = "table"
// Render render output with given format
func Render(services []types.Service, format string) error {
if strings.ToLower(format) == formatJSON {
return toJSON(services)
}
return toTable(services)
}
func toTable(services []types.Service) error {
data := [][]string{}
for _, s := range services {
col := []string{
s.ID,
s.Name,
fmt.Sprintf("%s:%d", s.Host, +s.Port),
}
data = append(data, col)
}
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"ID", "Name", "Endpoint"})
table.AppendBulk(data)
table.Render()
return nil
}
func toJSON(services []types.Service) error {
output, err := json.Marshal(services)
if err != nil {
return err
}
if _, err := fmt.Print(string(output)); err != nil {
return err
}
return nil
}

View File

@@ -0,0 +1,24 @@
package renderrer
import (
"testing"
"github.com/metrue/fx/types"
)
func TestRenderrer(t *testing.T) {
services := []types.Service{
types.Service{
ID: "id-1",
Name: "name-1",
Host: "127.0.0.1",
Port: 1000,
},
}
t.Run("toTable", func(t *testing.T) {
Render(services, "table")
})
t.Run("toJSON", func(t *testing.T) {
Render(services, "json")
})
}