#!/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 '\n\n \n \n \n My Website\n \n \n \n

Header 1

\n

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

\n \n \n' > 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