-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
dev
executable file
·138 lines (114 loc) · 4 KB
/
dev
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
#!/usr/bin/env python3
# ./dev -h
import argparse
from http.client import HTTPException
import os
from subprocess import run
import sys
from threading import Thread
import time
from urllib.error import URLError
from urllib.request import urlopen
import webbrowser
parser = argparse.ArgumentParser(prog='./dev')
subparsers = parser.add_subparsers(metavar='<command>', title='commands')
LOCAL_SITE = 'http://localhost:1313'
def command(help):
def decorator(func):
parser = subparsers.add_parser(
func.__name__.replace('_', '-'), help=help
)
parser.set_defaults(func=func)
return func
return decorator
def run_command(command, bind_port=False):
return run(
[
'docker', 'run', '--init', '--rm', '-v',
f'{os.getcwd()}:/src:cached'
] +
(['-p', '1313:1313'] if bind_port else []) +
(['-it'] if sys.stdout.isatty() else []) + ['dannyguo-dev'] + command
).returncode
def open_in_browser():
while True:
try:
urlopen(LOCAL_SITE)
break
except (ConnectionError, URLError, HTTPException):
time.sleep(1)
webbrowser.open(LOCAL_SITE)
@command('Sync the search index with Algolia')
def algolia(args, remaining):
if os.environ.get('CI') == 'true':
with open('template.env') as template, open('.env', 'w') as env:
for line in template:
if '=' in line and line[0] != '#':
split = line.strip().split('=')
key = split[0]
value = os.environ.get(key, split[1])
env.write(f'{key}={value}\n')
elif not os.path.isfile('.env'):
print('Aborting: create a .env file based off of template.env')
return 1
with open('template.env') as template:
required_variables = {
line.split('=')[0] for line in template
if '=' in line and line[0] != '#'
}
with open('.env') as env:
set_variables = {
line.split('=')[0] for line in env
if '=' in line and line[0] != '#'
}
missing_variables = required_variables - set_variables
if missing_variables:
print('Your .env is missing these variables:')
print(', '.join(missing_variables))
return 1
# Generate the search index by generating the site
rc = hugo(None, None)
if rc:
return rc
return run_command(['yarn', 'run', 'update-search-index'])
@command('Build a Docker image for development')
def build_docker(args, remaining):
return run(['docker', 'build', '-t', 'dannyguo-dev', '.']).returncode
@command('Run a Hugo command')
def hugo(args, remaining):
return run_command(['hugo'] + (remaining or []))
@command('Run linters')
def lint(args, remaining):
rc = hugo(None, None)
if rc:
return rc
return run_command(['yarn', 'run', 'lint'])
def new(args, remaining):
return run_command(['hugo', 'new', f'blog/{args.title}.md'])
new_parser = subparsers.add_parser('new', help='Generate a new blog post')
new_parser.add_argument('title', help="title of the post in kebab-case")
new_parser.set_defaults(func=new)
@command('Serve the prod site locally')
def prod(args, remaining):
Thread(target=open_in_browser).start()
run_command(['hugo', 'server', '--bind', '0.0.0.0'], True)
@command('View the website in your browser')
def view(args, remaining):
webbrowser.open(LOCAL_SITE)
@command('Open a shell')
def sh(args, remaining):
return run_command(['sh'])
@command('Start development')
def start(args, remaining):
Thread(target=open_in_browser).start()
run_command(['hugo', 'server', '--bind', '0.0.0.0', '--buildDrafts'], True)
@command('Run a Yarn command')
def yarn(args, remaining):
return run_command(['yarn'] + (remaining or []))
if __name__ == '__main__':
if len(sys.argv) > 1:
args, remaining = parser.parse_known_args()
returncode = args.func(args, remaining)
sys.exit(returncode)
else:
parser.print_help()