|
|
|
@ -0,0 +1,162 @@
|
|
|
|
|
#! python
|
|
|
|
|
"""
|
|
|
|
|
This is an alternative to `git_hooks_post-receive.sh`
|
|
|
|
|
The post commit hook in Gitea would include something like the following to ensure this script is called.
|
|
|
|
|
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
read oldrev newrev ref
|
|
|
|
|
python "D:\dev\websites\sandpoints-dev\custom_syadmin\git_hooks_post-receive.py" \
|
|
|
|
|
--git_repo "D:\dev\websites\pirate-care-syllabus\gitea\gitea-repositories\gitea\pirate-care-syllabus.git" \
|
|
|
|
|
--website "D:\dev\websites\testing-ground\sandpoints" \
|
|
|
|
|
--website_preview "D:\dev\websites\testing-ground\sandpoints\_preview" \
|
|
|
|
|
--hugo_preview_url https://syllabus.pirate.care/_preview/ \
|
|
|
|
|
--library "D:\dev\websites\pirate-care-syllabus\_library" \
|
|
|
|
|
--tmp_dir "D:\tmp\tmp"
|
|
|
|
|
--oldrev $oldrev \
|
|
|
|
|
--newrev $newrev \
|
|
|
|
|
--ref $ref
|
|
|
|
|
|
|
|
|
|
To test this script from the command line without relying on a commit hook being triggered, use:
|
|
|
|
|
|
|
|
|
|
python "D:\dev\websites\sandpoints-dev\custom_syadmin\git_hooks_post-receive.py" --ref refs/heads/master --git_repo "D:\dev\websites\pirate-care-syllabus\gitea\gitea-repositories\gitea\pirate-care-syllabus.git" --website D:\\dev\\websites\\testing-ground\\sandpoints --website_preview D:\\dev\\websites\\testing-ground\\sandpoints\\_preview --tmp_dir D:\\tmp\\tmp --git_url "http://localhost:3000/gitea/pirate-care-syllabus" --base_url "http://localhost:8000"
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
import os
|
|
|
|
|
import argparse
|
|
|
|
|
import random
|
|
|
|
|
import string
|
|
|
|
|
import subprocess
|
|
|
|
|
import shutil
|
|
|
|
|
import stat
|
|
|
|
|
from datetime import datetime
|
|
|
|
|
|
|
|
|
|
# format for dates
|
|
|
|
|
date_format = "%m/%d/%Y, %H:%M:%S"
|
|
|
|
|
|
|
|
|
|
# Set the variables we'll be allowing for (as CL arg or environment variable)
|
|
|
|
|
vars = {
|
|
|
|
|
'oldrev': False, # set programmatically by git hook
|
|
|
|
|
'newrev': False, # set programmatically by git hook
|
|
|
|
|
'ref': False, # set programmatically by git hook
|
|
|
|
|
'library': '_library',
|
|
|
|
|
'website': '_website',
|
|
|
|
|
'website_preview': '_websitepreview',
|
|
|
|
|
'git_repo': False,
|
|
|
|
|
'base_url': False, #override the site's base
|
|
|
|
|
'git_url': False,
|
|
|
|
|
'git_path': 'git',
|
|
|
|
|
'hugo_path': 'hugo',
|
|
|
|
|
'tmp_dir': '/tmp',
|
|
|
|
|
'force': False,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# logging time
|
|
|
|
|
start_time = datetime.now().strftime(date_format)
|
|
|
|
|
|
|
|
|
|
def random_string(length=3):
|
|
|
|
|
""" Generates a random string """
|
|
|
|
|
letters = string.ascii_lowercase
|
|
|
|
|
return ''.join(random.choice(letters) for i in range(length))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_value(name, default=False):
|
|
|
|
|
""" Variables can be set as environment variable or in command line """
|
|
|
|
|
if hasattr(args, name.lower()) and getattr(args, name.lower()) is not None:
|
|
|
|
|
print('CLI:', name, getattr(args, name.lower()))
|
|
|
|
|
return getattr(args, name.lower())
|
|
|
|
|
elif name.upper() in os.environ:
|
|
|
|
|
print('env:', name, os.environ[name.upper()])
|
|
|
|
|
return os.environ[name.upper()]
|
|
|
|
|
else:
|
|
|
|
|
print('default:', name, default)
|
|
|
|
|
return default
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def cmd(parts, cwd=None, env=None):
|
|
|
|
|
""" Executes a shell command and returns the output """
|
|
|
|
|
print(f"Command: {' '.join(parts)} ({cwd})")
|
|
|
|
|
return subprocess.check_output(parts, cwd=cwd, env=env, universal_newlines=True).strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def rmrf(path):
|
|
|
|
|
""" Use safe-rm for recursive removal """
|
|
|
|
|
""" @TODO: make it safer """
|
|
|
|
|
def remove_readonly(func, path, excinfo):
|
|
|
|
|
os.chmod(path, stat.S_IWRITE)
|
|
|
|
|
func(path)
|
|
|
|
|
# Try removal
|
|
|
|
|
if os.path.exists(path) and len(os.path.realpath(path)) > 1:
|
|
|
|
|
shutil.rmtree(path, onerror=remove_readonly)
|
|
|
|
|
else:
|
|
|
|
|
print("Either the path doesn't exist or you are trying to delete the root directory(?!):", path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def clobber(filepath, data, append=False):
|
|
|
|
|
""" Equivalent of > or >> when append is True """
|
|
|
|
|
mode = 'a' if append else 'w'
|
|
|
|
|
with open(filepath, mode) as f:
|
|
|
|
|
f.write(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_site(dest, tmp, hugo_environment='gitea'):
|
|
|
|
|
""" builds the website to "dest" using "tmp" as an intermediate location """
|
|
|
|
|
global GIT_PATH, GIT_REPO, HUGO_PATH
|
|
|
|
|
cmd([GIT_PATH, 'clone', '.', tmp], cwd=GIT_REPO)
|
|
|
|
|
rmrf(dest)
|
|
|
|
|
try:
|
|
|
|
|
os.makedirs(dest, exist_ok=True)
|
|
|
|
|
except:
|
|
|
|
|
print(f"Error creating the directory: {dest}")
|
|
|
|
|
lcl = f'{tmp}/last-commit-log.txt'
|
|
|
|
|
# overriding hugo config for development environments
|
|
|
|
|
env = os.environ.copy()
|
|
|
|
|
if BASE_URL:
|
|
|
|
|
env["HUGO_PARAMS_BASEURL"] = BASE_URL
|
|
|
|
|
if GIT_URL:
|
|
|
|
|
env["HUGO_PARAMS_GITURL"] = GIT_URL
|
|
|
|
|
# run the hugo command
|
|
|
|
|
hugo_output = cmd([HUGO_PATH, '-e', hugo_environment, '-d', dest], cwd=tmp, env=env)
|
|
|
|
|
clobber(lcl, hugo_output)
|
|
|
|
|
now_time = datetime.now().strftime(date_format)
|
|
|
|
|
clobber(lcl, f"\n{start_time}\n{now_time}", append=True)
|
|
|
|
|
shutil.move(lcl, dest)
|
|
|
|
|
rmrf(tmp)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Parsing command line arguments
|
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
|
for v in vars:
|
|
|
|
|
parser.add_argument(f"--{v.lower()}")
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
# Load all variables from command line arguments or environment variables
|
|
|
|
|
for v in vars:
|
|
|
|
|
globals()[v.upper()] = get_value(v.lower(), vars[v])
|
|
|
|
|
|
|
|
|
|
# set up directories
|
|
|
|
|
os.makedirs(WEBSITE, exist_ok=True)
|
|
|
|
|
os.makedirs(WEBSITE_PREVIEW, exist_ok=True)
|
|
|
|
|
TMP_WEBSITE = os.path.join(TMP_DIR, 'website', random_string())
|
|
|
|
|
TMP_WEBSITE_PREVIEW = os.path.join(TMP_DIR, 'websitepreview', random_string())
|
|
|
|
|
os.makedirs(TMP_WEBSITE, exist_ok=True)
|
|
|
|
|
os.makedirs(TMP_WEBSITE_PREVIEW, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
# start working
|
|
|
|
|
# Check if someone edited the publish trigger
|
|
|
|
|
published = False
|
|
|
|
|
refs = cmd([GIT_PATH, 'diff-tree', '--no-commit-id', '--name-only', REF], cwd=GIT_REPO).split("\n")
|
|
|
|
|
for r in refs:
|
|
|
|
|
if FORCE or r == "PUBLISH.trigger.md":
|
|
|
|
|
build_site(WEBSITE, TMP_WEBSITE)
|
|
|
|
|
published = True
|
|
|
|
|
# Check if there is a !publish!
|
|
|
|
|
if not published:
|
|
|
|
|
refs = cmd([GIT_PATH, 'show', '--format="%s"', '-s'], cwd=GIT_REPO).split(' ')
|
|
|
|
|
for r in refs:
|
|
|
|
|
if r == "!publish!":
|
|
|
|
|
build_site(WEBSITE, TMP_WEBSITE)
|
|
|
|
|
published = True
|
|
|
|
|
# create preview version
|
|
|
|
|
build_site(WEBSITE_PREVIEW, TMP_WEBSITE_PREVIEW, hugo_environment='preview')
|
|
|
|
|
|
|
|
|
|
# @TODO: link the library
|