-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.go
290 lines (235 loc) · 7.5 KB
/
main.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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
package main
import (
"github.com/howeyc/fsnotify"
"flag"
"fmt"
"net/http"
"os"
"path/filepath"
"strings"
"sync"
)
var (
// directory where Jekyll will look to transform files
source = flag.String("source", "", "")
// directory where Jekyll will write files to
destination = flag.String("destination", "_site", "")
// fires up a server that will host your _site directory if True
server = flag.Bool("server", false, "")
// the port that the Jekyll server will run on
port = flag.String("port", ":4000", "")
// re-generates the site when files are modified.
auto = flag.Bool("auto", false, "")
// serves the website from the specified base url
baseurl = flag.String("base-url", "", "")
// deploys the website to QiniuCloudStorage
deploy76 = flag.Bool("qiniu", false, "")
// qiniu config
q6config = flag.String("qiniu-config", "", "")
// qiniu access key
q6key = flag.String("qiniu-key", "", "")
// qiniu secret key
q6secret = flag.String("qiniu-secret", "", "")
// qiniu bucket name
q6bucket = flag.String("qiniu-bucket", "", "")
// deploys the website to S3
deploys3 = flag.Bool("s3", false, "")
// s3 config
s3config = flag.String("s3-config", "", "")
// s3 access key
s3key = flag.String("s3-key", "", "")
// s3 secret key
s3secret = flag.String("s3-secret", "", "")
// s3 bucket name
s3bucket = flag.String("s3-bucket", "", "")
// runs Jekyll with verbose output if True
verbose = flag.Bool("verbose", false, "")
// displays the help / usage if True
help = flag.Bool("help", false, "")
)
// Mutex used when doing auto-builds
var mu sync.RWMutex
func main() {
// Parse the input parameters
flag.BoolVar(help, "h", false, "")
flag.BoolVar(verbose, "v", false, "")
flag.Usage = usage
flag.Parse()
if *help {
flag.Usage()
os.Exit(0)
}
// User may specify the source as a non-flag variable
if flag.NArg() > 0 {
source = &flag.Args()[0]
}
// Convert the directory to an absolute path
src, _ := filepath.Abs(*source)
dest, _ := filepath.Abs(*destination)
// Change the working directory to the website's source directory
os.Chdir(src)
// Initialize the Jekyll website
site, err := NewSite(src, dest)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
// Set any site variables that were overriden / provided in the cli args
if *baseurl != "" || site.Conf.Get("baseurl") == nil {
site.Conf.Set("baseurl", *baseurl)
}
// Generate the static website
if err := site.Generate(); err != nil {
fmt.Println(err)
os.Exit(1)
}
// Deploys the static website to S3
if *deploys3 {
var conf *DeployS3Config
// Read the S3 configuration details if not provided as
// command line
if *s3key == "" || *s3secret == "" || *s3bucket == "" {
path := filepath.Join(site.Src, "_jekyll_s3.yml")
if *s3config != "" {
path = *s3config
}
conf, err = ParseDeployS3Config(path)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
} else {
// else use the command line args
conf = &DeployS3Config{*s3key, *s3secret, *s3bucket}
}
if err := site.DeployToS3(conf.Key, conf.Secret, conf.Bucket); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
// Deploys the static website to QiniuCloudStorage
if *deploy76 {
var conf *Deploy76Config
// Read the Qiniu configuration details if not provided as
// command line
if *q6key == "" || *q6secret == "" || *q6bucket == "" {
path := filepath.Join(site.Src, "_jekyll_qiniu.yml")
if *q6config != "" {
path = *q6config
}
conf, err = ParseDeploy76Config(path)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
} else {
// else use the command line args
conf = &Deploy76Config{*q6key, *q6secret, *q6bucket}
}
if err := site.DeployToQiniu(conf.Key, conf.Secret, conf.Bucket); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
// If the auto option is enabled, use fsnotify to watch
// and re-generate the site if files change.
if *auto {
fmt.Printf("Listening for changes to %s\n", site.Src)
go watch(site)
}
// If the server option is enabled, launch a webserver
if *server {
// Change the working directory to the _site directory
//os.Chdir(dest)
// Create the handler to serve from the filesystem
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
mu.RLock()
defer mu.RUnlock()
base := site.Conf.GetString("baseurl")
path := r.URL.Path
pathList := filepath.SplitList(path)
if len(pathList) > 0 && pathList[0] == base {
path = strings.Join(pathList[len(pathList):], "/")
}
path = filepath.Clean(path)
path = filepath.Join(dest, path)
http.ServeFile(w, r, path)
})
// Serve the website from the _site directory
fmt.Printf("Starting server on port %s\n", *port)
if err := http.ListenAndServe(*port, nil); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
os.Exit(0)
}
func watch(site *Site) {
// Setup the inotify watcher
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Println(err)
return
}
// Get recursive list of directories to watch
for _, path := range dirs(site.Src) {
if err := watcher.Watch(path); err != nil {
fmt.Println(err)
return
}
}
for {
select {
case ev := <-watcher.Event:
// Ignore changes to the _site directoy, hidden, or temp files
if !strings.HasPrefix(ev.Name, site.Dest) && !isHiddenOrTemp(ev.Name) {
fmt.Println("Event:", ev.Name)
recompile(site)
}
case err := <-watcher.Error:
fmt.Println("inotify error:", err)
}
}
}
func recompile(site *Site) {
mu.Lock()
defer mu.Unlock()
site.Reload()
site.Generate()
}
func logf(msg string, args ...interface{}) {
if *verbose {
println(fmt.Sprintf(msg, args...))
}
}
var usage = func() {
fmt.Println(`Usage: jkl [OPTION]... [SOURCE]
--auto re-generates the site when files are modified
--base-url serve website from a given base URL
--source changes the dir where Jekyll will look to transform files
--destination changes the dir where Jekyll will write files to
--server starts a server that will host your _site directory
--port changes the port that the Jekyll server will run on
--s3 copies the _site directory to s3
--s3-config path to the _jekyll_s3.yml file that specifies your AWS key, secret and bucket
--s3-key aws access key use for s3 authentication
--s3-secret aws secret key use for s3 authentication
--s3-bucket name of the s3 bucket
--qiniu copies the _site directory to Qiniu Cloud Storage
--qiniu-config path to the _jekyll_qiniu.yml file that specifies your Qiniu key, secret and bucket
--qiniu-key access key use for qiniu authentication
--qiniu-secret secret key use for qiniu authentication
--qiniu-bucket name of the qiniu bucket
-v, --verbose runs Jekyll with verbose output
-h, --help display this help and exit
Examples:
jkl generates site from current working directory
jkl /path/to/site generates site from source dir /path/to/site
jkl --server generates site and serves at localhost:4000
jkl --server --port=:4567 generates site and serves at localhost:4567
jkl --s3 --verbose copies the _site directory to s3
jkl --qiniu --verbose copies the _site directory to Qiniu Cloud Storage
Report bugs to <https://github.com/why404/jkl/issues>
jkl home page: <https://github.com/why404/jkl>
Jekyll home page: <http://jekyllrb.com/>`)
}