-
Notifications
You must be signed in to change notification settings - Fork 26
/
articles.go
113 lines (100 loc) · 2.39 KB
/
articles.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
// The articles command is used for easily managing article files.
//
// To install this tool, type go install gnd.la/apps/articles/cmd/articles.
//
// Then, view its help and usage by typing:
//
// articles help
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"gnd.la/apps/articles/article"
"github.com/rainycape/command"
)
func openArticle(p string) (*article.Article, error) {
f, err := os.Open(p)
if err != nil {
return nil, fmt.Errorf("error opening %s: %s", p, err)
}
defer f.Close()
article, err := article.New(f)
if err != nil {
return nil, fmt.Errorf("error loading %s: %s", p, err)
}
return article, nil
}
func dumpCommand(args []string) {
for _, v := range args {
article, err := openArticle(v)
if err != nil {
log.Print(err)
continue
}
fmt.Printf("article %s\n%+v\n", v, article)
}
}
func setCommand(args []string) error {
if len(args) != 3 {
return fmt.Errorf("invalid number of arguments %d, must be <property> <value> <article>", len(args))
}
p := args[2]
article, err := openArticle(p)
if err != nil {
return err
}
if err := article.Set(args[0], args[1]); err != nil {
return err
}
var buf bytes.Buffer
if _, err := article.WriteTo(&buf); err != nil {
return err
}
return ioutil.WriteFile(p, buf.Bytes(), 0644)
}
const (
dumpHelp = `The dump command dumps the articles it parses to the
standard output. It can be used to validate articles files.`
setHelp = `The set command sets properties in article files. The parsed
properties include:
- id (string)
- title ([]string)
- slug ([]string)
- synopsis (string)
- updated ([]time.Time)
- priority (int)
Setting a property stored in a slice prepends the new value to the existing ones. To
delete a value, simply remove its line with a text editor.
time.Time properties must use one of the following formats:
- now
- today
- yyyy-mm-dd
- yyyy-mm-dd hh:MM
- yyyy-mm-dd hh:MM:ss
- time.RFC822
- time.RFC822Z`
)
var (
commands = []*command.Cmd{
{
Name: "dump",
Help: "Dump parsed articles to command line",
LongHelp: dumpHelp,
Usage: "<article-1> [article-2] ... [article-n]",
Func: dumpCommand,
},
{
Name: "set",
Help: "Set or add a property to the given article",
LongHelp: setHelp,
Usage: "<property> <value> <article>",
Func: setCommand,
},
}
)
func main() {
command.Run(commands)
}