333 lines
14 KiB
Bash
Executable file
333 lines
14 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
# checklist:
|
|
# [-] add -i flag for install script (default if not git repo is found)
|
|
# [-] add -r flag to go back in history (should list rollback and automatically copy commit id to be pasted...)
|
|
|
|
# Error handling
|
|
set -e
|
|
|
|
# For styling/colorizing output
|
|
txtbld=$(tput bold)
|
|
txtblue=${txtbld}$(tput setaf 4)
|
|
txtgreen=${txtbld}$(tput setaf 2)
|
|
txtred=${txtbld}$(tput setaf 1)
|
|
txtyellow=${txtbld}$(tput setaf 3)
|
|
txtwhite=${txtbld}$(tput setaf 7)
|
|
|
|
# Time to rewrite new version:
|
|
# Features to include:
|
|
# setopts/getopts flags for init,delete repos ( see git_create...txt file in notes)
|
|
|
|
# Intro Prompt
|
|
echo "${txtblue}bgit: a handy shell script for automating simple git inits/commits"
|
|
|
|
# Reset output style
|
|
tput bold & tput setaf 7
|
|
|
|
# counts the number of repos
|
|
numrepos=$(git remote | wc -l)
|
|
|
|
# If there are no git repositories in this directory...
|
|
if [ $numrepos -eq 0 ] ; then
|
|
echo "${txtgreen}no git repository found, executing git init...${txtwhite}"
|
|
while [ true ]
|
|
do
|
|
#Prompts the user if they'd like to initialize repository
|
|
read -e -r -p "${txtwhite}initialize repository?(y/n): ${txtyellow}" init
|
|
if [[ $init == "n" || $init = "no" ]]; then
|
|
echo "${txtred}no git repository initialized...exiting${txtwhite}"
|
|
break
|
|
elif [[ $init == "y" || $init == "yes" ]] ; then
|
|
|
|
# Creates a default README.md
|
|
echo -e "## A Simple README\n\nSome Text" > README.md
|
|
# Creates a default .gitignore
|
|
echo -e "node_modules\n*.env\n*.out\n.pretterrc\n.gitignore" > .gitignore
|
|
# Initializes git repository cwd...
|
|
git init
|
|
|
|
# defaults to not requiring gpg key sign
|
|
git config commit.gpgsign false
|
|
|
|
while [ true ];
|
|
do
|
|
# prompts user to change default username/email and changes them if they'd like (no input defaults to global values)
|
|
read -e -r -p "${txtwhite}would you like to change username/password from global defaults?(y/n): ${txtyellow}" changedefaults
|
|
if [[ $changedefaults == "y" || $changedefaults == "yes" ]] ; then
|
|
read -e -r -p "${txtwhite}enter your username: ${txtyellow}" uname
|
|
if [[ -n $uname ]] ; then
|
|
git config user.name $uname
|
|
read -e -r -p "${txtwhite}enter your email: ${txtyellow}" uemail
|
|
if [[ -n $uemail ]] ; then
|
|
git config user.email $uemail
|
|
break
|
|
else
|
|
echo "${txtblue}no email entered, defaulting to global value${txtwhite}"
|
|
break
|
|
fi
|
|
else
|
|
echo "${txtblue}no username entered, defaulting to global value${txtwhite}"
|
|
break
|
|
fi
|
|
else
|
|
echo "${txtblue}defaulting to global username/password${txtwhite}"
|
|
break
|
|
fi
|
|
done
|
|
|
|
while [ true ] ; do
|
|
# initializes standard html/css/javascript project (incomplete)
|
|
read -e -r -p "${txtwhite}would you like to make this an npm project?(y/n): ${txtyellow}" confirmnpm
|
|
if [[ $confirmnpm == "y" || $confirmnpm == "yes" ]] ; then
|
|
npm init -y
|
|
npm install -D nodemon prettier jest
|
|
|
|
# creates default .prettierrc
|
|
echo -e 'trailingComma: "all"\ntabWidth: 4\nsemi: false\nsingleQuote: true\nbracketSpacing: true\narrowParens: "avoid"' > .prettierrc
|
|
|
|
# replace touch commands here with echo later on...
|
|
echo -e '<!DOCTYPE html>\n<html>\n <head>\n <meta charset="utf-8">\n <meta name="viewport" content="width=device-width">\n <title>My Website</title>\n <link rel="stylesheet" href="css/styles.css" />\n </head>\n <body>\n <h1>Header 1</h1>\n <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>\n <script src="scripts/index.js" defer></script>\n </body>\n</html>' > index.html
|
|
mkdir scripts
|
|
mkdir css
|
|
mkdir tests
|
|
touch tests/index.test.js
|
|
echo 'console.log("Hello World!");' > scripts/index.js
|
|
echo -e '* {\n font-family: monospace;\n text-align: center;\n background-color: #dedede;\n}' > css/styles.css
|
|
sed 's/1"/1",/' package.json > package2.json && sed -i '/no test/a\ \ \ \ "start":\ "nodemon\ scripts/index.js"' package2.json && mv package2.json package.json
|
|
break
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Reset output style
|
|
tput bold & tput setaf 7
|
|
|
|
# sane default initial commit message
|
|
git add .
|
|
git commit -m ":tada: Initial commit"
|
|
|
|
while [ true ]
|
|
do
|
|
# allows user to change default branch name (no input defaults to "master")
|
|
read -e -r -p "${txtwhite}change branch name?(y/n): ${txtyellow}" chbranch
|
|
if [[ $chbranch == "y" || $chbranch == "yes" ]] ; then
|
|
read -e -r -p "${txtwhite}branch name?(i.e. 'main'): ${txtyellow}" branch
|
|
if [ -n "$branch" ] ; then
|
|
git branch -M $branch
|
|
break
|
|
else
|
|
echo "${txtred}branch name is empty, please enter branch name!${txtwhite}"
|
|
fi
|
|
else
|
|
echo "${txtblue}branch name will be left as ${txtyellow}'master'${txtwhite}"
|
|
branch="master"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# main git init loop
|
|
while [ true ]
|
|
do
|
|
uname=$(git config user.name)
|
|
read -e -r -p "${txtwhite}Please enter remote to add(i.e. origin): ${txtyellow}" remote
|
|
|
|
# if the user doesn't enter anything for the remote prompt, it defaults to origin
|
|
if [[ -z $remote ]]; then
|
|
remote="origin"
|
|
fi
|
|
|
|
# infinitely prompts the user for a host site until something is entered
|
|
while [ -z $host ]
|
|
do
|
|
read -e -r -p "${txtwhite}Please enter host site (i.e. github.com): ${txtyellow}" host
|
|
done
|
|
|
|
# similarly infinitely prompts the user for a repository name
|
|
while [ -z $repo ]
|
|
do
|
|
read -e -r -p "${txtwhite}Please enter name of repository: ${txtyellow}" repo
|
|
done
|
|
|
|
# Reset output style
|
|
tput bold & tput setaf 7
|
|
|
|
# bgit uses github api if github.com is defined as host site
|
|
if [[ -n $host && $host == "github.com" ]] ; then
|
|
read -e -r -p "${txtwhite}Host site is github.com, would you like bgit to create the repository?(y/n): ${txtyellow}" crepo
|
|
|
|
# Reset output style
|
|
tput bold & tput setaf 7
|
|
|
|
# if $HOME/.gh_pat doesn't exist, then exits
|
|
if [[ ! -f $HOME/.gh_pat ]]; then
|
|
echo "${txtred}Github personal access token doesn't exist"
|
|
echo "See https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token${txtwhite}"
|
|
exit 1
|
|
fi
|
|
|
|
source $HOME/.gh_pat
|
|
|
|
if [[ $crepo == 'y' || $crepo == 'yes' ]] ; then
|
|
echo "${txtgreen}Host Site is github.com, creating repository...${txtwhite}"
|
|
curl -u $uname:$GH_TOKEN https://api.github.com/user/repos -d '{"name": "'${repo}'"}'
|
|
fi
|
|
|
|
echo -e "${txtblue}Your \$GH_TOKEN is saved to your clipboard...\nsimply enter CTRL+SHIFT+V to paste your token...\nwhen prompted for your password${txtwhite}"
|
|
echo $GH_TOKEN | xclip -sel clip
|
|
fi
|
|
|
|
# finally adds the specified remote, host site, username, and repository, and pushes it
|
|
git remote add $remote "https://$host/$uname/$repo"
|
|
git push --set-upstream $remote $branch
|
|
# git push -u $remote $branch
|
|
|
|
if [[ $host == "github.com" ]] ; then
|
|
echo "${txtgreen}Git repository created and initiated!!${txtwhite}"
|
|
# clears $GH_TOKEN from clipboard
|
|
echo '' | xclip && xclip -selection clipboard /dev/null
|
|
else
|
|
echo "${txtgreen}Git repository initiated!!${txtwhite}"
|
|
fi
|
|
|
|
break
|
|
done
|
|
break
|
|
else
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Otherwise, if there already is a .git directory...
|
|
else
|
|
|
|
# creates a list of repos and puts them in an array
|
|
repoarray=($(git remote))
|
|
# Grabs all new files
|
|
newfiles=$(git status --short | grep '??' | awk '{print $2}' | tr '\n' ' ')
|
|
# Grabs all modified files
|
|
modified=$(git status --short | grep M | awk '{print $2}' | tr '\n' ' ')
|
|
# Grabs all deleted files
|
|
deleted=$(git status --short | grep D | awk '{print $2}' | tr '\n' ' ')
|
|
|
|
# Reports what is staged for commit
|
|
# If there is anything to commit...
|
|
if [[ ! -z $newfiles || ! -z $modified || ! -z $deleted ]] ; then
|
|
# Let the user know what is staged for commit
|
|
echo "${txtwhite}The following files are staged for commit:"
|
|
# Otherwise, if there isn't anything to commit...
|
|
else
|
|
# Let the user know that everything is up to date
|
|
echo "${txtred}everything up-to-date...exiting bgit${txtwhite}"
|
|
# and exit the program
|
|
exit 0
|
|
fi
|
|
|
|
# Let the user know what is staged for commit
|
|
if [[ $newfiles ]]; then
|
|
echo "${txtgreen}ADDED: ${txtgreen}$newfiles"
|
|
fi
|
|
if [[ $modified ]]; then
|
|
echo "${txtblue}MODIFIED: ${txtblue}$modified"
|
|
fi
|
|
if [[ $deleted ]]; then
|
|
echo "${txtred}DELETED: ${txtred}$deleted"
|
|
fi
|
|
|
|
while [ true ]
|
|
do
|
|
# Prompts user if they'd like to commit the changes
|
|
read -e -r -p "${txtwhite}commit changes?(y/n): ${txtyellow}" change
|
|
# If the user chooses to commit the changes...
|
|
if [[ $change == "y" || $change == "yes" ]] ; then
|
|
# prompt if user wants to specify gitmoji:
|
|
while [ true ]
|
|
do
|
|
read -e -r -p "${txtwhite}add a gitmoji?(y/n): ${txtyellow}" gmojiprompt
|
|
if [[ $gmojiprompt == "y" || $gmojiprompt == "yes" ]] ; then
|
|
read -e -r -p "${txtwhite}enter gitmoji: ${txtyellow}" gitmoji
|
|
gitmoji=":$gitmoji:"
|
|
break
|
|
else
|
|
echo "${txtblue}no gitmoji specified...${txtwhite}"
|
|
gitmoji=""
|
|
break
|
|
fi
|
|
done
|
|
# Grabs commit message
|
|
while [ true ]
|
|
do
|
|
# Prompts the user to input their commit message
|
|
# (does not allow for multiple message commits)
|
|
read -e -r -p "${txtwhite}commit message: ${txtyellow}" message
|
|
cmessage=("$message")
|
|
# capitalizes first character of commit message
|
|
cmessage="$(tr '[:lower:]' '[:upper:]' <<< ${cmessage:0:1})${cmessage:1}"
|
|
# if the user entered a commit message over 50 characters...
|
|
if [ "${#message}" -ge 51 ] ; then
|
|
echo "${txtred}commit message is too large!"
|
|
echo "${txtred}please limit to 50 or less characters${txtwhite}"
|
|
# if the user inputted a commit message..
|
|
elif [ -n "$message" ] ; then
|
|
# then break out of the while loop and continue with the commit...
|
|
break
|
|
# if the user did NOT input a commit message...
|
|
else
|
|
# tell the user to do so or to quit
|
|
echo "${txtred}commit message is empty, please write a commit message"
|
|
echo "${txtred}or type 'CTRL+C' to quit${txtwhite}"
|
|
fi
|
|
done
|
|
|
|
# Reset output style
|
|
tput bold & tput setaf 7
|
|
|
|
# adds the modified and new files
|
|
# (suppresses message anyways if only deleted files are to be committed)
|
|
if [[ $newfiles || $modified ]] ; then
|
|
# also remembers password for 1 hour after last use
|
|
# (comment out if more security needed, or just use ssh...)
|
|
echo "${txtgreen}bgit will remember your password for 1 hour!"
|
|
echo "(doesn't apply to gpg or ssh)${txtwhite}"
|
|
git config credential.helper 'cache --timeout=3600';
|
|
git config advice.addEmptyPathspec false;
|
|
git add $modified $newfiles;
|
|
fi
|
|
|
|
if [[ $deleted ]] ; then
|
|
git rm $deleted;
|
|
fi
|
|
|
|
# commits the user's message (multi-word supported)
|
|
git commit -m "$gitmoji $cmessage" ;
|
|
|
|
# pushes the commit to each repository
|
|
for ((i = 0; i < $numrepos; i++)) ; do
|
|
git push ${repoarray[i]} ;
|
|
done
|
|
|
|
echo "${txtblue}bgit script has completed! goodbye!${txtwhite}"
|
|
exit 0
|
|
# If the user chooses to not the commit the changes ...
|
|
elif [[ $change == "n" || $change == "no" ]] ; then
|
|
|
|
# Reset output style
|
|
tput bold & tput setaf 7
|
|
|
|
# Report the git status
|
|
git status --short
|
|
|
|
# And let the user know no changes were committed
|
|
echo "${txtred}no changes committed"
|
|
|
|
exit 0
|
|
# If the user chooses to quit...
|
|
elif [[ $change == "q" || $change == "quit" ]] ; then
|
|
exit 0
|
|
# If the user continues to just press enter...
|
|
else
|
|
echo "${txtred}please enter y or n or type 'q' or 'quit' or 'CTRL+C' to quit${txtwhite}"
|
|
fi
|
|
done
|
|
fi
|