-
Notifications
You must be signed in to change notification settings - Fork 1
/
cmd.go
148 lines (128 loc) · 3.48 KB
/
cmd.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
Package cmd implements command-line interfaces.
*/
package cmd
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"os/exec"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"go.uber.org/multierr"
"github.com/artefactual-labs/amflow/internal/constants"
"github.com/artefactual-labs/amflow/internal/graph"
"github.com/artefactual-labs/amflow/internal/graph/encoding"
"github.com/artefactual-labs/amflow/internal/version"
)
var (
v string
)
var rootCmd = &cobra.Command{
Use: "amflow",
Short: "A tool that facilitates workflow editing for Archivematica.",
}
func Run() error {
c := command(os.Stdout, os.Stderr)
return c.Execute()
}
func command(out, err io.Writer) *cobra.Command {
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
if err := setUpLogs(err, v); err != nil {
return err
}
rootCmd.SilenceUsage = true
logrus.Infof("amflow %+s", version.Get())
return nil
}
rootCmd.SilenceErrors = true
rootCmd.AddCommand(newCmdVersion(out))
rootCmd.AddCommand(newCmdEdit(out))
rootCmd.AddCommand(newCmdExport(out))
rootCmd.AddCommand(newCmdSearch(out))
rootCmd.AddCommand(newCmdCheck(out))
rootCmd.PersistentFlags().StringVarP(&v, "verbosity", "v", constants.DefaultLogLevel.String(), "Log level (debug, info, warn, error, fatal, panic")
return rootCmd
}
func setUpLogs(out io.Writer, level string) error {
logrus.SetOutput(out)
lvl, err := logrus.ParseLevel(v)
if err != nil {
return errors.Wrap(err, "parsing log level")
}
logrus.SetLevel(lvl)
return nil
}
// load returns the workflow loaded from the contents of the file.
func load(file string) (*graph.Workflow, error) {
var (
bytes []byte
err error
)
// Load workflow bytes.
if file == "" {
logrus.WithFields(logrus.Fields{"mode": "embedded"}).Info("Loading workfow")
bytes, err = graph.WorkflowSchemaBox.Find("example.json")
} else if isURL(file) {
logrus.WithFields(logrus.Fields{"mode": "file", "source": file}).Info("Downloading workfow")
bytes, err = downloadRemote(file)
} else {
logrus.WithFields(logrus.Fields{"mode": "file", "source": file}).Info("Loading workfow")
bytes, err = ioutil.ReadFile(file)
}
if err != nil {
return nil, errors.WithMessage(err, "Workflow could not be retrieved")
}
// Decode it.
data, err := encoding.LoadWorkflowData(bytes)
if err != nil {
return nil, err
}
// Populate it.
w := graph.New(data)
logrus.WithFields(logrus.Fields{
"bytes": len(bytes),
"vertices": w.Nodes().Len(),
}).Debug("Workflow loaded")
// Check for errors.
for _, err := range multierr.Errors(w.Check()) {
logrus.WithFields(logrus.Fields{
"err": err,
}).Warn("Unhealthy workflow warning")
}
return w, nil
}
func isURL(addr string) bool {
u, err := url.Parse(addr)
if err != nil {
return false
}
if u.Scheme == "" {
return false
}
return true
}
func downloadRemote(addr string) ([]byte, error) {
resp, err := http.Get(addr)
if err != nil {
return nil, errors.WithMessage(err, "remote resource could not be retrieved")
}
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, fmt.Errorf("remote server returned and unexpected response with status code: %d", resp.StatusCode)
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, errors.WithMessage(err, "remote resource could not be loaded")
}
return bytes, nil
}
func checkDot() {
if _, err := exec.LookPath("dot"); err != nil {
logrus.Warn("dot (Graphviz) is not installed")
}
}