forked from umputun/remark42
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cmd.go
110 lines (97 loc) · 2.81 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
// Package cmd has all top-level commands dispatched by main's flag.Parse
// The entry point of each command is Execute function
package cmd
import (
"bytes"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
"text/template"
"time"
log "github.com/go-pkgz/lgr"
"github.com/pkg/errors"
)
// CommonOptionsCommander extends flags.Commander with SetCommon
// All commands should implement this interfaces
type CommonOptionsCommander interface {
SetCommon(commonOpts CommonOpts)
Execute(args []string) error
}
// CommonOpts sets externally from main, shared across all commands
type CommonOpts struct {
RemarkURL string
SharedSecret string
Revision string
}
// SetCommon satisfies CommonOptionsCommander interface and sets common option fields
// The method called by main for each command
func (c *CommonOpts) SetCommon(commonOpts CommonOpts) {
c.RemarkURL = commonOpts.RemarkURL
c.SharedSecret = commonOpts.SharedSecret
c.Revision = commonOpts.Revision
}
// fileParser used to convert template strings like blah-{{.SITE}}-{{.YYYYMMDD}} the final format
type fileParser struct {
site string
file string
path string
}
// parse apply template and also concat path and file. In case if file contains path separator path will be ignored
func (p *fileParser) parse(now time.Time) (string, error) {
// file/location parameters my have template masks
fileTemplate := struct {
YYYYMMDD string
YYYY string
YYYYMM string
MM string
DD string
TS string
UNIX int64
SITE string
}{
YYYYMMDD: now.Format("20060102"),
YYYY: now.Format("2006"),
YYYYMM: now.Format("200601"),
MM: now.Format("01"),
DD: now.Format("02"),
UNIX: now.Unix(),
SITE: p.site,
TS: now.Format("20060102T150405"),
}
bb := bytes.Buffer{}
fname := p.file
if !strings.Contains(p.file, string(filepath.Separator)) {
fname = filepath.Join(p.path, p.file)
}
if err := template.Must(template.New("bb").Parse(fname)).Execute(&bb, fileTemplate); err != nil {
return "", errors.Wrapf(err, "failed to parse %q", fname)
}
return bb.String(), nil
}
// resetEnv clears sensitive env vars
func resetEnv(envs ...string) {
for _, env := range envs {
if err := os.Unsetenv(env); err != nil {
log.Printf("[WARN] can't unset env %s, %s", env, err)
}
}
}
// responseError returns error with status and response body
func responseError(resp *http.Response) error {
body, e := ioutil.ReadAll(resp.Body)
if e != nil {
body = []byte("")
}
return errors.Errorf("error response %q, %s", resp.Status, body)
}
// mkdir -p for all dirs
func makeDirs(dirs ...string) error {
for _, dir := range dirs {
if err := os.MkdirAll(dir, 0700); err != nil { // If path is already a directory, MkdirAll does nothing
return errors.Wrapf(err, "can't make directory %s", dir)
}
}
return nil
}