aboutsummaryrefslogtreecommitdiff
path: root/cli/cli.py
diff options
context:
space:
mode:
Diffstat (limited to 'cli/cli.py')
-rw-r--r--cli/cli.py221
1 files changed, 0 insertions, 221 deletions
diff --git a/cli/cli.py b/cli/cli.py
deleted file mode 100644
index 9d35c643..00000000
--- a/cli/cli.py
+++ /dev/null
@@ -1,221 +0,0 @@
-#/bin/python3
-
-import subprocess
-import sys
-import re
-import time
-import signal
-
-from config.config import *
-from utils import utils
-from generators import generators
-
-
-def generate(args):
- """Wrapper for generate_blog(fresh=False)."""
- # pylint: disable=unused-argument
- exit(generators.generate_blog(fresh=False))
-
-
-def regenerate(args):
- """Wrapper for generate_blog(fresh=True)."""
- # pylint: disable=unused-argument
- exit(generators.generate_blog(fresh=True))
-
-
-def deploy(args):
- """Deploys build directory to origin/master without regenerating.
-
- Returns
- -------
- 0
- On success. Exit early with nonzero status otherwise.
-
- """
-
- # pylint: disable=unused-argument,too-many-statements
-
- # check whether root is dirty
- os.chdir(ROOTDIR)
- dirty = subprocess.check_output(["git", "status", "--porcelain"])
- if dirty:
- sys.stderr.write(YELLOW)
- sys.stderr.write("Project root is dirty.\n")
- sys.stderr.write("You may want to commit in your changes "
- "to the source branch, since the SHA and title "
- "of the latest commit on the source branch will be "
- "incorporated into the commit message on "
- "the deployment branch. Type s[hell] on the "
- "next prompt to open an interactive shell.\n")
- sys.stderr.write(RESET)
- while True:
- sys.stderr.write("Continue? [yNs] ")
- answer = input()
- if not answer:
- # default
- abort = True
- break
- elif answer.startswith(('y', 'Y')):
- abort = False
- break
- elif answer.startswith(('n', 'N')):
- abort = True
- break
- elif answer.startswith(('s', 'S')):
- shell = (os.environ['SHELL'] if 'SHELL' in os.environ and os.environ['SHELL']
- else 'zsh')
- subprocess.call(shell)
- stilldirty = subprocess.check_output(["git", "status", "--porcelain"])
- if stilldirty:
- sys.stderr.write(YELLOW)
- sys.stderr.write("Project root is still dirty.\n")
- sys.stderr.write(RESET)
- else:
- sys.stderr.write("Please answer yes or no.\n")
- if abort:
- sys.stderr.write("%saborting deployment%s\n" % (RED, RESET))
- return 1
-
- # extract latest commit on the source branch
- source_commit = subprocess.check_output(
- ["git", "log", "-1", "--pretty=oneline", "source", "--"]).decode('utf-8').strip()
-
- # cd into BUILDDIR and assemble commit message
- sys.stderr.write("%scommand: cd '%s'%s\n" % (BLUE, BUILDDIR, RESET))
- os.chdir(BUILDDIR)
-
- # extract updated time from atom.xml
- if not os.path.exists("atom.xml"):
- sys.stderr.write("atom.xml not found, cannot deploy\naborting\n")
- return 1
- atomxml = ET.parse("atom.xml").getroot()
- updated = atomxml.find('{http://www.w3.org/2005/Atom}updated').text
-
- commit_message = ("Site updated at %s\n\nsource branch was at:\n%s\n" %
- (updated, source_commit))
-
- # commit changes in BUILDDIR
- sys.stderr.write("%scommand: git add --all%s\n" % (BLUE, RESET))
- subprocess.check_call(["git", "add", "--all"])
- sys.stderr.write("%scommand: git commit --no-verify --gpg-sign --message='%s'%s\n" %
- (BLUE, commit_message, RESET))
- try:
- subprocess.check_call(["git", "commit", "--gpg-sign",
- "--message=%s" % commit_message])
- except subprocess.CalledProcessError:
- sys.stderr.write("\n%serror: git commit failed%s\n" % (RED, RESET))
- return 1
-
- # check dirty status
- dirty = subprocess.check_output(["git", "status", "--porcelain"])
- if dirty:
- sys.stderr.write(RED)
- sys.stderr.write("error: failed to commit all changes; "
- "build directory still dirty\n")
- sys.stderr.write("error: please manually inspect what was left out\n")
- sys.stderr.write(RESET)
- return 1
-
- # push to origin/master
- sys.stderr.write("%scommand: git push origin master%s\n" % (BLUE, RESET))
- try:
- subprocess.check_call(["git", "push", "origin", "master"])
- except subprocess.CalledProcessError:
- sys.stderr.write("\n%serror: git push failed%s\n" % (RED, RESET))
- return 1
- return 0
-
-
-def gen_deploy(args):
- """Regenerate and deploy."""
- # pylint: disable=unused-argument,too-many-branches
-
- # try to smartly determine the latest post, and prompt to touch it
- current_time = time.time()
- latest_post = None
- latest_postdate = 0
- latest_mtime = 0
- for name in os.listdir(POSTSDIR):
- matchobj = re.match(r"^([0-9]{4})-([0-9]{2})-([0-9]{2})-.*\.md", name)
- if not matchobj:
- continue
- fullpath = os.path.join(POSTSDIR, name)
- mtime = os.path.getmtime(fullpath)
- # get post date from the date metadata field of the post
- postdate = 0
- with open(fullpath) as postobj:
- for line in postobj:
- dateregex = r"^date: (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}-\d{2}:?\d{2})"
- datematch = re.match(dateregex, line.rstrip())
- if datematch:
- postdate = dateutil.parser.parse(datematch.group(1)).timestamp()
- break
- # skip the post if it is dated more than three days ago
- if current_time - postdate > 3 * 24 * 3600:
- continue
- if mtime > latest_mtime:
- latest_post = name
- latest_postdate = postdate
- latest_mtime = mtime
- # prompt for touching if the latest post determined above was
- # modified within the last hour but the date registered in the post
- # isn't within the last ten minutes
- if ((latest_post is not None and current_time - latest_mtime < 3600 and
- current_time - latest_postdate > 600)):
- sys.stderr.write("%sIt appears that %s might be a new post.\n"
- "Do you want to touch its timestamp?%s\n" %
- (GREEN, latest_post, RESET))
- while True:
- yesnoquit = input("[ynq]: ")
- if yesnoquit.startswith(("Y", "y")):
- yesno = True
- break
- elif yesnoquit.startswith(("N", "n")):
- yesno = False
- break
- elif yesnoquit.startswith(("Q", "q")):
- sys.stderr.write("%saborting gen_deploy%s\n" % (RED, RESET))
- return 1
- else:
- sys.stderr.write("Please answer yes, no, or quit.\n")
- if yesno:
- sys.stderr.write("%stouching %s%s\n" % (BLUE, latest_post, RESET))
- touch(latest_post)
- sys.stderr.write("\n")
-
- generators.generate_blog(fresh=True)
- deploy(None)
-
-
-def preview(args):
- """Serve the blog and auto regenerate upon changes."""
-
- # pylint: disable=unused-argument
-
- server_process = utils.HTTPServerProcess(BUILDDIR)
- server_process.start()
- sys.stderr.write("watching for changes\n")
- sys.stderr.write("send SIGINT to stop\n")
-
- # install a SIGINT handler only for this process
- sigint_raised = False
-
- def sigint_mitigator(signum, frame):
- """Translate SIGINT to setting the sigint_raised flag."""
- nonlocal sigint_raised
- sigint_raised = True
-
- signal.signal(signal.SIGINT, sigint_mitigator)
-
- # Watch and auto-regen.
- # No need to actually implement watch separately, since
- # generate_blog(fresh=False, report_total_errors=False) already
- # watches for modifications and only regens upon changes, and it is
- # completely silent when there's no change.
- while not sigint_raised:
- generators.generate_blog(fresh=False, report_total_errors=False)
- time.sleep(0.5)
-
- sys.stderr.write("\nSIGINT received, cleaning up...\n")
- server_process.join()
- return 0