-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfile2const.go
110 lines (98 loc) · 2.24 KB
/
file2const.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 main
import (
"flag"
"fmt"
"go/ast"
"go/format"
"go/token"
"io/ioutil"
"os"
"path/filepath"
"strconv"
"strings"
"unicode"
)
type inputFile struct {
contents string
constantName string
}
var (
packageName string
outputFile string
inputFiles []inputFile
)
func printHelp() {
fmt.Fprintf(os.Stderr, "Usage: %s <flags> [<inputFile:constantName>] <outputFile.go>\n", os.Args[0])
flag.PrintDefaults()
}
func parseFlags() error {
flag.StringVar(&packageName, "package", "", "name of package to give to file. Default to directory name")
flag.Parse()
if flag.NArg() < 2 {
return fmt.Errorf("need at least 2 arguments")
}
outputFile = flag.Args()[flag.NArg()-1]
outputFile, err := filepath.Abs(outputFile)
if err != nil {
return err
}
if packageName == "" {
packageName = filepath.Base(filepath.Dir(outputFile))
}
inputFiles = make([]inputFile, flag.NArg()-1)
for i, input := range flag.Args()[:flag.NArg()-1] {
s := strings.SplitN(input, ":", 2)
if len(s) != 2 {
return fmt.Errorf("wrongly formatted input file %#v", input)
}
contents, err := ioutil.ReadFile(s[0])
if err != nil {
return err
}
inputFiles[i].contents = string(contents)
inputFiles[i].constantName = s[1]
}
return nil
}
func ValueToLiteral(value string) string {
if strings.Contains(value, "`") || strings.IndexFunc(value, func(r rune) bool { return !unicode.IsGraphic(r) && r != '\n' }) != -1 {
return strconv.Quote(value)
} else {
return "`" + value + "`"
}
}
func main() {
err := parseFlags()
if err != nil {
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr)
printHelp()
return
}
fs := token.NewFileSet()
values := make([]ast.Spec, len(inputFiles))
for i, input := range inputFiles {
values[i] = &ast.ValueSpec{
Names: []*ast.Ident{&ast.Ident{Name: input.constantName}},
Values: []ast.Expr{&ast.BasicLit{Kind: token.STRING, Value: ValueToLiteral(input.contents)}},
}
}
f := &ast.File{
Name: &ast.Ident{Name: packageName},
Decls: []ast.Decl{
&ast.GenDecl{
Tok: token.CONST,
Lparen: token.Pos(1),
Rparen: token.Pos(1),
Specs: values,
},
},
}
file, err := os.Create(outputFile)
if err != nil {
fmt.Fprint(os.Stderr, err)
return
}
defer file.Close()
format.Node(file, fs, f)
}