/
api.go
106 lines (90 loc) · 2.56 KB
/
api.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
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"github.com/errata-ai/vale/v2/internal/core"
"github.com/mholt/archiver/v3"
"github.com/spf13/pflag"
)
// Style represents an externally-hosted style.
type Style struct {
// User-provided fields.
Author string `json:"author"`
Description string `json:"description"`
Deps string `json:"deps"`
Feed string `json:"feed"`
Homepage string `json:"homepage"`
Name string `json:"name"`
URL string `json:"url"`
// Generated fields.
HasUpdate bool `json:"has_update"`
InLibrary bool `json:"in_library"`
Installed bool `json:"installed"`
Addon bool `json:"addon"`
}
// Meta represents an installed style's meta data.
type Meta struct {
Author string `json:"author"`
Coverage float64 `json:"coverage"`
Description string `json:"description"`
Email string `json:"email"`
Feed string `json:"feed"`
Lang string `json:"lang"`
License string `json:"license"`
Name string `json:"name"`
Sources []string `json:"sources"`
URL string `json:"url"`
Vale string `json:"vale_version"`
Version string `json:"version"`
}
func init() {
pflag.BoolVar(&Flags.Remote, "mode-rev-compat", false,
"prioritize local Vale configurations")
pflag.StringVar(&Flags.Built, "built", "", "post-processed file path")
Actions["install"] = install
}
func fetch(src, dst string) error {
// Fetch the resource from the web:
resp, err := http.Get(src) //nolint:gosec,noctx
if err != nil {
return err
} else if resp.StatusCode != 200 {
return fmt.Errorf("could not fetch '%s' (status code '%d')", src, resp.StatusCode)
}
// Create a temp file to represent the archive locally:
tmpfile, err := os.CreateTemp("", "temp.*.zip")
if err != nil {
return err
}
defer os.Remove(tmpfile.Name()) // clean up
// Write to the local archive:
_, err = io.Copy(tmpfile, resp.Body)
if err != nil {
return err
} else if err = tmpfile.Close(); err != nil {
return err
}
resp.Body.Close()
return archiver.Unarchive(tmpfile.Name(), dst)
}
func install(args []string, flags *core.CLIFlags) error {
cfg, err := core.ReadPipeline(flags, false)
if err != nil {
return err
}
style := filepath.Join(cfg.StylesPath, args[0])
if core.IsDir(style) {
os.RemoveAll(style) // Remove existing version
}
err = fetch(args[1], cfg.StylesPath)
if err != nil {
return sendResponse(
fmt.Sprintf("Failed to install '%s'", args[1]),
err)
}
return sendResponse(fmt.Sprintf(
"Successfully installed '%s'", args[1]), nil)
}