summaryrefslogtreecommitdiffstats
path: root/core/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'core/utils.py')
-rw-r--r--core/utils.py213
1 files changed, 118 insertions, 95 deletions
diff --git a/core/utils.py b/core/utils.py
index 798e48f..904faad 100644
--- a/core/utils.py
+++ b/core/utils.py
@@ -45,6 +45,13 @@ sha = hashlib.new('sha256')
COOKIE_MAX_AGE = 12*60*60 # seconds
throw = 35.0
+DEV_OK = """On branch master
+Your branch is ahead of 'origin/master' by 1 commit.
+ (use "git push" to publish your local commits)
+
+nothing to commit, working tree clean
+"""
+
class DatabaseResetOngoing(Exception):
"""Exception class for errors while the server is reimporting everything"""
@@ -126,7 +133,7 @@ def make_new_expo_dir(year):
def current_expo():
"""Returns the current expo year, but also checks if the most recent expo year is the same
as this year. If it is not, then it creates an empty Expedition and fixes some files and
- folders. If were are more than one year out of date, it creates all intervening Expo objects
+ folders. If we are more than one year out of date, it creates all intervening Expo objects
and folders. You will need to tidy this up manually.
"""
expos = Expedition.objects.all().order_by('-year')
@@ -191,61 +198,10 @@ def parse_aliases(aliasfile):
return [(None, None)], "Fail on file reading"
return aliases, report
-def only_commit(fname, message, editor=None):
- """Only used to commit a survex file edited and saved in view/survex.py"""
- git = settings.GIT
- cwd = fname.parent
- filename = fname.name
- # print(f'{fname=} ')
- if editor:
- editor = git_string(editor)
- else:
- # cannot happen as form verification has this as an obligatory field
- editor = "Anathema Device <a.device@potatohut.expo>"
-
- try:
- print(f"git add {filename}")
- cp_add = subprocess.run([git, "add", filename], cwd=cwd, capture_output=True, text=True)
- if cp_add.returncode != 0:
- msgdata = f"Ask a nerd to fix this problem in only_commit().\n--{cp_add.stderr}\n--{cp_add.stdout}\n--return code:{str(cp_add.returncode)}"
- raise WriteAndCommitError(
- f"CANNOT git ADD on server for this file {filename}. Edits saved but not added to git.\n\n" + msgdata
- )
- print(f"git commit {filename}")
- print(f"Committing:\n{message=}\n{editor=}")
- cmd_commit = [git, "commit", "-m", message, "--author", f"{editor}"]
-
- cp_commit = subprocess.run(cmd_commit, cwd=cwd, capture_output=True, text=True)
- # This produces return code = 1 if it commits OK, but when the local repo still needs to be pushed to origin/loser
- # which will be the case when running a test troggle system on a development machine
- devok_text = """On branch master
-Your branch is ahead of 'origin/master' by 1 commit.
- (use "git push" to publish your local commits)
-
-nothing to commit, working tree clean
-"""
- if cp_commit.returncode == 1 and cp_commit.stdout == devok_text:
- pass
- else:
- if cp_commit.returncode != 0 and not cp_commit.stdout.strip().endswith(
- "nothing to commit, working tree clean"
- ):
- msgdata = f'--Ask a nerd to fix this problem in only_commit().\n--{cp_commit.stderr}\n--"{cp_commit.stdout}"\n--return code:{str(cp_commit.returncode)}'
- print(msgdata)
- raise WriteAndCommitError(
- f"Error code with git on server for this file {filename}. Edits saved, added to git, but NOT committed.\n\n"
- + msgdata
- )
-
- except subprocess.SubprocessError:
- msg = f"CANNOT git COMMIT on server for this file {filename}. Subprocess error. Edits not saved.\nAsk a nerd to fix this."
- print(msg)
- raise WriteAndCommitError(msg)
-
def git_string(author_string):
"""Rewrites the supplied editor string intoa git-complient author string
- Uses a regular expression for a git-compatible author string
+ Uses a regular expression for a git-compatible author string written mostly by Copilot
valid example "John Doe <john.doe@example.com>"
"""
author_regex = re.compile(r'^[a-zA-Z][\w\s\_\.\-]* <[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-_]+\.[a-zA-Z]{2,}>$')
@@ -259,25 +215,103 @@ def git_string(author_string):
editor += f" <{editor}@potatohut.expo>"
print(f"Not git-compatible author string, replacing as '{editor}'")
return editor
+
+
+def git_add(filename, cwd, commands=[]):
+ """Add a file to the list of Staged files ready for a later git commit
+ """
+ git = settings.GIT
+
+ # what is the purpose of this 'git diff' ? To prevent merge conflicts happening I guess,
+ # so we do not have to reverse a 'git add'
+ print(f"git diff {filename}")
+ cmd_diff = [git, "diff", filename]
+ commands.append(cmd_diff)
+ cp_diff = subprocess.run(cmd_diff, cwd=cwd, capture_output=True, text=True)
+ if cp_diff.returncode != 0:
+ msgdata = f"Ask a nerd to fix this DIFF problem in git_add().\n--{cp_diff.stderr}\n--{cp_diff.stdout}\n--return code:{str(cp_diff.returncode)}"
+ raise WriteAndCommitError(
+ f"CANNOT git ADD on server for this file {filename}.\n\n" + msgdata
+ )
+
+ print(f"git add {filename}")
+ cmd_add = [git, "add", filename]
+ commands.append(cmd_add)
+ cp_add = subprocess.run(cmd_add, cwd=cwd, capture_output=True, text=True)
+ if cp_add.returncode != 0:
+ msgdata = f"Ask a nerd to fix this ADD problem in git_add().\n--{cp_add.stderr}\n--{cp_add.stdout}\n--return code:{str(cp_add.returncode)}"
+ raise WriteAndCommitError(
+ f"CANNOT git ADD on server for this file {filename}.\n\n" + msgdata
+ )
+ return commands
+
+
+def git_commit(cwd, message, editor, commands=[]):
+ """Commits whatever has been Staged by git in this directory
+ """
+ git = settings.GIT
+ print(f"git commit in {cwd}")
+ print(f"Committing:\n{message=}\n{editor=}")
+ cmd_commit = [git, "commit", "-m", message, "--author", f"{editor}"]
+ commands.append(cmd_commit)
+
+ cp_commit = subprocess.run(cmd_commit, cwd=cwd, capture_output=True, text=True)
+ # This produces return code = 1 if it commits OK, but when the local repo still needs to be pushed to origin/repo
+ # which will be the case when running a test troggle system on a development machine
+ if cp_commit.returncode == 1 and cp_commit.stdout == DEV_OK: # only good for 1 commit ahead of origin/repo
+ pass
+ else:
+ if cp_commit.returncode != 0 and not cp_commit.stdout.strip().endswith(
+ "nothing to commit, working tree clean"
+ ):
+ msgdata = f'--Ask a nerd to fix this problem in add_commit().\n--{cp_commit.stderr}\n--"{cp_commit.stdout}"\n--return code:{str(cp_commit.returncode)}'
+ print(msgdata)
+ raise WriteAndCommitError(
+ f"Error code with git on server in this directory: {cwd}. Edits saved, added to git, but NOT committed.\n\n"
+ + msgdata
+ )
+ return commands
+
+def add_commit(fname, message, editor=None):
+ """Only used to commit a survex file edited and saved in view/survex.py"""
+ cwd = fname.parent
+ filename = fname.name
+ commands = []
+
+ if editor:
+ editor = git_string(editor)
+ else:
+ # 'cannot happen' as form verification has this as an obligatory field
+ editor = "Anathema Device <a.device@potatohut.expo>"
+
+ try:
+ commands = git_add(filename, cwd, commands)
+ commands = git_commit(cwd, message, editor, commands)
+
+ except subprocess.SubprocessError:
+ msg = f"CANNOT git ADD or COMMIT on server for this file {filename}.\nSubprocess error: {commands}\nEdits probably not saved.\nAsk a nerd to fix this."
+ print(msg)
+ raise WriteAndCommitError(msg)
+
def write_and_commit(files, message, editor=None):
"""Writes the content to the filepath and adds and commits the file to git. If this fails, a WriteAndCommitError is raised.
- This needs refactoring to just write and then call only_commit()
+ This needs refactoring to just write and then call add_commit()
"""
+ # GIT see also core/views/uploads.py dwgupload()
+ # GIT see also core/views/expo.py editexpopage()
git = settings.GIT
commands = []
if editor:
editor = git_string(editor)
else:
# cannot happen as form verification has this as an obligatory field
- editor = "Automatic <automaton@potatohut.expo>"
+ editor = "Write_and_commit <automaton@potatohut.expo>"
try:
for filepath, content, encoding in files:
cwd = filepath.parent
filename = filepath.name
- # GIT see also core/views/uploads.py dwgupload()
- # GIT see also core/views/expo.py editexpopage()
os.makedirs(os.path.dirname(filepath), exist_ok = True)
if filepath.is_dir():
raise WriteAndCommitError(
@@ -301,7 +335,10 @@ def write_and_commit(files, message, editor=None):
except Exception as e:
raise WriteAndCommitError(
f"CANNOT write this file {filepath}. Ask a nerd to fix this: {e}"
- )
+ )
+
+ # what is the purpose of this 'git diff' ? To prevent merge conflicts happening I guess,
+ # so we do not have to reverse a 'git add'
cmd_diff = [git, "diff", filename]
cp_diff = subprocess.run(cmd_diff, cwd=cwd, capture_output=True, text=True)
commands.append(cmd_diff)
@@ -328,41 +365,27 @@ def write_and_commit(files, message, editor=None):
print(f"No change {filepath}")
filepaths = [filepath for filepath, content, encoding in files]
# message = message + " " + str(filepaths)
- print([git, "commit", "-m", message, "--author", f"{editor}"])
- cmd_commit = [git, "commit", "-m", message, "--author", f"{editor}"]
- cm_status = subprocess.run(cmd_commit, cwd=cwd, capture_output=True, text=True)
- commands.append(cmd_commit)
- if cm_status.returncode != 0:
- msgdata = (
- "Commands: " + str(commands) +
- "Ask a nerd to fix this.\n\n"
- + "Stderr: " + cm_status.stderr
- + "\n\n"
- + "Stdout: " + cm_status.stdout
- + "\n\nreturn code: " + str(cm_status.returncode)
- + "\n\ngit add return code in previous operation was: " + git_add_returncode
- )
- raise WriteAndCommitError(
- f"ERROR committing. Edits saved, [maybe] added to git, but NOT committed.\n\n"
- + msgdata
- )
- cmd_status = [git, "status"] # + filepaths
- cp_status = subprocess.run(cmd_status, cwd=cwd, capture_output=True, text=True)
- commands.append(cp_status)
- #This produces return code = 1 if it commits OK, but when the repo still needs to be pushed to origin/expoweb
- if (not cp_status.stdout) or len(cp_status.stdout) < 2 or cp_status.stdout.split("\n")[-2] != "nothing to commit, working tree clean":
- msgdata = (
- str(commands) +
- "Ask a nerd to fix this.\n\n"
- + "Stderr: " + cp_status.stderr
- + "\n\n"
- + "Stdout: " + cp_status.stdout
- + "\n\nreturn code: " + str(cp_status.returncode)
- )
- raise WriteAndCommitError(
- f"Error code with git on server for this file {filename}. Edits saved, added to git, but NOT committed. Git status not clean.\n\n"
- + msgdata
- )
+
+ commands = git_commit(cwd, message, editor, commands)
+
+ if False:
+ cmd_status = [git, "status"] # + filepaths
+ cp_status = subprocess.run(cmd_status, cwd=cwd, capture_output=True, text=True)
+ commands.append(cp_status)
+ #This produces return code = 1 if it commits OK, but when the repo still needs to be pushed to origin/expoweb
+ if (not cp_status.stdout) or len(cp_status.stdout) < 2 or cp_status.stdout.split("\n")[-2] != "nothing to commit, working tree clean":
+ msgdata = (
+ str(commands) +
+ "Ask a nerd to fix this.\n\n"
+ + "Stderr: " + cp_status.stderr
+ + "\n\n"
+ + "Stdout: " + cp_status.stdout
+ + "\n\nreturn code: " + str(cp_status.returncode)
+ )
+ raise WriteAndCommitError(
+ f"Error code with git on server for this file {filename}. Edits saved, added to git, but NOT committed. Git status not clean.\n\n"
+ + msgdata
+ )
except subprocess.SubprocessError:
raise WriteAndCommitError(
f"CANNOT git on server for this file {filename}. Subprocess error. Edits not saved.\nAsk a nerd to fix this."
@@ -387,13 +410,13 @@ def writetrogglefile(filepath, filecontent, commit_msg=None):
core/models/caves.py
and by
make_new_expo_dir(year)
+ but NOT by core/views/caves.py
Commit the new saved file to git
- Callers to cave.writeDataFile() or entrance.writeDataFile() should handle the exception PermissionsError explicitly
+
"""
# GIT see also core/views/expo.py editexpopage()
# GIT see also core/views/uploads.py dwgupload()
- # Called from core/models/caves.py Cave.writeDataFile() Entrance.writeDataFile()
filepath = Path(filepath)
cwd = filepath.parent
filename = filepath.name