diff --git a/.coverage b/.coverage new file mode 100644 index 0000000..970870f Binary files /dev/null and b/.coverage differ diff --git a/.gitignore b/.gitignore index aa62f8e..4861bfa 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,13 @@ -# Binaries for programs and plugins +#Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib +# GITS.egg-info +GITS.egg-info/ +dist/ # Test binary, built with `go test -c` *.test @@ -45,6 +48,7 @@ luac.out /test/tmp/ /test/version_tmp/ /tmp/ +/.idea/ # Used by dotenv library to load environment variables. # .env diff --git a/.tmux.conf b/.tmux.conf new file mode 100644 index 0000000..f57b0cb --- /dev/null +++ b/.tmux.conf @@ -0,0 +1,67 @@ +set -g aggressive-resize on +set-option -g default-shell /usr/bin/fish +unbind C-b +set -g prefix C-space +bind C-space send-prefix +set -g base-index 1 +# start with pane 1 +bind | split-window -h -c "#{pane_current_path}" +bind - split-window -v -c "#{pane_current_path}" +unbind '"' +unbind % +# open new windows in the current path +bind c new-window -c "#{pane_current_path}" +# reload config file +bind r source-file $Tnix/.config/dottmux +unbind p +bind p previous-window +# shorten command delay +set -sg escape-time 1 +# don't rename windows automatically +set-option -g allow-rename off +# mouse control (clickable windows, panes, resizable panes) +set -g mouse on +# Use Alt-arrow keys without prefix key to switch panes +bind -n M-Left select-pane -L +bind -n M-Right select-pane -R +bind -n M-Up select-pane -U +bind -n M-Down select-pane -D +# enable vi mode keys +set-window-option -g mode-keys vi +# set default terminal mode to 256 colors +set -g default-terminal "screen-256color" +bind-key u capture-pane \;\ + save-buffer /tmp/tmux-buffer \;\ + split-window -l 10 "urlview /tmp/tmux-buffer" +bind P paste-buffer +bind-key -T copy-mode-vi v send-keys -X begin-selection +bind-key -T copy-mode-vi y send-keys -X copy-selection +bind-key -T copy-mode-vi r send-keys -X rectangle-toggle +# loud or quiet? +set-option -g visual-activity off +set-option -g visual-bell off +set-option -g visual-silence off +set-window-option -g monitor-activity off +set-option -g bell-action none +# modes +setw -g clock-mode-colour colour5 +# panes +# statusbar +set -g status-position top +set -g status-justify left +set -g status-bg colour232 +set -g status-fg colour137 +###set -g status-attr dim +set -g status-left '' +set -g status-right '#{?window_zoomed_flag,🔍,} #[fg=colour255,bold]#H #[fg=colour255,bg=colour19,bold] %b %d #[fg=colour255,bg=colour8,bold] %H:%M ' +set -g status-right '#{?window_zoomed_flag,🔍,} #[fg=colour255,bold]#H %H:%M ' +set -g status-right-length 50 +set -g status-left-length 20 +setw -g window-status-current-format ' #I#[fg=colour249]:#[fg=colour255]#W#[fg=colour249]#F ' +setw -g window-status-format ' #I#[fg=colour237]:#[fg=colour250]#W#[fg=colour244]#F ' + +# messages +# layouts +bind S source-file $Tnix/.config/tmux-session1 +setw -g monitor-activity on +set -g visual-activity on diff --git a/.travis.yml b/.travis.yml index a694f7e..55546fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,20 @@ -language: python + +language: + python python: - - "3.8" # current default Python on Travis CI -# command to install dependencies -#install: -# - pip install -r requirements.txt -# command to run tests + - "3.5" +install: + - pip install -U pip + - pip install -r requirements.txt + - pip install coverage + - pip install codecov +git: + depth: 50 +jobs: + include: + - name: "project-1" + python: "3.8" script: - - python3 -m pytest + - coverage run -m pytest -q test/ +after_success: + - bash <(curl -s https://codecov.io/bash) -t d9ad46a5-ddae-4e9b-b0db-959bb96541f0 diff --git a/PROJ1-selfAssessment.md b/PROJ2-selfAssessment.md similarity index 76% rename from PROJ1-selfAssessment.md rename to PROJ2-selfAssessment.md index 1431859..dba421c 100644 --- a/PROJ1-selfAssessment.md +++ b/PROJ2-selfAssessment.md @@ -3,10 +3,10 @@ |Misc | Group members attended tutorial sessions|4| |Distrbuted dev model: | decisions made by unanmyous vote}|4| || group meetings had a round robin speaking order|4| -|| group meetings had a moderator that managed the round robin|2| -|| group meeting moderator rotated among the group|2| +|| group meetings had a moderator that managed the round robin|4| +|| group meeting moderator rotated among the group|4| || code conforms to some packaging standard|4| -|| code has can be downloaded from some standard package manager|0| +|| code has can be downloaded from some standard package manager|| | |workload is spread over the whole team (one team member is often Xtimes more productive than the others... but nevertheless, here is a track record that everyone is contributing a lot)|4| || Number of commits|4| || Number of commits: by different people|4| @@ -15,11 +15,11 @@ || License: exists|4| || DOI badge: exists |4| ||Docs: doco generated , format not ugly |4| -||Docs: what: point descriptions of each class/function (in isolation) |4| -||Docs: how: for common use cases X,Y,Z mini-tutorials showing worked examples on how to do X,Y,Z|2| -||Docs: why: docs tell a story, motivate the whole thing, deliver a punchline that makes you want to rush out and use the thing|4| +||Docs: what: point descriptions of each class/function (in isolation) || +||Docs: how: for common use cases X,Y,Z mini-tutorials showing worked examples on how to do X,Y,Z|| +||Docs: why: docs tell a story, motivate the whole thing, deliver a punchline that makes you want to rush out and use the thing|| ||Docs: 3 minute video, posted to YouTube. That convinces people why they want to work on your code.|4| -|| (hard) code conforms to some known patterns |2| +|| (hard) code conforms to some known patterns || |Tools Matter| Use of version control tools|4| || Extensive use of version control tools |4| || Repo has an up-to-date requirements.txt file|4| @@ -30,22 +30,22 @@ || Extensive Use of code formatters. |4| || Use of syntax checkers. |4| || Extensive use of syntax checkers. |4| -|| Use of code coverage |2| -|| Extensive use of code coverage |2| -|| other automated analysis tools|2| -|| Extensive use of other automated analysis tools|2| +|| Use of code coverage |4| +|| Extensive use of code coverage |4| +|| other automated analysis tools|| +|| Extensive use of other automated analysis tools|| || test cases exist|4| || test cases are routinely executed|4| -| consensus-oriented model| the files CONTRIBUTING.md and CODEOFCONDUCT.md has have multiple edits by multiple people|4| -| | the files CONTRIBUTING.md lists coding standards and lots of tips on how to extend the system without screwing things up|4| +| consensus-oriented model| the files CONTRIBUTING.md and CODEOFCONDUCT.md has have multiple edits by multiple people|| +| | the files CONTRIBUTING.md lists coding standards and lots of tips on how to extend the system without screwing things up|| | | multiple people contribute to discussions|4| || issues are discussed before they are closed|4| || Chat channel: exists|4| || Chat channel: is active |4| -|| test cases:.a large proportion of the issues related to handling failing cases.|2| -| zero internal boundaries | evidence that the whole team is using the same tools: everyone can get to all tools and files|4| -| | evidence that the whole team is using the same tools (e.g. config files in the repo, updated by lots of different people)|4| -| | evidence that the whole team is using the same tools (e.g. tutor can ask anyone to share screen, they demonstrate the system running on their computer)|4| -| | evidence that the members of the team are working across multiple places in the code base|4| -| low-regressions rule | (hard to judge) features released are not subsequently removed|4| -|short release cycles | (hard to see in short projects) project members are committing often enough so that everyone can get your work|4| +|| test cases:.a large proportion of the issues related to handling failing cases.|| +| zero internal boundaries | evidence that the whole team is using the same tools: everyone can get to all tools and files|| +| | evidence that the whole team is using the same tools (e.g. config files in the repo, updated by lots of different people)|| +| | evidence that the whole team is using the same tools (e.g. tutor can ask anyone to share screen, they demonstrate the system running on their computer)|| +| | evidence that the members of the team are working across multiple places in the code base|| +| low-regressions rule | (hard to judge) features released are not subsequently removed|| +|short release cycles | (hard to see in short projects) project members are committing often enough so that everyone can get your work|| diff --git a/README.md b/README.md index b48a18d..9f2770b 100644 --- a/README.md +++ b/README.md @@ -2,76 +2,83 @@ # GITS ### GIT Simplified -![GitHub](https://img.shields.io/github/license/amolgautam25/GITS) -[![Build Status](https://travis-ci.com/amolgautam25/GITS.svg?branch=master)](https://travis-ci.com/amolgautam25/GITS) -![GitHub](https://img.shields.io/badge/language-python-blue.svg) -![GitHub](https://img.shields.io/badge/language-shell-orange.svg) -![YouTube Video Views](https://img.shields.io/youtube/views/cMcftHMtIZ4?style=social) +![GitHub](https://img.shields.io/github/license/harshitpatel96/GITS) +[![Build Status](https://travis-ci.com/harshitpatel96/GITS.svg?branch=master)](https://travis-ci.com/harshitpatel96/GITS) +[![codecov](https://codecov.io/gh/harshitpatel96/GITS/branch/master/graph/badge.svg?token=G6RG52G2YO)](https://codecov.io/gh/harshitpatel96/GITS/) +![YouTube Video Views](https://img.shields.io/youtube/views/6Y8_RQecnZ8?style=social) [![DOI](https://zenodo.org/badge/295480790.svg)](https://zenodo.org/badge/latestdoi/295480790) -![GitHub issues](https://img.shields.io/github/issues/amolgautam25/GITS) -![GitHub closed issues](https://img.shields.io/github/issues-closed/amolgautam25/GITS) - -![GitHub pull requests](https://img.shields.io/github/issues-pr/amolgautam25/GITS) -![GitHub closed pull requests](https://img.shields.io/github/issues-pr-closed/amolgautam25/GITS) - -[![](https://img.youtube.com/vi/cMcftHMtIZ4/0.jpg)](https://youtu.be/cMcftHMtIZ4 "GITS demo") - - -### Supported functionality - -#### gits pr_update -This functionality makes sure that the current branch is able to make a PR without much trouble ( conflict ). It makes sure that the current branch has the latest commit off master branch, and that the local master has all the commits from the upstream master. This helps in reducing merge conflicts - -#### gits profile -This functionality allows the user to change the git account quickly with a single command. There are situations when a developer has a personal github account and a enterprise github account as well. Changing between these accounts is a little complicated. This functionality aims to simplify it. - -#### gits rebase -This is a highly simplified version of git rebase command. This interactive command asks for the branch that you want to rebase and automatically rebases it off master. This is the most common scenario. The original GIT rebase command is a little un-intuitive and there is always a confusion , about the source branch and the destination branch. - -#### gits reset -'Reset' intuitively means a HARD reset. This functionality does a HARD reset on your branch, and makes it even with the remote branch. This aims to simplify the confusion between HARD and the SOFT reset. - -#### gits set -This functionality sets the parent branch. - -#### gits upstream -This functionality changes the upstream with a single command. No need to manually remove the existing upstream, and adding a new upstream. This command will automatically change the upstream for the git repo. If there is any existing upstream , it will be overwritten. - -#### gits super reset -Have you ever run into a situation, where you had to clone the repository again ? Yes, this functionality is exactly for that scenario. It will remove the current repository. It will clone it again, and add all the 'remote' to this freshly cloned repository. - -#### gits add -Function that adds files as passed to the gits add command. Performs operation as similar to git add command - -#### gits commit -It is a highly simplified version of git commit command. We are actively working on this functionality such that a commit would fail if the unit tests does not pass. We can specify the tests that need to pass before the commit can actually happen. - -#### gits create_branch -This automatically checks out a new branch from local master , after pulling all the changes from the remote master to local master. The idea behind this is that this new branch should have all the latest commits before a developer starts working on them. - -#### gits logging -This logs all the commands executed by the user, and also stores the output of each command - -Note: More functionality are being added to this project. Please refer to the 'issues' tab for more information. In case you want to contribute to this project , please refer to 'Contributing.md' file. - - -### pydoc implementation +![GitHub issues](https://img.shields.io/github/issues/harshitpatel96/GITS) +![GitHub closed issues](https://img.shields.io/github/issues-closed/harshitpatel96/GITS) + +[![](https://img.youtube.com/vi/6Y8_RQecnZ8/hqdefault.jpg)](https://youtu.be/6Y8_RQecnZ8 "GITS demo") + +# About GITS +GITS streamlines most frequently performed workflows using fewer commands which is so much easier and better than usual. +Git-Simplified AKA GITS can be thought of wrapper around major Git functionalities. + +# Installation for Linux +1. Clone GITS Repo +2. From the root directory run the following command + ``` + pip install -r requirements.txt + ``` +3. Go to configurations directory and run the following command + ``` + bash project_init.sh + ``` + +# Installation for Windows +1. Clone GITS Repo +2. From the root directory run the following command + ``` + pip install -r requirements.txt + ``` +3. Currently, this project cannot be run on Windows. You need to make use of WSL to work on this project in Windows +although this fix would only work for systems running Windows 10. If you are using another version of Windows, using a +virtual machine might be preferred. + + Please refer this link to enable WSL : https://docs.microsoft.com/en-us/windows/wsl/install-win10 + +# How to Contribute? +Please take a look at our CONTRIBUTING.md where we provide instructions on contributing to the repo and help us in enhancing the current video conferencing platforms. + +# Documentation +## Functionalities Implemented +1. [gits profile](https://github.com/harshitpatel96/GITS/blob/master/docs/profile.md) +1. [gits rebase](https://github.com/harshitpatel96/GITS/blob/master/docs/rebase.md) +1. [gits reset](https://github.com/harshitpatel96/GITS/blob/master/docs/reset.md) +1. [gits upstream](https://github.com/harshitpatel96/GITS/blob/master/docs/upstream.md) +1. [gits super reset](https://github.com/harshitpatel96/GITS/blob/master/docs/super_reset.md) +1. [gits commit](https://github.com/harshitpatel96/GITS/blob/master/docs/commit.md) +1. [gits create_branch](https://github.com/harshitpatel96/GITS/blob/master/docs/create_branch.md) +1. [gits logging](https://github.com/harshitpatel96/GITS/blob/master/docs/logging.md) +1. [gits undo](https://github.com/harshitpatel96/GITS/blob/master/docs/undo.md) +1. [gits untrack](https://github.com/harshitpatel96/GITS/blob/master/docs/untrack.md) +1. [gits track](https://github.com/harshitpatel96/GITS/blob/master/docs/track.md) +1. [gits delete](https://github.com/harshitpatel96/GITS/blob/master/docs/delete.md) +1. [gits sync](https://github.com/harshitpatel96/GITS/blob/master/docs/sync.md) +1. [gits switch](https://github.com/harshitpatel96/GITS/blob/master/docs/switch.md) +1. [gits status](https://github.com/harshitpatel96/GITS/blob/master/docs/status.md) +1. [gits branch](https://github.com/harshitpatel96/GITS/blob/master/docs/branch.md) +1. [gits diff](https://github.com/harshitpatel96/GITS/blob/master/docs/diff.md) +1. [gits init](https://github.com/harshitpatel96/GITS/blob/master/docs/init.md) +1. [gits merge](https://github.com/harshitpatel96/GITS/blob/master/docs/merge.md) +1. [gits push](https://github.com/harshitpatel96/GITS/blob/master/docs/push.md) +1. [gits pull](https://github.com/harshitpatel96/GITS/blob/master/docs/pull.md) + + +## Pydoc implementation We have tried to write as much documentation as possible. You can use pydoc to go through the documentation. For example if you want to go through all the documentation for all files in code/ directory, do the following: `cd code`
`python3 -m pydoc -b ` -This will open up a browser and you can see all the files. You can click on a particular file to access the documentation associated with that file. +This will open up a browser and you can see all the files. You can click on a particular file to access the +documentation associated with that file. This repository is made for CSC 510 Software Engineering Course at NC State University. -Group 17 Team Members: -Amol Gautam -Sneha Kumar -Sreeraksha Mavinhally Sreekantha -Srujana Rachakonda -Tanay Agarwal diff --git a/code/gits.py b/code/gits.py index 0ca034e..d34dd75 100755 --- a/code/gits.py +++ b/code/gits.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#/usr/bin/python3 import sys import argparse @@ -13,10 +13,22 @@ from gits_rebase import gits_rebase from gits_reset import gits_reset +from gits_delete import gits_delete from gits_profile import gits_set_profile from gits_pr_update import gits_pr_update_func - +from gits_track import gits_track +from gits_untrack import gits_untrack +from gits_undo import gits_undo +from gits_sync import gits_sync +from gits_push import gits_push +from gits_switch import switch_branch +from gits_merge import merge_branch +from gits_status import gits_status +from gits_diff import gits_diff +from gits_branch import gits_branch +from gits_init import gits_init +from gits_pull import gits_pull logger_status = init_gits_logger() if not logger_status: @@ -54,6 +66,13 @@ gits_create_subparser.add_argument('-b', help="branch name to create") gits_create_subparser.set_defaults(func=create_branch) +gits_switch_subparser = subparsers.add_parser('switch') +gits_switch_subparser.add_argument('branch_name', help="branch name to switch") +gits_switch_subparser.set_defaults(func=switch_branch) + +gits_merge_subparser = subparsers.add_parser('merge') +gits_merge_subparser.add_argument('branch_name', help="branch name to merge") +gits_merge_subparser.set_defaults(func=merge_branch) gits_upstream_subparser = subparsers.add_parser('upstream') gits_upstream_subparser.add_argument('--remote', @@ -73,7 +92,7 @@ required=True, help='name to be used') -gits_pr_subparser = subparsers.add_parser('sync', help='sync help') +gits_pr_subparser = subparsers.add_parser('pr_update', help='sync help') gits_pr_subparser.set_defaults(func=gits_pr_update_func) gits_pr_subparser.add_argument('--upstream', nargs='?') @@ -84,10 +103,68 @@ gits_rb_subparser = subparsers.add_parser('rebase', help='sync help') gits_rb_subparser.set_defaults(func=gits_rebase) +gits_status_subparser = subparsers.add_parser('status', help='sync help') +gits_status_subparser.set_defaults(func=gits_status) + +gits_diff_subparser = subparsers.add_parser('diff', help='sync help') +gits_diff_subparser.set_defaults(func=gits_diff) + +gits_branch_subparser = subparsers.add_parser('branch', help='sync help') +gits_branch_subparser.set_defaults(func=gits_branch) + gits_reset_subparser = subparsers.add_parser('reset', help='sync help') gits_reset_subparser.set_defaults(func=gits_reset) gits_reset_subparser.add_argument('--branch', required=True, help='branch to be used') +gits_reset_subparser = subparsers.add_parser('delete', help='sync help') +gits_reset_subparser.set_defaults(func=gits_delete) +gits_reset_subparser.add_argument('--branch', required=True, help='branch to be used') +gits_reset_subparser.add_argument('--count', required=True, help='Last commits to be deleted') + +gits_track_subparser = subparsers.add_parser('track') +gits_track_subparser.add_argument('file_names', + metavar='N', + type=str, + nargs='+', + help='all file names') +gits_track_subparser.set_defaults(func=gits_track) + +gits_untrack_subparser = subparsers.add_parser('untrack') +gits_untrack_subparser.add_argument('file_names', + metavar='N', + type=str, + nargs='+', + help='all file names') +gits_untrack_subparser.set_defaults(func=gits_untrack) + +gits_undo_subparser = subparsers.add_parser('undo') +gits_undo_subparser.add_argument('file_names', + metavar='N', + type=str, + nargs='+', + help='all file names') +gits_undo_subparser.set_defaults(func=gits_undo) + +gits_sync_subparser = subparsers.add_parser('sync') +gits_sync_subparser.add_argument('-source', help="name of the trunk branch") +gits_sync_subparser.set_defaults(func=gits_sync) + +gits_push_subparser = subparsers.add_parser('push') +gits_push_subparser.add_argument("--rebase", nargs=1, default=False, help="do a pull rebase before pushing the changes", required=False) +gits_push_subparser.set_defaults(func=gits_push) + +gits_init_subparser = subparsers.add_parser("init") + +gits_init_subparser.add_argument("--bare", action="store_true", help="intialize an empty git repositories but omit the working directory") +gits_init_subparser.add_argument("--template", help="initialize a git repository using predifined templates") +gits_init_subparser.add_argument("--clone_url", help="url for cloning an already existing repo") +gits_init_subparser.set_defaults(func=gits_init) + +gits_pull_subparser = subparsers.add_parser("pull") +gits_pull_subparser.add_argument("--nocommit", action='store_true', help="fetches the remote contain but does not create a new merge commit", required=False) +gits_pull_subparser.add_argument("--rebase", action='store_true', help="uses git rebase to merge with the remote branch", required=False) +gits_pull_subparser.add_argument("--branch", nargs="?", default=False, help="you can specify the branch you want to pull", required=False) +gits_pull_subparser.set_defaults(func=gits_pull) args = parser.parse_args() args.func(args) diff --git a/code/gits_add.py b/code/gits_add.py index abb23a1..729e416 100755 --- a/code/gits_add.py +++ b/code/gits_add.py @@ -2,6 +2,7 @@ import gits_logging from subprocess import Popen, PIPE +import subprocess def gits_add_func(args): @@ -23,7 +24,7 @@ def gits_add_func(args): else: for i in range(0, total_files): subprocess_command.append(file_names_list[i]) - process = Popen(subprocess_command, stdout=PIPE, stderr=PIPE) + process = subprocess.Popen(subprocess_command, stdout=PIPE, stderr=PIPE) stdout, stderr = process.communicate() except Exception as e: diff --git a/code/gits_branch.py b/code/gits_branch.py new file mode 100644 index 0000000..8cc81d6 --- /dev/null +++ b/code/gits_branch.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +from subprocess import PIPE +import subprocess + + +def gits_branch(args): + """ + Function that allows users to show difference from last commit + """ + try: + diff_cmd = list() + diff_cmd.append("git") + diff_cmd.append("branch") + process1 = subprocess.Popen(diff_cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + print(stdout.decode("UTF-8")) + + except Exception as e: + print("ERROR: gits branch command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_commit.py b/code/gits_commit.py index ba1f28c..caafb46 100755 --- a/code/gits_commit.py +++ b/code/gits_commit.py @@ -1,6 +1,7 @@ #!/usr/bin/python3 -from subprocess import Popen, PIPE +from subprocess import PIPE +import subprocess def gits_commit_func(args): @@ -27,7 +28,7 @@ def gits_commit_func(args): subprocess_command.append("--amend") # print(subprocess_command) - process = Popen(subprocess_command, stdout=PIPE, stderr=PIPE) + process = subprocess.Popen(subprocess_command, stdout=PIPE, stderr=PIPE) stdout, stderr = process.communicate() except Exception as e: diff --git a/code/gits_create_branch.py b/code/gits_create_branch.py index d329072..4cc4d69 100644 --- a/code/gits_create_branch.py +++ b/code/gits_create_branch.py @@ -1,6 +1,8 @@ #!/usr/bin/python3 -from subprocess import Popen, PIPE +from subprocess import PIPE +import helper +import subprocess def create_branch(args): @@ -10,19 +12,19 @@ def create_branch(args): from remote master. The idea here is that the new branch should have all the latest commits. """ try: - # checkout master first + # checkout main/master first checkout_master = list() checkout_master.append("git") checkout_master.append("checkout") - checkout_master.append("master") - process1 = Popen(checkout_master, stdout=PIPE, stderr=PIPE) + checkout_master.append(helper.get_trunk_branch_name()) + process1 = subprocess.Popen(checkout_master, stdout=PIPE, stderr=PIPE) stdout, stderr = process1.communicate() # update with remote update_master = list() update_master.append("git") update_master.append("pull") - process2 = Popen(update_master, stdout=PIPE, stderr=PIPE) + process2 = subprocess.Popen(update_master, stdout=PIPE, stderr=PIPE) stdout, stderr = process2.communicate() # checkout new branch @@ -34,7 +36,7 @@ def create_branch(args): checkout_feature.append("checkout") checkout_feature.append("-b") checkout_feature.append(args.b) - process3 = Popen(checkout_feature, stdout=PIPE, stderr=PIPE) + process3 = subprocess.Popen(checkout_feature, stdout=PIPE, stderr=PIPE) stdout, stderr = process3.communicate() except Exception as e: diff --git a/code/gits_delete.py b/code/gits_delete.py new file mode 100644 index 0000000..1f74b81 --- /dev/null +++ b/code/gits_delete.py @@ -0,0 +1,25 @@ +import subprocess +from subprocess import PIPE + + +def gits_delete(args): + """ + Please use this functionality with caution since there would be no going back from this. + This function will delete a commit from the remote branch. + This functionality is useful when you have commited a mistake to the remote repo and do not + want it be visible in your commit history. + """ + print("Hello from GITS command line tools- GITS reset") + try: + process1 = subprocess.Popen(['git', 'checkout', args.branch], stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + process2 = subprocess.Popen(['git', 'reset', '--hard', "HEAD~"+str(args.count)], stdout=PIPE, stderr=PIPE) + stdout, stderr = process2.communicate() + process3 = subprocess.Popen(['git', 'push', '--force'], stdout=PIPE, stderr=PIPE) + stdout, stderr = process3.communicate() + print('Last '+args.count+' commits have been deleted') + except Exception as e: + print("ERROR: gits reset command caught an exception") + print("ERROR: {}".format(str(e))) + return False + return True diff --git a/code/gits_diff.py b/code/gits_diff.py new file mode 100644 index 0000000..be0746a --- /dev/null +++ b/code/gits_diff.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 + +from subprocess import PIPE +import subprocess + + +def gits_diff(args): + """ + Function that allows users to show difference since last commit + """ + try: + diff_cmd = list() + diff_cmd.append("git") + diff_cmd.append("diff") + process1 = subprocess.Popen(diff_cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + print(stdout.decode("UTF-8")) + + except Exception as e: + print("ERROR: gits diff command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_hello.py b/code/gits_hello.py index 912f876..ce45cea 100755 --- a/code/gits_hello.py +++ b/code/gits_hello.py @@ -1,6 +1,5 @@ import gits_logging - def gits_hello_world(args): """ Function that prints hello message diff --git a/code/gits_init.py b/code/gits_init.py new file mode 100644 index 0000000..63baa55 --- /dev/null +++ b/code/gits_init.py @@ -0,0 +1,35 @@ +from subprocess import Popen, PIPE + +def gits_init(args): + """ + This function allows user to transform current + directory into a Git repository. + There are three ways to do it. + 1) Simple git init + gits init + 2) Initialize with a bare flag + gits init --bare + 3) Initialize using a preexisting template + gits init --template path-to-template + """ + try: + if args.clone_url: + process_commands = ["git","clone", args.clone_url] + else: + process_commands = ["git", "init"] + if args.bare is not False and args.bare is not None: + process_commands.append("--bare") + elif args.template is not None: + process_commands.append("--template") + process_commands.append(args.template) + + process = Popen(process_commands, stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + print(stdout.decode("UTF-8")) + + except Exception as e: + print("ERROR: gits init command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_merge.py b/code/gits_merge.py new file mode 100644 index 0000000..f13e58c --- /dev/null +++ b/code/gits_merge.py @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +from subprocess import PIPE +import subprocess + + +def merge_branch(args): + """ + Function that allows user to merge any branch into current branch + """ + try: + merge_cmd = list() + merge_cmd.append("git") + merge_cmd.append("merge") + merge_cmd.append(args.branch_name) + process1 = subprocess.Popen(merge_cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + # print(stdout.decode("UTF-8")) + + except Exception as e: + print("ERROR: gits merge command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_pr_update.py b/code/gits_pr_update.py deleted file mode 100644 index bb2371e..0000000 --- a/code/gits_pr_update.py +++ /dev/null @@ -1,81 +0,0 @@ -import subprocess -from subprocess import PIPE - - -def gits_pr_update_func(args): - # print(args) - # print("Hello from GITS command line tools- PR Update") - # flag = 0 - """This functionality makes sure that the current branch is able to make a PR without much trouble ( conflict ). It makes sure that the current branch has the latest commit off master branch, and that the local master has all the commits from the remote or upstream master. This helps in reducing merge conflicts -""" - try: - Untracked_file_check_status = list() - Untracked_file_check_status.append("git") - Untracked_file_check_status.append("status") - Untracked_file_check_status.append("--porcelain") - - process1 = subprocess.Popen(Untracked_file_check_status, - stdout=PIPE, stderr=PIPE) - - stdout, stderr = process1.communicate() - # print(format(stdout)) - if stdout != b'': - print("Note: Please commit uncommitted changes") - # git stash - exit() - - print("Checking if upstream is set..") - process2 = subprocess.Popen(['git', 'remote', '-vv'], - stdout=PIPE, stderr=PIPE) - process21 = subprocess.Popen(['grep', 'upstream'], - stdin=process2.stdout, - stdout=PIPE, stderr=PIPE) - stdout, stderr = process21.communicate() - - if stdout != b'': - print("Upstream set") - elif stdout == b'' and args.upstream: - print("Setting upstream") - process3 = subprocess.Popen(['git', 'remote', 'add', 'upstream', - args.upstream], - stdout=PIPE, - stderr=PIPE) - stdout, stderr = process3.communicate() - else: - print("Set --upstream") - exit() - - print("\nCheckout master..") - checkout_master = list() - checkout_master.append("git") - checkout_master.append("checkout") - checkout_master.append("master") - process4 = subprocess.Popen(checkout_master, stdout=PIPE, stderr=PIPE) - stdout, stderr = process4.communicate() - print(stdout.decode('utf-8')) - - print("Pull Changes from Upstream Master..") - pull_upstream = list() - pull_upstream.append("git") - pull_upstream.append("pull") - pull_upstream.append("upstream") - pull_upstream.append("master") - process5 = subprocess.Popen(pull_upstream, stdout=PIPE, stderr=PIPE) - stdout, stderr = process5.communicate() - print(stdout.decode('utf-8')) - - print("Push changes to local master..") - push_origin = list() - push_origin.append("git") - push_origin.append("push") - push_origin.append("origin") - push_origin.append("master") - process6 = subprocess.Popen(push_origin, stdout=PIPE, stderr=PIPE) - stdout, stderr = process6.communicate() - print(stdout.decode('utf-8'), stderr.decode('utf-8')) - - except Exception as e: - print("ERROR: gits sync command caught an exception") - print("ERROR: {}".format(str(e))) - return False - return True diff --git a/code/gits_pull.py b/code/gits_pull.py new file mode 100644 index 0000000..adf62ec --- /dev/null +++ b/code/gits_pull.py @@ -0,0 +1,54 @@ +import subprocess +from subprocess import PIPE +import helper + +def gits_pull(args): + """ + This function is used to pull remote branch and + merge it into local branch. + Usage: gits pull + gits pull --no-commit + gits pull --rebase + gits pull --verbose + """ + try: + untracked_file_check_status = ["git", "status", "--porcelain"] + process0 = subprocess.Popen(untracked_file_check_status, + stdout=PIPE, stderr=PIPE) + stdout, stderr = process0.communicate() + # print(stdout.decode("utf-8")) + + if stdout != b'': + print("Note: Please commit uncommited changes before pulling") + return False + + print(args) + arguments = [] + curr_branch = helper.get_current_branch() + if args.nocommit is True and args.rebase is True: + print("You cannot use both nocommit and rebase at the same time") + return False + elif args.nocommit is True: + arguments += ["--no-commit"] + elif args.rebase is True: + arguments += ["--rebase"] + + if args.branch is not False and args.branch is not None: + arguments += [args.branch] + else: + arguments += [curr_branch] + + pull_command = ["git", "pull"] + ["origin"] + arguments + print(pull_command) + process1 = subprocess.Popen(pull_command, stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + print(stdout) + # print(stdout.decode("utf-8")) + + except Exception as e: + print("ERROR: gits pull command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True + diff --git a/code/gits_push.py b/code/gits_push.py new file mode 100644 index 0000000..4ff0922 --- /dev/null +++ b/code/gits_push.py @@ -0,0 +1,45 @@ +import subprocess +from subprocess import PIPE +import helper + +def gits_push(args): + """ + This function is used to push local changes to remote branch. + Usage: gits push + """ + try: + untracked_file_check_status = ["git", "status", "--porcelain"] + process0 = subprocess.Popen(untracked_file_check_status, + stdout=PIPE, stderr=PIPE) + + stdout, stderr = process0.communicate() + # print(stdout.decode("utf-8")) + + if stdout != b'': + print("Note: Please commit uncommited changes") + return False + + curr_branch = helper.get_current_branch() + + if args.rebase is not False: + print("Pulling changes from Upstream source branch and rebasing it") + pull_rebase = ["git", "pull", "--rebase", "origin", args.rebase] + process1 = subprocess.Popen(pull_rebase, stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + # print(stdout.decode("utf-8")) + + print("Pushing local commits") + push_commits = ["git", "push"] + process2 = subprocess.Popen(push_commits, stdout=PIPE, stderr=PIPE) + + stdout, stderr = process2.communicate() + # print(stdout.decode("utf-8")) + + except Exception as e: + print("ERROR: gits push command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True + + diff --git a/code/gits_rebase.py b/code/gits_rebase.py index eb68843..d595857 100644 --- a/code/gits_rebase.py +++ b/code/gits_rebase.py @@ -1,25 +1,28 @@ import subprocess from subprocess import PIPE +import helper def gits_rebase(args): - """This is a highly simplified version of git rebase command. This interactive command asks for the branch that you want to rebase and automatically rebases it off master. This is the most common scenario. The original GIT rebase command is a little un-intuitive and there is always a confusion , about the source branch and the destination branch. + """This is a highly simplified version of git rebase command. + This interactive command asks for the branch that you want to rebase and automatically rebases it off master. + This is the most common scenario. The original GIT rebase command is a little un-intuitive and there is always a + confusion , about the source branch and the destination branch. """ - print(args) - print("Hello from GITS command line tools- Rebase") try: print("Is the rebase on current branch?") inp = input("[yes/no][y/n]") if inp.lower() == "yes" or inp.lower() == "y": - process1 = subprocess.Popen(['git', 'rebase', 'master'], stdout=PIPE, stderr=PIPE) + process1 = subprocess.Popen(['git', 'rebase', helper.get_trunk_branch_name()], stdout=PIPE, stderr=PIPE) stdout, stderr = process1.communicate() - # print(stdout) + print(stdout.decode("UTF-8")) else: - inp2 = input("Enter the name of the branch you want to rebase") - # print(inp2) - process2 = subprocess.Popen(['git', 'checkout', inp2, 'git', 'rebase', 'master'], stdout=PIPE, stderr=PIPE) + inp2 = input("Enter the name of the branch you want to rebase: ") + print(inp, inp2) + process2 = subprocess.Popen(['git', 'checkout', inp2, 'git', 'rebase', helper.get_trunk_branch_name()], + stdout=PIPE, stderr=PIPE) stdout, stderr = process2.communicate() - # print(stdout) + print(stdout.decode("UTF-8")) except Exception as e: print("ERROR: gits reset command caught an exception") print("ERROR: {}".format(str(e))) diff --git a/code/gits_reset.py b/code/gits_reset.py index 735f40f..cf18717 100644 --- a/code/gits_reset.py +++ b/code/gits_reset.py @@ -3,13 +3,15 @@ def gits_reset(args): - """'Reset' intuitively means a HARD reset. This functionality does a HARD reset on your branch, and makes it even with the remote branch. This aims to simplify the confusion between HARD and the SOFT reset.""" + """'Reset' intuitively means a HARD reset. + This functionality does a HARD reset on your branch, and makes it even with the remote branch. + This aims to simplify the confusion between HARD and the SOFT reset.""" print("Hello from GITS command line tools- GITS reset") try: process1 = subprocess.Popen(['git', 'checkout', args.branch], stdout=PIPE, stderr=PIPE) stdout, stderr = process1.communicate() # print(stdout) - process2 = subprocess.Popen(['git', 'reset', '--hard', 'origin', args.branch], stdout=PIPE, stderr=PIPE) + process2 = subprocess.Popen(['git', 'reset', '--hard', args.branch], stdout=PIPE, stderr=PIPE) stdout, stderr = process2.communicate() # print(stdout) except Exception as e: diff --git a/code/gits_status.py b/code/gits_status.py new file mode 100644 index 0000000..073a17c --- /dev/null +++ b/code/gits_status.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 + +from subprocess import PIPE +import subprocess + + +def gits_status(args): + """ + Function that allows users to show status about + 1. changes present in the working directory but not in the staging area. + 2. changes present inside staging area. + 3. changes to the files which are not being tracked. + """ + try: + status_cmd = list() + status_cmd.append("git") + status_cmd.append("status") + process1 = subprocess.Popen(status_cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + print(stdout.decode("UTF-8")) + + except Exception as e: + print("ERROR: gits status command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_super_reset.py b/code/gits_super_reset.py index 0bdc4b5..57c8b77 100644 --- a/code/gits_super_reset.py +++ b/code/gits_super_reset.py @@ -18,11 +18,7 @@ def super_reset(args): print("Required parameters are not provided. " "Please add --name parameter.") return False - - # Stepping into the repository for configuration details os.chdir("./" + args.name) - - # get remote url first remote_loc = check_output(["git", "config", "remote.origin.url"]) if not remote_loc: @@ -30,15 +26,9 @@ def super_reset(args): return False remote_loc = remote_loc.strip().decode("utf-8") - - # going out of the directory to remove it os.chdir("../") - - # removing the repo print("Removing the current repository...") shutil.rmtree(args.name) - - # new clone print("Freshly cloning...") check_output(["git", "clone", remote_loc]) diff --git a/code/gits_switch.py b/code/gits_switch.py new file mode 100644 index 0000000..ed8d1fc --- /dev/null +++ b/code/gits_switch.py @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +from subprocess import PIPE +import subprocess + + +def switch_branch(args): + """ + Function that allows user to switch between branches + """ + try: + switch_cmd = list() + switch_cmd.append("git") + switch_cmd.append("checkout") + switch_cmd.append(args.branch_name) + process1 = subprocess.Popen(switch_cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = process1.communicate() + print("Switched to branch:", args.branch_name) + + except Exception as e: + print("ERROR: gits switch command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_sync.py b/code/gits_sync.py new file mode 100644 index 0000000..4882305 --- /dev/null +++ b/code/gits_sync.py @@ -0,0 +1,67 @@ +import subprocess +from subprocess import PIPE +from helper import get_current_branch, get_trunk_branch_name + + +def gits_sync(args): + try: + Untracked_file_check_status = list() + Untracked_file_check_status.append("git") + Untracked_file_check_status.append("status") + Untracked_file_check_status.append("--porcelain") + + process1 = subprocess.Popen(Untracked_file_check_status, + stdout=PIPE, stderr=PIPE) + + stdout, stderr = process1.communicate() + + if stdout != b'': + print("Note: Please commit uncommitted changes") + exit() + + curr_branch = get_current_branch() + if args.source: + source_branch = args.source + else: + source_branch = get_trunk_branch_name() + + print("Checking out source branch..") + checkout_master = list() + checkout_master.append("git") + checkout_master.append("checkout") + checkout_master.append(source_branch) + process2 = subprocess.Popen(checkout_master, stdout=PIPE, stderr=PIPE) + stdout, stderr = process2.communicate() + print(stdout.decode('utf-8')) + + print("Pulling Changes from Upstream source branch..") + pull_upstream = list() + pull_upstream.append("git") + pull_upstream.append("pull") + process3 = subprocess.Popen(pull_upstream, stdout=PIPE, stderr=PIPE) + stdout, stderr = process3.communicate() + print(stdout.decode('utf-8')) + + print("Checking out current branch..") + checkout_current = list() + checkout_current.append("git") + checkout_current.append("checkout") + checkout_current.append(curr_branch) + process4 = subprocess.Popen(checkout_current, stdout=PIPE, stderr=PIPE) + stdout, stderr = process4.communicate() + print(stdout.decode('utf-8')) + + print("Syncing current branch from the updated source branch..") + rebase_cmd = list() + rebase_cmd.append("git") + rebase_cmd.append("rebase") + rebase_cmd.append(source_branch) + process5 = subprocess.Popen(rebase_cmd, stdout=PIPE, stderr=PIPE) + stdout, stderr = process5.communicate() + print(stdout.decode('utf-8')) + + except Exception as e: + print("ERROR: gits sync command caught an exception") + print("ERROR: {}".format(str(e))) + return False + return True diff --git a/code/gits_track.py b/code/gits_track.py new file mode 100644 index 0000000..bc2fee1 --- /dev/null +++ b/code/gits_track.py @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import gits_logging +from subprocess import PIPE +import subprocess + + +def gits_track(args): + """ + Function that moves files from working directory to the staging directory. + Only tracked files will be considered for any upcoming files. + """ + try: + subprocess_command = list() + subprocess_command.append("git") + subprocess_command.append("add") + file_names_list = args.file_names + total_files = len(file_names_list) + if total_files != 0: + for i in range(0, total_files): + subprocess_command.append(file_names_list[i]) + process = subprocess.Popen(subprocess_command, stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + + except Exception as e: + gits_logging.gits_logger.error("gits track command caught an exception") + gits_logging.gits_logger.error("{}".format(str(e))) + print("ERROR: gits track command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_undo.py b/code/gits_undo.py new file mode 100644 index 0000000..d5e949a --- /dev/null +++ b/code/gits_undo.py @@ -0,0 +1,32 @@ +#!/usr/bin/python3 + +import gits_logging +from subprocess import PIPE +import subprocess + + +def gits_undo(args): + """ + Function that moves files from working directory to the staging directory. + Only tracked files will be considered for any upcoming files. + """ + try: + subprocess_command = list() + subprocess_command.append("git") + subprocess_command.append("checkout") + file_names_list = args.file_names + total_files = len(file_names_list) + if total_files != 0: + for i in range(0, total_files): + subprocess_command.append(file_names_list[i]) + process = subprocess.Popen(subprocess_command, stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + + except Exception as e: + gits_logging.gits_logger.error("gits undo command caught an exception") + gits_logging.gits_logger.error("{}".format(str(e))) + print("ERROR: gits undo command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/gits_untrack.py b/code/gits_untrack.py new file mode 100644 index 0000000..ce4dee1 --- /dev/null +++ b/code/gits_untrack.py @@ -0,0 +1,33 @@ +#!/usr/bin/python3 + +import gits_logging +from subprocess import PIPE +import subprocess + + +def gits_untrack(args): + """ + Function that moves files from staging area to the working directory. + Untracked files will not be considered for the upcoming commits. + """ + try: + subprocess_command = list() + subprocess_command.append("git") + subprocess_command.append("reset") + subprocess_command.append("HEAD") + file_names_list = args.file_names + total_files = len(file_names_list) + if total_files != 0: + for i in range(0, total_files): + subprocess_command.append(file_names_list[i]) + process = subprocess.Popen(subprocess_command, stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + + except Exception as e: + gits_logging.gits_logger.error("gits untrack command caught an exception") + gits_logging.gits_logger.error("{}".format(str(e))) + print("ERROR: gits untrack command caught an exception") + print("ERROR: {}".format(str(e))) + return False + + return True diff --git a/code/helper.py b/code/helper.py new file mode 100644 index 0000000..5de0de3 --- /dev/null +++ b/code/helper.py @@ -0,0 +1,50 @@ +#!/usr/bin/python3 + +from subprocess import PIPE +import subprocess + + +def get_current_branch(): + """ + This function returns current checked out branch. + """ + try: + subprocess_command = list() + subprocess_command.append("git") + subprocess_command.append("rev-parse") + subprocess_command.append("--abbrev-ref") + subprocess_command.append("HEAD") + process = subprocess.Popen(subprocess_command, stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + branch = stdout.decode('UTF-8') + + return branch.rstrip() + + except: + print("error occured while getting current branch name!") + return None + +def get_trunk_branch_name(): + """ + This function returns the name of the trunk branch for the project + """ + try: + subprocess_command = list() + subprocess_command.append("git") + subprocess_command.append("branch") + process = subprocess.Popen(subprocess_command, stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + all_branches = stdout.decode('UTF-8') + list_of_branch_names = all_branches.split() + list_of_branch_names.remove('*') + if "master" in list_of_branch_names: + return "master" + elif "main" in list_of_branch_names: + return "main" + else: + print("h") + return list_of_branch_names[0] + + except: + print("error occured while getting trunk branch name!") + return None \ No newline at end of file diff --git a/code/test_gits_add.py b/code/test_gits_add.py deleted file mode 100644 index 7894e27..0000000 --- a/code/test_gits_add.py +++ /dev/null @@ -1,14 +0,0 @@ -import argparse -import gits_add -from mock import patch - - -@patch("argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace(file_names="test_file_names")) -@patch("subprocess.Popen", return_value="anything") -def test_gits_add_func_1(mock_var1, mock_args): - """ - Function to test gits_add, success case - """ - test_result = gits_add.gits_add_func(mock_args) - assert True == test_result, "Normal case" diff --git a/code/test_gits_commit.py b/code/test_gits_commit.py deleted file mode 100644 index 6586d16..0000000 --- a/code/test_gits_commit.py +++ /dev/null @@ -1,14 +0,0 @@ -import argparse -import gits_commit -from mock import patch - - -@patch("argparse.ArgumentParser.parse_args", - return_value=argparse.Namespace(m="test_commit", amend=True)) -@patch("subprocess.Popen", return_value="anything") -def test_gits_commit_func_1(mock_var1, mock_args): - """ - Function to test gits_add, success case - """ - test_result = gits_commit.gits_commit_func(mock_args) - assert True == test_result, "Normal case" diff --git a/code/test_gits_create_branch.py b/code/test_gits_create_branch.py deleted file mode 100644 index ccdaacd..0000000 --- a/code/test_gits_create_branch.py +++ /dev/null @@ -1,13 +0,0 @@ -import argparse -import gits_create_branch -from mock import patch, Mock - - -@patch("argparse.ArgumentParser.parse_args", return_value=argparse.Namespace(b="branch name")) -@patch("subprocess.Popen") -def test_git_create_branch_happy_path(mock_popen, mock_args): - """ - Function to test gits_create_branch, success case - """ - test_result = gits_create_branch.create_branch(mock_args) - assert test_result == True diff --git a/configurations/project_init.fish b/configurations/project_init.fish new file mode 100644 index 0000000..89e9453 --- /dev/null +++ b/configurations/project_init.fish @@ -0,0 +1,24 @@ +set SCRIPT_DIR (cd (dirname (status -f)); and pwd) + +set PROJECT_DIR $SCRIPT_DIR/.. + +set RELATIVE_GITS_PATH "code/gits.py" + +set GITS_EXEC_PATH "$PROJECT_DIR/$RELATIVE_GITS_PATH" + +set FISHRC ~/.config/fish/conf.d/virtualfish-loader.fish + +if [ -f "$FISHRC" ]; + echo "$FISHRC exists, appending gits commandline tool alias" + echo "alias gits=\"python3 $GITS_EXEC_PATH\"" >> $FISHRC +else + echo "$FISHRC does not exist, creating a new file and adding gits commandline tool alias" + echo "alias gits=\"python3 $GITS_EXEC_PATH\"" >> $FISHRC +end + +echo "Intializing gits directory in user home directory" + +set GITS ~/.gits +set GITS_LOG ~/.gits/logs + +mkdir -p $GITS $GITS_LOG diff --git a/docs/branch.md b/docs/branch.md new file mode 100644 index 0000000..2293225 --- /dev/null +++ b/docs/branch.md @@ -0,0 +1,17 @@ +# About gits branch +This command is used to list all the branches present. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_branch.py). + +# Code Description +## Functions +1. gits_branch(args): +This function simply displays all the branch present inside the local repository. It also places * in front of the branch that is currently checked out. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Use the command as below to list all branches: +``` +$ gits branch +``` diff --git a/docs/commit.md b/docs/commit.md new file mode 100644 index 0000000..9024524 --- /dev/null +++ b/docs/commit.md @@ -0,0 +1,28 @@ +# About gits commit +This command is used to commit changes present inside the staging area. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_commit.py). + +# Code Description +## Functions +1. gits_commit_func(args): +this function takes **args** object as an input which has an attribute **m** to store the commit message and another boolean attribute **amend**. +If **amend** is set to true, command will not create new commit. Instead, it will simply add changes to the last commit. +Function returns True for successful execution and False otherwise with an exception. + + +# How to run it? (Small Example) +Let say you are on a particular branch working on some feature X. +You've made some changes so far and you want to commit those chnages. +You can use the following command to do so: +``` +$ gits commit -m "My first commit" +``` +Soon after you realized a mistake in the last commit and want to fix that mistake. +However you do not want others to notice that mistake. +In this situation, you can use the amend argument as shown below to update the last commit. +``` +$ gits commit -m "My first commit with mistake fixed" --amend +``` +After successful execution of this command, you will still have only one commit for the changes you have made so far. \ No newline at end of file diff --git a/docs/create_branch.md b/docs/create_branch.md new file mode 100644 index 0000000..706aba6 --- /dev/null +++ b/docs/create_branch.md @@ -0,0 +1,22 @@ +# About gits create +This automatically checks out a new branch from local master, after pulling all the changes from the remote master to local master. +The idea behind this is that this new branch should have all the latest commits before a developer starts +working on them. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_create_branch.py). + +# Code Description +## Functions +1. create_branch(args): +This function takes **args** object as an input which has an attribute **b** to store the name of the branch to be created. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Let say you are about to start working on a particular feature for the product your team is building. +It is general practice to implement a feature in a separate branch off the master and merge the changes back once you are done. +To do so, you can use the gits create command as follow which will create new branch from the master. +``` +$ gits create -b foo +``` +Successful execution of this command will create a branch named foo which is in sync with the upstream main branch. \ No newline at end of file diff --git a/docs/delete.md b/docs/delete.md new file mode 100644 index 0000000..a746d0e --- /dev/null +++ b/docs/delete.md @@ -0,0 +1,20 @@ +# About gits delete +Please use this functionality with caution since there would be no going back from this. +This function will delete a commit from the remote branch. +This functionality is useful when you have commited a mistake to the remote repo and do not +want it be visible in your commit history. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_delete.py) + +# Code Description +## Functions +1. gits_delete(args):this function takes args object as an input which has an attribute count to determine how many commits are supposed to be deleted from the master branch. + + +# How to run it? (Small Example) +Let's say that you want to delete last 2 commits from the master branch of your repository, then you can do so by passing master in the branch argument and 2 in the count argument. +The following command can be used to fulfill the above-mentioned task. +``` +gits delete --branch master --count 2 +``` diff --git a/docs/diff.md b/docs/diff.md new file mode 100644 index 0000000..d2d15c5 --- /dev/null +++ b/docs/diff.md @@ -0,0 +1,17 @@ +# About gits diff +This command is used to display the difference from the last commit. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_diff.py). + +# Code Description +## Functions +1. gits_diff(args): +This function simply displays the changes since last commit. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Use the command as below to list all branches: +``` +$ gits diff +``` diff --git a/docs/init.md b/docs/init.md new file mode 100644 index 0000000..beefec5 --- /dev/null +++ b/docs/init.md @@ -0,0 +1,36 @@ +# About gits init +This function allows user to transform current directory into a Git repository. +It also allow user to clone an already existing repository. + +# Location of Code +The code that implements this gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_init.py) + +# Code Description +## Functions +1. gits_init(args): +This function takes optional arguments as an input. Those arguments are **bare** which is a boolean attribute, **template** which takes path to template file as input and **clone_url** which represents the url for repository in case of cloning. +If **bare** is set to true, then an empty git repository would be initialized but the working directory would be omitted. +Whereas, if **template** argument is used, then the directory is initialized with the provided template repository. +If **clone_url** is provided, it will create and initialize new repository inside current directory with specified url. + +# How to run it? (Small Example) +There are three different ways to initialize the repository. +- Simple git initialization +``` +$ gits init +``` +- Using bare flag +``` +$ gits init --bare +``` +- Using templates +``` +$ gits init --template pathtotemplate +``` +After using any of these commands your directory would have a version control system. + +To clone a repository inside current directory: +``` +$ gits init --clone_url repository_url_here +``` +It will create and initialize new repository inside current directory. \ No newline at end of file diff --git a/docs/logging.md b/docs/logging.md new file mode 100644 index 0000000..3c494e6 --- /dev/null +++ b/docs/logging.md @@ -0,0 +1,15 @@ +# About gits logging +This logs all the commands executed by the user, and also stores the output of each command + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_logging.py) + +# Code Description +## Functions +1. init_gits_logger(args): + + +# How to run it? (Small Example) +``` + +``` \ No newline at end of file diff --git a/docs/merge.md b/docs/merge.md new file mode 100644 index 0000000..95ea22e --- /dev/null +++ b/docs/merge.md @@ -0,0 +1,20 @@ +# About gits merge +This command is used to merge your changes back to the base branch from which you've checked out your personal development branch. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_merge.py). + +# Code Description +## Functions +1. merge_branch(args): +this function takes **args** object as an input which has an attribute **branch_name** to store the name of the branch to be merged with current branch. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Consider the scenario where you checked out branch **foo** from the master to work on a particular task. +Now, you are done with that task and you want your changes to be merged back in to the master branch. +To do so, you can use this command in following way from master branch: +``` +$ gits merge foo +``` +This will merge all the commits from branch **foo** to current branch. \ No newline at end of file diff --git a/docs/pr_update.md b/docs/pr_update.md new file mode 100644 index 0000000..c415b72 --- /dev/null +++ b/docs/pr_update.md @@ -0,0 +1,21 @@ +# About gits pr_update +This functionality makes sure that the current branch is able to make a PR without much trouble ( conflict ). +It makes sure that the current branch has the latest commit off master branch, +and that the local master has all the commits from the upstream master. +This helps in reducing merge conflicts. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_pr_update.py). + +# Code Description +## Functions +1. gits_pr_update_func(args): +This function takes **args** object as an input which has an attribute **upstream** to store name of the upstream branch. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +To make sure that your changes does not result in any merge conflict, you can use this command in following way: +``` +$ gits pr_update +``` +If command detects any possible conflicts, it will ask you to fix those on your local machine only. \ No newline at end of file diff --git a/docs/profile.md b/docs/profile.md new file mode 100644 index 0000000..310888e --- /dev/null +++ b/docs/profile.md @@ -0,0 +1,22 @@ +# About gits profile +This functionality allows the user to change the git account quickly with a single command. +There are situations when a developer has a personal github account and a enterprise github account as well. +Changing between these accounts is a little complicated. This functionality aims to simplify it. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_profile.py). + +# Code Description +## Functions +1. gits_set_profile(args): +This function takes **args** object as an input which has an attribute **email** to store the email address to be updated and **name** to store the name to be updated. +Function returns True for successful execution and False otherwise with an exception. + +2. check(email): +This function takes a string **email** as an input and returns True if it is valid email address and False otherwise. + +# How to run it? (Small Example) +Use the command in following way to update user name and email address to "foo" and "foo@bar.com" respectively. +``` +$ gits profile --name foo --email foo@bar.com +``` \ No newline at end of file diff --git a/docs/pull.md b/docs/pull.md new file mode 100644 index 0000000..63e9f87 --- /dev/null +++ b/docs/pull.md @@ -0,0 +1,29 @@ +# About gits pull +This function allows user to pull remote branch and merge it into local branch. + +# Location of Code +The code that implements this gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_pull.py) + +# Code Description +## Functions +1. gits_pull(args): +This function has three optional arguments. Those arguments are **nocommit**, **rebase and **branch**. **nocommit** fetches the remote content but does not create a new merge commit, **rebase** merges the remote branch with local branch using git rebase instead of git merge. **branch** is used to tell the function which branch you want to pull if it is not current branch. + +# How to run it? (Small Example) +There are three ways you can pull the remote branch. In each of the commands described below branch is optional argument. +1) Simple pull +``` +$ gits pull --branch branchname +``` +2) Using nocommit method +``` +$ gits pull --nocommit --branch branchname +``` +3) Using rebase method +``` +$ gits pull --rebase --branch branchname +``` + +After executing this command you would get remote branch pulled into your local repository. You may be required to resolve some merge conflicts. + + diff --git a/docs/push.md b/docs/push.md new file mode 100644 index 0000000..a4d1bc9 --- /dev/null +++ b/docs/push.md @@ -0,0 +1,22 @@ +# About gits push +This function allows user to push local commits to remote branch. + +# Location of Code +The code that implements this gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_push.py) + +# Code Description +## Functions +1. gits_push(args): +This function takes option argument **rebase** as input. When you use **rebase**, gits first pulls the specified remote branch and rebase's current branch on top of the last commit on remote branch. + +# How to run it? (Small Example) +You can use this command in two different ways. +1) Simple push +``` +gits push +``` +2) Using rebase +``` +gits push --rebase branchname +``` +After using this command, your local branch would be pushed to the remote branch. diff --git a/docs/rebase.md b/docs/rebase.md new file mode 100644 index 0000000..ee14c9c --- /dev/null +++ b/docs/rebase.md @@ -0,0 +1,32 @@ +# About gits rebase +This is a highly simplified version of git rebase command. +This interactive command asks for the branch that you want to rebase and automatically rebases it off master. +This is the most common scenario. +The original GIT rebase command is a little un-intuitive and there is always a confusion, about the source branch and the destination branch. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_rebase.py). + +# Code Description +## Functions +1. gits_rebase(args): +On execution, this commands asks for the user input about whether the rebase is for current branch or some other branch. +If user chooses the second option, user has to specify name of the branch in another input. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Consider the scenario where you've been working on some feature on your branch which is checked out from the master. +Now, other developers from your team has merged their part to the master and you need to use those changes in the feature you are working on currently. +You can use this command in this way to get those changes: +``` +$ gits rebase +Is the rebase on current branch? +[yes/no][y/n]y +``` +If you are interested in rebasing some other branch names "foo", use the command in following way: +``` +$ gits rebase +Is the rebase on current branch? +[yes/no][y/n]n +Enter the name of the branch you want to rebase: foo +``` \ No newline at end of file diff --git a/docs/reset.md b/docs/reset.md new file mode 100644 index 0000000..16b2311 --- /dev/null +++ b/docs/reset.md @@ -0,0 +1,22 @@ +# About gits reset +'Reset' intuitively means a HARD reset. +This functionality does a HARD reset on your branch, and makes it even with the remote branch. +This aims to simplify the confusion between HARD and the SOFT reset. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_reset.py). + +# Code Description +## Functions +1. gits_reset(args): +this function takes **args** object as an input which has an attribute **branch** to store the name of the branch that you want to reset. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Consider the scenario where you are experimenting with someone else's work and to do so, you've cloned that person's development branch "foo" on your local machine. +You tried a bunch of stuff but nothing seem to work out well and you want to get the clean copy back for that branch. +Instead of manually deleting the cloned branch and cloning it again, you can use this command this way: +``` +$ gits reset --branch foo +``` +This will discard any changes present in you local machine and make it in sync with upstream branch. \ No newline at end of file diff --git a/docs/status.md b/docs/status.md new file mode 100644 index 0000000..bf8718e --- /dev/null +++ b/docs/status.md @@ -0,0 +1,21 @@ +# About gits status +This function allows users to see status about +- changes present in the working directory but not moved to the staging area yet. [untracked files] +- changes to the files present inside staging area. [tracked files] +- changes to the files which are not being tracked. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_status.py). + +# Code Description +## Functions +1. gits_status(args): +This function simply displays the difference as mentioned in the above section. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Use the command as below to see the status: +``` +$ gits status +``` + diff --git a/docs/super_reset.md b/docs/super_reset.md new file mode 100644 index 0000000..1cf668e --- /dev/null +++ b/docs/super_reset.md @@ -0,0 +1,24 @@ +# About gits super_reset +Have you ever run into a situation, where you had to clone the repository again? +Yes, this functionality is exactly for that scenario. +It will remove the current repository. +It will clone it again, and add all the remote branches to this freshly cloned repository. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_super_reset.py). + +# Code Description +## Functions +1. super_reset(args): +this function takes **args** object as an input which has an attribute **name** to store the name of the repository that you want to super-reset. +It simply deletes the repository from the file system and clone it again in the same directory. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Consider the scenario where you have made a mess in the whole repository and the only possible way out is by cloning the repo again. +Instead of manually deleting the repository and cloning it all again, you can use this command. +One thing to note here is that unlike all other gits command, this command needs to be executed from the parent directory of repository. +``` +$ gits super-reset --name foo_repository +``` +Successful execution of this command will delete the repository named "foo_repository" and reclone at the same location with all the remote branches. \ No newline at end of file diff --git a/docs/switch.md b/docs/switch.md new file mode 100644 index 0000000..3358b73 --- /dev/null +++ b/docs/switch.md @@ -0,0 +1,18 @@ +# About gits switch +This command is useful for switching between two branches during implementation. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_switch.py). + +# Code Description +## Functions +1. switch_branch(args): +this function takes **args** object as an input which has an attribute **branch_name** to store the name of the branch to be checked out. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Let say you are currently on branch **foo** and now you want to work on branch **bar**. +Use this command in following way to switch to branch **bar**. +``` +$ gits switch foo +``` \ No newline at end of file diff --git a/docs/sync.md b/docs/sync.md new file mode 100644 index 0000000..cc1de84 --- /dev/null +++ b/docs/sync.md @@ -0,0 +1,28 @@ +# About gits sync +This command is particularly useful for developers who always work off the master branch on their own development branch. +In this type of development, it is necessary to keep the development branch upto date with upstream master in order to avoid any merge comflicts in future. +gits sync command basically sync the current branch with upstream trunk (main/master) branch by first syncing the trunk branch and rebasing current branch on the synced trunk. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_sync.py). + +# Code Description +## Functions +1. gits_sync(args): +this function takes **args** object as an input which has an attribute **source** which represents the branch to be considered as a source for the syncing. +Function returns True for successful execution and False otherwise with an exception. + + +# How to run it? (Small Example) +Let say your team maintains a branch named **main** for any project with upto date changes. +Every developer in the team uses this branch as a source for their personal development tasks and merge the changes to this **main** branch again when they are done with their task. +Just like others, you also checked out you personal branch off the **main** and started working your task. +However, you realized that it has been a few days ever since you started working on this task and other developers have already merged some changes to the **main** branch. +Here, you can use the following command to sync your local development branch with upstream **main** branch: +``` +$ gits sync -source main +``` +If you do not provide source, it will take the trunk branch by default. +``` +$ gits sync +``` \ No newline at end of file diff --git a/docs/track.md b/docs/track.md new file mode 100644 index 0000000..020f004 --- /dev/null +++ b/docs/track.md @@ -0,0 +1,24 @@ +# About gits track +This command is used to move files from current working directory to the staging area. +Only those files which are moved to the staging area are considered for the upcoming commits. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_track.py). + +# Code Description +## Functions +1. gits_track(args): +this function takes **args** object as an input which has an attribute **filenames** to store the list of files to move from working directory to staging area. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Let say you have made changes to the two files since last commit: foo.py and bar.py. You want these changes to be considered for the next commit. Here are some examples on how to use this command. +``` +$ gits track foo.py +$ gits track bar.py +$ gits track foo.py bar.py +``` +If these are the only changes made after last commit, you can also use the following command: +``` +$ gits track . +``` \ No newline at end of file diff --git a/docs/undo.md b/docs/undo.md new file mode 100644 index 0000000..058a0e7 --- /dev/null +++ b/docs/undo.md @@ -0,0 +1,22 @@ +# About gits undo +This command is useful when the changes you've made after last commit is not working well and you want to update your working directory with last stable commit instead of manually undoing the changes. +Be careful while using this command because changes present in the working directory will be lost after execution of this command. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_undo.py). + +# Code Description +## Functions +1. gits_undo(args): +this function takes **args** object as an input which has an attribute **filenames** to store the list of files for which we want to undo the changes. +Function returns True for successful execution and False otherwise with an exception. + + +# How to run it? (Small Example) +let say since your last commit, you've made changes to the files: foo.py and bar.py. However, changes are not showing expected result and you want to undo those changes. +To undo those changes, consider the following examples: +``` +$ gits undo foo.py +$ gits undo bar.py +$ gits undo foo.py bar.py +``` \ No newline at end of file diff --git a/docs/untrack.md b/docs/untrack.md new file mode 100644 index 0000000..a7daee4 --- /dev/null +++ b/docs/untrack.md @@ -0,0 +1,26 @@ +# About gits untrack +This functionality is exactly opposite of another Gits feature: track. +This command moves files from staging area to the working directory back. +These untracked files will not be considered for the upcoming commits. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_untrack.py). + +# Code Description +## Functions +1. gits_untrack(args): +This function takes **args** object as an input which has an attribute **filenames** to store the list of files to move from staging area to working directory. +Function returns True for successful execution and False otherwise with an exception. + +# How to run it? (Small Example) +Let say you have already used track command to move foo.py and bar.py from working directory to staging area. +To untrack these files, consider following examples: +``` +$ gits untrack foo.py +$ gits untrack bar.py +$ gits untrack foo.py bar.py +``` +To untrack all the files currently present inside staging area, use the following command: +``` +$ gits untrack . +``` \ No newline at end of file diff --git a/docs/upstream.md b/docs/upstream.md new file mode 100644 index 0000000..825045a --- /dev/null +++ b/docs/upstream.md @@ -0,0 +1,23 @@ +# About gits set upstream +This command set upstream for a local branch to a remote branch. +It can also be used to set upstream for a remote branch to the original branch in case of a forked repo. + +# Location of Code +The code that implements the above mentioned gits functionality is located [here](https://github.com/harshitpatel96/GITS/blob/master/code/gits_setupstream.py). + +# Code Description +## Functions +1. upstream(args): +This function takes **args** object as an input which has an attribute **local** to store the name of the local branch, **remote** to store the name of the remote branch and **upstream** to store the name of the branch present on the original repository in case of forked repo. +Function returns True for successful execution and False otherwise with an exception. + + +# How to run it? (Small Example) +There are two variation of this command. If you want your local branch names "foo" to be upstream with remote branch "bar", you can use this command like this: +``` +$ gits upstream --local foo --remote bar +``` +In case of forked repository, if you want your remote branch "foo" to track an upstream branch "bar" from the original repository, you can use the following command: +``` +$ gits upstream --remote foo --upstream bar +``` \ No newline at end of file diff --git a/tasks.md b/tasks.md new file mode 100644 index 0000000..234faaf --- /dev/null +++ b/tasks.md @@ -0,0 +1,43 @@ +## Things already done: +1. Supported functionalities + - gits pr_update + - gits profile + - gits rebase + - gits reset + - gits set + - gits upstream + - gits super reset + - gits add + - gits commit + - gits create_branch + - gits logging +2. Currently, this project can only be executed on Linux or Mac operating system's. + +## Things need to be done: +1. Transform this 'what' documentation to 'how' documentation. +2. Write instructions to setup an environment to run this project. +3. Add Unit tests for every GITS command. +4. Refactor the code using a suitable pattern if possible. +5. Split the implementation into src and tst directories. +6. Implement functional tests for this new command line tool. +7. Add new simplified commands in addition to what is already implemented. +8. Add unit test coverage checker before Gits Push. +9. Make this tool available for windows operating system as well. +10. New functionalities: + - gits sync + - gits push + - gits init + - gits status + - gits track + - gits untrack + - gits diff + - gits checkout + - gits branch + + + +## Deliverables for phase 2: +1. Well defined automated testing setup. +2. Mixture of What and How documentation. +3. Implementation of new additional functionalities. + diff --git a/test/test_changedir.py b/test/test_changedir.py new file mode 100644 index 0000000..293725a --- /dev/null +++ b/test/test_changedir.py @@ -0,0 +1,10 @@ +import os + +currpath = os.path.abspath(".") + +if "code" not in currpath: + if "test" in currpath: + os.chdir(os.path.join("..", "code")) + else: + os.chdir("code") + diff --git a/test/test_gits_add.py b/test/test_gits_add.py new file mode 100644 index 0000000..820ccc5 --- /dev/null +++ b/test/test_gits_add.py @@ -0,0 +1,59 @@ +import argparse +import sys +import os + +sys.path.insert(1, os.getcwd()) + +from gits_add import gits_add_func +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=["test1", "test2"])) +@patch("subprocess.Popen") +def test_gits_add_happy_case(mock_var, mock_args): + """ + Function to test gits_add, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_add_func(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("gits_logging.gits_logger") +def test_gits_add_sad_case(mock_err, mock_args): + """ + Function to test gits add, failure case + """ + mock_args = parse_args(mock_args) + test_result = gits_add_func(mock_args) + assert False == test_result + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=[])) +@patch("subprocess.Popen") +def test_gits_add_happy_case_no_files(mock_var, mock_args): + """ + Function to test gits add, success case when no files are passes as argument + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_add_func(mock_args) + assert True == test_result, "Normal case" diff --git a/test/test_gits_branch.py b/test/test_gits_branch.py new file mode 100644 index 0000000..ad8c39c --- /dev/null +++ b/test/test_gits_branch.py @@ -0,0 +1,47 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_branch import gits_branch +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_branch_happy_case(mock_var, mock_args): + """ + Function to test gits branch, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_branch(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_branch_sad_case(mock_var, mock_args): + """ + Function to test gits branch, failure case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_branch(mock_args) + assert False == test_result, "Normal case" \ No newline at end of file diff --git a/test/test_gits_commit.py b/test/test_gits_commit.py new file mode 100644 index 0000000..1e20507 --- /dev/null +++ b/test/test_gits_commit.py @@ -0,0 +1,76 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_commit import gits_commit_func +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(m="test_commit", amend=True)) +@patch("subprocess.Popen") +def test_gits_commit_happy_case_with_amend(mock_var, mock_args): + """ + Function to test gits_commit, success case with amend message + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_commit_func(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(m="test_commit", amend=False)) +@patch("subprocess.Popen") +def test_gits_commit_happy_case_without_amend(mock_var, mock_args): + """ + Function to test gits_commit, success case with no amend message + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_commit_func(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(m=None, amend=False)) +@patch("subprocess.Popen") +def test_gits_commit_sad_case_with_no_message(mock_var, mock_args): + """ + Function to test gits_commit, failure case with no commit message + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_commit_func(mock_args) + assert False == test_result + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("gits_logging.gits_logger") +def test_gits_commit_sad_case_with_no_arguments(mock_err, mock_args): + """ + Function to test gits_commit, failure case with no arguments passed + """ + mock_args = parse_args(mock_args) + test_result = gits_commit_func(mock_args) + assert False == test_result diff --git a/test/test_gits_create_branch.py b/test/test_gits_create_branch.py new file mode 100644 index 0000000..5400cac --- /dev/null +++ b/test/test_gits_create_branch.py @@ -0,0 +1,64 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_create_branch import create_branch +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", return_value=argparse.Namespace(b="branch name")) +@patch("subprocess.Popen") +@patch("helper.get_trunk_branch_name", return_value="master branch") +def test_git_create_branch_happy_case(mock_master_branch, mock_var, mock_args): + """ + Function to test gits_create_branch, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = create_branch(mock_args) + assert test_result == True + + +@patch("argparse.ArgumentParser.parse_args", return_value=argparse.Namespace(b=None)) +@patch("subprocess.Popen") +@patch("helper.get_trunk_branch_name", return_value="master branch") +def test_git_create_branch_sad_case_with_no_branch(mock_master_branch, mock_var, mock_args): + """ + Function to test gits_create_branch, failure case with no branch name provided + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = create_branch(mock_args) + assert test_result == False + + +@patch("argparse.ArgumentParser.parse_args", return_value=argparse.Namespace()) +@patch("subprocess.Popen") +@patch("helper.get_trunk_branch_name", return_value="master branch") +def test_git_create_branch_sad_case_with_no_arguments(mock_master_branch, mock_var, mock_args): + """ + Function to test gits_create_branch, failure case with no arguments passed + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = create_branch(mock_args) + assert test_result == False diff --git a/test/test_gits_diff.py b/test/test_gits_diff.py new file mode 100644 index 0000000..460d842 --- /dev/null +++ b/test/test_gits_diff.py @@ -0,0 +1,49 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_diff import gits_diff +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_diff_happy_case(mock_var, mock_args): + """ + Function to test gits diff, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_diff(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_diff_sad_case(mock_var, mock_args): + """ + Function to test gits diff, failure case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_diff(mock_args) + assert False == test_result + + diff --git a/test/test_gits_init.py b/test/test_gits_init.py new file mode 100644 index 0000000..fa128b0 --- /dev/null +++ b/test/test_gits_init.py @@ -0,0 +1,55 @@ +import argparse +import sys +import os +import shutil + +sys.path.insert(1, os.getcwd()) + +from gits_init import gits_init +from mock import patch + + +def remove_extras(path): + files = os.listdir(path) + for file in files: + if "py" in file: + continue + try: + shutil.rmtree(file) + except: + os.remove(file) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(barre=None, template=None, amend=True)) +@patch("subprocess.Popen", return_value="anything") +def test_gits_init_normal(mock_var1, mock_args): + """ + Function to test gits init, success case + """ + test_result = gits_init(mock_args) + remove_extras(".") + assert test_result == True, "Normal init" + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(barre=True, template=None, amend=True)) +@patch("subprocess.Popen", return_value="anything") +def test_gits_init_bare(mock_var1, mock_args): + """ + Function to test gits init --bare, success case + """ + test_result = gits_init(mock_args) + remove_extras(".") + assert test_result == True, "Bare init" + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(barre=None, template="test_template", amend=True)) +@patch("subprocess.Popen", return_value="anything") +def test_gits_init_template(mock_var1, mock_args): + """ + Function to test gits init --template, success case + """ + test_result = gits_init(mock_args) + remove_extras(".") + assert test_result == True, "Template init" + diff --git a/test/test_gits_merge.py b/test/test_gits_merge.py new file mode 100644 index 0000000..7959692 --- /dev/null +++ b/test/test_gits_merge.py @@ -0,0 +1,39 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_merge import merge_branch +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", return_value=argparse.Namespace(branch_name="branch name")) +@patch("subprocess.Popen") +def test_git_create_branch_happy_case(mock_var, mock_args): + """ + Function to test gits_merge_branch, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = merge_branch(mock_args) + assert test_result == True + + +@patch("argparse.ArgumentParser.parse_args", return_value=argparse.Namespace()) +def test_git_create_branch_sad_case(mock_args): + """ + Function to test gits_merge_branch, failure case when no arguments + """ + mock_args = parse_args(mock_args) + test_result = merge_branch(mock_args) + assert test_result == False \ No newline at end of file diff --git a/test/test_gits_pull.py b/test/test_gits_pull.py new file mode 100644 index 0000000..6d6baef --- /dev/null +++ b/test/test_gits_pull.py @@ -0,0 +1,120 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_pull import gits_pull +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(nocommit=True, rebase=False, branch="branch name")) +@patch("subprocess.Popen") +@patch("helper.get_current_branch", return_value="current branch") +def test_gits_pull_happy_case_with_no_commit_and_given_branch(mock_current_branch, mock_var, mock_args): + """ + Function to test gits pull, success case with no commits, no rebase and given branch + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_pull(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(nocommit=True, rebase=False, branch=False)) +@patch("subprocess.Popen") +@patch("helper.get_current_branch", return_value="current branch") +def test_gits_pull_happy_case_with_no_commit_and_current_branch(mock_current_branch, mock_var, mock_args): + """ + Function to test gits pull, success case with no commits, no rebase and given branch + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_pull(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(nocommit=False, rebase=True, branch="branch name")) +@patch("subprocess.Popen") +@patch("helper.get_current_branch", return_value="current branch") +def test_gits_pull_happy_case_with_commit_and_given_branch(mock_current_branch, mock_var, mock_args): + """ + Function to test gits pull, success case with commits, rebase and given branch + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_pull(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(nocommit=True, rebase=True, branch="branch name")) +@patch("subprocess.Popen") +@patch("helper.get_current_branch", return_value="current branch") +def test_gits_pull_sad_case_with_no_commit_and_rebase(mock_current_branch, mock_var, mock_args): + """ + Function to test gits pull, failure case with no commits, but rebase + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_pull(mock_args) + assert False == test_result + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(nocommit=True, rebase=True, branch="branch name")) +@patch("subprocess.Popen") +def test_gits_pull_sad_case_with_uncommitted_changes(mock_var, mock_args): + """ + Function to test gits pull, failure case with uncommited changes + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'anything', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_pull(mock_args) + assert False == test_result + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +@patch("helper.get_current_branch", return_value="current branch") +def test_gits_pull_sad_case_with_no_arguments(mock_current_branch, mock_var, mock_args): + """ + Function to test gits pull, failure case with no arguments passed + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_pull(mock_args) + assert False == test_result \ No newline at end of file diff --git a/test/test_gits_push.py b/test/test_gits_push.py new file mode 100644 index 0000000..0a89ba8 --- /dev/null +++ b/test/test_gits_push.py @@ -0,0 +1,66 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_push import gits_push +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(rebase="branch name")) +@patch("subprocess.Popen") +@patch("helper.get_current_branch", return_value="current branch") +def test_gits_push_happy_case_with_rebase(mock_current_branch, mock_var, mock_args): + """ + Function to test gits push, success case with rebase + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_push(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(rebase="branch name")) +@patch("subprocess.Popen") +def test_gits_push_sad_case_with_uncommitted_changes(mock_var, mock_args): + """ + Function to test gits push, failure case with uncommitted changes + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'anything', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_push(mock_args) + assert False == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +@patch("helper.get_current_branch", return_value="current branch") +def test_gits_push_sad_case_with_no_arguments(mock_current_branch, mock_var, mock_args): + """ + Function to test gits push, failure case with no arguments + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': (b'', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_push(mock_args) + assert False == test_result, "Normal case" \ No newline at end of file diff --git a/test/test_gits_rebase.py b/test/test_gits_rebase.py new file mode 100644 index 0000000..a41b9ca --- /dev/null +++ b/test/test_gits_rebase.py @@ -0,0 +1,59 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_rebase import gits_rebase +from mock import patch, Mock + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +@patch("builtins.input", return_value="yes") +def test_gits_rebase_happy_case_current_branch(mock_input, mock_var, mock_args): + """ + Function to test gits rebase, success case with rebase on current branch + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = gits_rebase(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +@patch("builtins.input", side_effect=["no", "branch name"]) +def test_gits_rebase_happy_case_given_branch(mock_input, mock_var, mock_args): + """ + Function to test gits rebase, success case with rebase on given branch + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = gits_rebase(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +@patch("builtins.input", side_effect=["no", "branch name"]) +def test_gits_rebase_sad_case(mock_input, mock_var, mock_args): + """ + Function to test gits rebase, failure case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = gits_rebase(mock_args) + assert False == test_result, "Normal case" diff --git a/test/test_gits_reset.py b/test/test_gits_reset.py new file mode 100644 index 0000000..44c9f22 --- /dev/null +++ b/test/test_gits_reset.py @@ -0,0 +1,47 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_reset import gits_reset +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(branch="branch name")) +@patch("subprocess.Popen") +def test_gits_reset_happy_case(mock_var, mock_args): + """ + Function to test gits reset, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_reset(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_reset_sad_case(mock_var, mock_args): + """ + Function to test gits reset, failure case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_reset(mock_args) + assert False == test_result \ No newline at end of file diff --git a/test/test_gits_status.py b/test/test_gits_status.py new file mode 100644 index 0000000..84e386b --- /dev/null +++ b/test/test_gits_status.py @@ -0,0 +1,47 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_status import gits_status +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_track_happy_case(mock_var, mock_args): + """ + Function to test gits status, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_status(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_track_sad_case(mock_var, mock_args): + """ + Function to test gits status, failure case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_status(mock_args) + assert False == test_result \ No newline at end of file diff --git a/test/test_gits_switch.py b/test/test_gits_switch.py new file mode 100644 index 0000000..c2e154e --- /dev/null +++ b/test/test_gits_switch.py @@ -0,0 +1,47 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_switch import switch_branch +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(branch_name="branch name")) +@patch("subprocess.Popen") +def test_gits_switch_happy_case(mock_var, mock_args): + """ + Function to test gits switch, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = switch_branch(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("subprocess.Popen") +def test_gits_switch_sad_case(mock_var, mock_args): + """ + Function to test gits switch, failure case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = switch_branch(mock_args) + assert False == test_result, "Normal case" diff --git a/test/test_gits_track.py b/test/test_gits_track.py new file mode 100644 index 0000000..37948a0 --- /dev/null +++ b/test/test_gits_track.py @@ -0,0 +1,59 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_track import gits_track +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=["test1", "test2"])) +@patch("subprocess.Popen") +def test_gits_track_happy_case(mock_var, mock_args): + """ + Function to test gits track, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_track(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("gits_logging.gits_logger") +def test_gits_track_sad_case(mock_err, mock_args): + """ + Function to test gits track, failure case + """ + mock_args = parse_args(mock_args) + test_result = gits_track(mock_args) + assert False == test_result + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=[])) +@patch("subprocess.Popen") +def test_gits_track_happy_case_no_files(mock_var, mock_args): + """ + Function to test gits track, success case when no files are passed as argument + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_track(mock_args) + assert True == test_result, "Normal case" \ No newline at end of file diff --git a/test/test_gits_undo.py b/test/test_gits_undo.py new file mode 100644 index 0000000..caef288 --- /dev/null +++ b/test/test_gits_undo.py @@ -0,0 +1,59 @@ +import argparse +import sys +import os + +sys.path.insert(1, os.getcwd()) + +from gits_undo import gits_undo +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=["test1", "test2"])) +@patch("subprocess.Popen") +def test_gits_undo_happy_case(mock_var, mock_args): + """ + Function to test gits_undo, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_undo(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("gits_logging.gits_logger") +def test_gits_undo_sad_case(mock_err, mock_args): + """ + Function to test gits undo, failure case + """ + mock_args = parse_args(mock_args) + test_result = gits_undo(mock_args) + assert False == test_result + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=[])) +@patch("subprocess.Popen") +def test_gits_undo_happy_case_no_files(mock_var, mock_args): + """ + Function to test gits undo, success case when no files are passed as argument + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_undo(mock_args) + assert True == test_result, "Normal case" \ No newline at end of file diff --git a/test/test_gits_untrack.py b/test/test_gits_untrack.py new file mode 100644 index 0000000..ca80ad6 --- /dev/null +++ b/test/test_gits_untrack.py @@ -0,0 +1,59 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from gits_untrack import gits_untrack +from mock import patch, Mock + + +def parse_args(args): + parser = argparse.ArgumentParser() + return parser.parse_args(args) + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=["test1", "test2"])) +@patch("subprocess.Popen") +def test_gits_track(mock_var, mock_args): + """ + Function to test gits track, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_untrack(mock_args) + assert True == test_result, "Normal case" + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace()) +@patch("gits_logging.gits_logger") +def test_gits_track_sad_case(mock_err, mock_args): + """ + Function to test gits untrack, failure case + """ + mock_args = parse_args(mock_args) + test_result = gits_untrack(mock_args) + assert False == test_result + + +@patch("argparse.ArgumentParser.parse_args", + return_value=argparse.Namespace(file_names=[])) +@patch("subprocess.Popen") +def test_gits_untrack_happy_case_no_files(mock_var, mock_args): + """ + Function to test gits track, success case when no files are passed as argument + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + mock_args = parse_args(mock_args) + test_result = gits_untrack(mock_args) + assert True == test_result, "Normal case" \ No newline at end of file diff --git a/test/test_helper.py b/test/test_helper.py new file mode 100644 index 0000000..5f76fcf --- /dev/null +++ b/test/test_helper.py @@ -0,0 +1,94 @@ +import argparse +import os +import sys + +sys.path.insert(1, os.getcwd()) + +from helper import get_current_branch +from mock import patch, Mock + + +@patch("subprocess.Popen") +def test_get_current_branch_happy_case(mock_var): + """ + Function to test fetching current branch, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = get_current_branch() + assert "output" == test_result, "Normal case" + + +@patch("subprocess.Popen") +def test_get_current_branch_sad_case(mock_var): + """ + Function to test fetching current branch, success case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('output', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = get_current_branch() + assert None == test_result + + +@patch("subprocess.Popen") +def test_get_trunk_branch_happy_case_master_branch(mock_var): + """ + Function to test fetching main branch, success case when trunk branch='master' + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('master'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = get_current_branch() + assert "master" == test_result, "Normal case" + + +@patch("subprocess.Popen") +def test_get_trunk_branch_happy_case_main_branch(mock_var): + """ + Function to test fetching main branch, success case when trunk branch='main' + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('main'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = get_current_branch() + assert "main" == test_result, "Normal case" + + +@patch("subprocess.Popen") +def test_get_trunk_branch_happy_case_other_branch(mock_var): + """ + Function to test fetching main branch, success case when trunk branch is any other branch + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('branch'.encode('UTF-8'), 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = get_current_branch() + assert "branch" == test_result, "Normal case" + + +@patch("subprocess.Popen") +def test_get_trunk_branch_sad_case(mock_var): + """ + Function to test fetching main branch, failure case + """ + mocked_pipe = Mock() + attrs = {'communicate.return_value': ('branch', 'error'), 'returncode': 0} + mocked_pipe.configure_mock(**attrs) + mock_var.return_value = mocked_pipe + + test_result = get_current_branch() + assert None == test_result + +