diff options
Diffstat (limited to 'cli/cli.py')
-rw-r--r-- | cli/cli.py | 221 |
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 |