Create a python script for pushing changes to the git repo
This commit is contained in:
parent
ee520f849b
commit
c1e3025ed3
|
@ -0,0 +1,7 @@
|
|||
with import <nixpkgs> {};
|
||||
|
||||
(pkgs.python310.buildEnv.override {
|
||||
extraLibs = with pkgs.python310Packages; [
|
||||
GitPython
|
||||
];
|
||||
}).env
|
|
@ -0,0 +1,183 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from git import Repo
|
||||
from git import Actor
|
||||
import shutil
|
||||
import os
|
||||
|
||||
WORKING_DIR = "/tmp/push-dotfiles"
|
||||
GIT_REPO_URL = "git@git.seanomik.net:SeanOMik/nixos-dotfiles.git"
|
||||
|
||||
## Get a yes or no answer from the user and handle invalid input
|
||||
def get_yes_no_answer(question: str, error_msg: str = "ERROR: Malformed input!"):
|
||||
ans = ""
|
||||
|
||||
while ans != "y" or ans != "n":
|
||||
print(f"{question} (y,n): ", end="")
|
||||
ans = input()
|
||||
|
||||
if ans != "y" or ans != "n":
|
||||
print(error_msg)
|
||||
|
||||
if ans == "y":
|
||||
return True
|
||||
elif ans == "n":
|
||||
return False
|
||||
|
||||
## Clears the working directory
|
||||
def remove_working_dir():
|
||||
if os.path.exists(WORKING_DIR):
|
||||
shutil.rmtree(WORKING_DIR)
|
||||
print(f"Removed working directory ({WORKING_DIR}).")
|
||||
else:
|
||||
print(f"Skipping deletion of working directory since it doesn't exist.")
|
||||
|
||||
## Copy the dotfiles (/etc/nixos) to the working directory
|
||||
def copy_dotfiles():
|
||||
src_directory = "/etc/nixos"
|
||||
for filename in os.listdir(src_directory):
|
||||
if filename == ".git":
|
||||
continue
|
||||
else:
|
||||
full_path = os.path.join(src_directory, filename)
|
||||
if os.path.isdir(full_path):
|
||||
shutil.copytree(full_path, os.path.join(WORKING_DIR, filename))
|
||||
else:
|
||||
shutil.copy(full_path, WORKING_DIR)
|
||||
|
||||
print("Copied \"/etc/nixos\" dotfiles to working directory.")
|
||||
|
||||
## Clone the git repository to the working dir
|
||||
def clone_git_repo():
|
||||
print("Cloning git repository...")
|
||||
Repo.clone_from(GIT_REPO_URL, WORKING_DIR)
|
||||
print("Cloned git repository!")
|
||||
|
||||
## Clear the working directory
|
||||
def clear_working_dir():
|
||||
for filename in os.listdir(WORKING_DIR):
|
||||
if filename == ".git" or filename.endswith(".py") or filename == "shell.nix":
|
||||
continue
|
||||
else:
|
||||
full_path = os.path.join(WORKING_DIR, filename)
|
||||
if os.path.isdir(full_path):
|
||||
shutil.rmtree(full_path)
|
||||
else:
|
||||
os.remove(full_path)
|
||||
print("Cleared git repo...")
|
||||
|
||||
## Get the git repository in the working dir
|
||||
def get_git_repo():
|
||||
return Repo(WORKING_DIR)
|
||||
|
||||
## Stage changes
|
||||
def stage_git_changes(repo: Repo):
|
||||
file_diff_list = []
|
||||
|
||||
# TODO: Check for the staged changes also
|
||||
diff = repo.index.diff(None)
|
||||
|
||||
if len(diff) == 0:
|
||||
diff = repo.index.diff("HEAD")
|
||||
|
||||
if len(diff) == 0:
|
||||
print("ERROR: No changes have been made!")
|
||||
exit()
|
||||
else:
|
||||
print("All changes are already staged...")
|
||||
return
|
||||
|
||||
print("Git diff:")
|
||||
for item in diff:
|
||||
if item.deleted_file:
|
||||
print(f" D - {item.a_path}")
|
||||
|
||||
file_diff_list.append(os.path.join(repo.working_tree_dir, item.a_path))
|
||||
elif item.new_file:
|
||||
print(f" N - {item.b_path}")
|
||||
|
||||
file_diff_list.append(os.path.join(repo.working_tree_dir, item.b_path))
|
||||
elif item.renamed_file:
|
||||
print(f" R - {item.a_path} to {item.b_path}")
|
||||
|
||||
file_diff_list.append(os.path.join(repo.working_tree_dir, item.b_path))
|
||||
else:
|
||||
print(f" C - {item.a_path}")
|
||||
|
||||
file_diff_list.append(os.path.join(repo.working_tree_dir, item.a_path))
|
||||
|
||||
ans = get_yes_no_answer("Stage entire diff?")
|
||||
|
||||
if ans:
|
||||
for diff in file_diff_list:
|
||||
repo.git.add(diff)
|
||||
|
||||
print("Staged all changes")
|
||||
else:
|
||||
print("TODO: Create numbered list to only stage certain files") # TODO
|
||||
|
||||
## Get the author from the user
|
||||
def get_git_author(repo: Repo):
|
||||
ans = get_yes_no_answer("Use git config user?")
|
||||
if ans:
|
||||
username = repo.config_reader().get_value("user", "name")
|
||||
email = repo.config_reader().get_value("user", "email")
|
||||
|
||||
print(f"Got git author:\n Username: {username}\n Email: {email}")
|
||||
|
||||
ans = get_yes_no_answer("Is this author correct?")
|
||||
|
||||
if ans:
|
||||
return Actor(username, email)
|
||||
else:
|
||||
return get_git_author(repo)
|
||||
else:
|
||||
print("Enter username: ", end="")
|
||||
username = input()
|
||||
|
||||
print("Enter email: ", end="")
|
||||
email = input()
|
||||
|
||||
return Actor(username, email)
|
||||
|
||||
## Commit changes
|
||||
def commit_changes(repo: Repo, message: str, author: Actor):
|
||||
res = repo.git.commit('-S', '-m', f'"{message}"', author=f'"{author.name} <{author.email}>"')
|
||||
print(res)
|
||||
print("Committed changes!")
|
||||
|
||||
## Push git changes to the repo!
|
||||
def push_git_changes():
|
||||
repo = get_git_repo()
|
||||
stage_git_changes(repo)
|
||||
|
||||
ans = ""
|
||||
|
||||
while len(ans) == 0:
|
||||
print("Commit message: ", end="")
|
||||
ans = input()
|
||||
|
||||
if len(ans) == 0:
|
||||
print("ERROR: Cannot use an empty commit message!")
|
||||
|
||||
commit_changes(repo, ans, get_git_author(repo))
|
||||
|
||||
# Actually push now
|
||||
print("Pushing changes...")
|
||||
origin = repo.remote(name='origin')
|
||||
origin.push()
|
||||
print("Pushed changes!")
|
||||
|
||||
def main():
|
||||
remove_working_dir();
|
||||
|
||||
clone_git_repo();
|
||||
clear_working_dir();
|
||||
|
||||
copy_dotfiles();
|
||||
#push_git_changes();
|
||||
|
||||
print("Done!")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue