123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- package SimplyGit::Git;
- use strict;
- use warnings;
- use Log::Log4perl qw(:easy);
- use lib ".";
- use SimplyGit::Shellex qw(shellex findBin);
- use Exporter qw(import);
- our @EXPORT_OK = qw(readConfig getStatus returnState addFiles commitChanges pushChanges stashAndReset resetFromUpstream updateGitIgnore);
- # TODO: Handle "optional" passing of logger object
- # Need to identify which subs are called before the logger object is initialized ( if any )
- # and then required the logger object arg for all who don't fit that usecase
- # TODO: Add info/debug logging for all subroutines
- sub checkPath {
- my $path = shift;
- my $logger = shift;
- if ( ! -d $path ) {
- if ( defined $logger && $logger ne "" ) {
- $logger->error("$path doesn't look like a dir, exiting...");
- exit 1;
- } else {
- print "Failed and no logger passed, exiting...\n";
- exit 1;
- }
- }
- }
- sub returnConfigPath {
- my $path = shift;
- my $logger = shift;
- checkPath($path,$logger);
- my $gitConfigPath = $path . "/" . ".git/config";
- return $gitConfigPath;
- }
-
- sub readConfig {
- # This sub is probably not really needed for what I'm trying to do
- # git itself already parses this config...but an interesting exercise non the less
- # and may be useful later
- my $path = shift;
- my $logger = shift;
- my $gitConfigPath = returnConfigPath($path,$logger);
- my $catCmd = findBin("cat",$logger);
- my @configLines = split("\n",shellex("$catCmd $gitConfigPath",$logger));
- # Key is config header, value is hash ref containing config values
- my %gitConfig;
- my @valueLines;
- my $lineCounter = 0;
- foreach my $line ( @configLines ) {
- $lineCounter++;
- #if ( $line =~ m/\[(.*)\]/ ) {
- if ( $line =~ m/\[(.*)\]/ ) {
- #$valueLine =~ /\t(.*)\ =\ (.*)$/;
- $gitConfig{$1} = "";
- }
- }
- # Tag each line with it's heading
- # Only way I could think of that worked to solve how this
- # There are almost certainly better ways
- # TODO
- my @taggedLines;
- my $tag = "NULLTAG";
- foreach my $line ( @configLines ) {
- if ( $line =~ m/\[(.*)\]/ ) {
- $tag = $1;
- } else {
- my $newLine = $tag . $line;
- push(@taggedLines,$newLine);
- }
- }
- # Get all of the tagged lines into a hash structure.
- foreach my $key ( keys %gitConfig ) {
- my %stash;
- foreach my $tl ( @taggedLines ) {
- if ( $tl =~ m/^($key)/ ) {
- $tl =~ s/^($key)//g;
- $tl =~ m/^\t(.*)\ \=\ (.*)$/;
- my $confKey = $1;
- my $confVal = $2;
- $stash{$confKey} = $confVal;
- }
- }
- $gitConfig{$key} = \%stash;
- }
- return %gitConfig;
- }
- sub getStatus {
- my $logger = shift;
- my $gitCmd = findBin("git",$logger);
- my $status = shellex("$gitCmd status -uall --porcelain",$logger);
- chomp $status;
- return $status;
- }
- sub returnState {
- my $logger = shift;
- my $gitCmd = findBin("git",$logger);
- my $currentStatus = getStatus($logger);
- my @statusLines = split("\n", $currentStatus);
- my @untracked;
- my @modified;
- my @added;
- my @deleted;
- foreach my $file ( @statusLines ) {
- $file =~ m/^\ {0,1}([A-Z?]{1,2})\ {1,2}(.*)/;
- my $fileAttrs = $1;
- my $filename = $2;
- my @attrs = split("",$fileAttrs);
- foreach my $attr ( @attrs ) {
- if ( $attr =~ m/\?/ ) {
- push(@untracked, $filename) unless grep $_ eq $filename, @untracked;
- }
-
- if ( $attr =~ m/[M]/ ) {
- push(@modified, $filename) unless grep $_ eq $filename, @modified;
- }
-
- if ( $attr =~ m/[A]/ ) {
- push(@added, $filename) unless grep $_ eq $filename, @added;
- }
- if ( $attr =~ m/[D]/ ) {
- push(@deleted, $filename) unless grep $_ eq $filename, @deleted;
- }
- }
- }
- return ( \@untracked, \@modified, \@added, \@deleted );
- }
- sub addFiles {
- my $filesToAddRef = shift;
- my $logger = shift;
- my $gitCmd = findBin("git",$logger);
- foreach my $file ( @$filesToAddRef ) {
- shellex("$gitCmd add $file",$logger);
- }
- }
- # TODO: Possibly worth returning output for commitChanges(), pushChanges(), stashAndReset, even if I'm not using it right now
- sub commitChanges {
- my $commitMsg = shift;
- chomp $commitMsg;
- my $logger = shift;
- my $gitCmd = findBin("git",$logger);
- shellex("$gitCmd commit -m \"$commitMsg\"",$logger);
- }
- sub pushChanges {
- my $logger = shift;
- my $gitCmd = findBin("git",$logger);
- my $output = shellex("$gitCmd push",$logger);
- }
- sub stashAndReset {
- my $logger = shift;
- my $gitCmd = findBin("git",$logger);
- shellex("$gitCmd stash",$logger);
- my @stashList = split("\n", shellex("$gitCmd stash list",$logger));
- my $stashCount = scalar @stashList;
- foreach my $stashNum ( 1..$stashCount ) {
- shellex("$gitCmd stash drop 0",$logger);
- }
- # TODO: Depending on use case need to do more here
- shellex("$gitCmd rebase",$logger);
- }
- sub resetFromUpstream {
- # git stash and git reset --hard and git pull ? I think
- }
- sub updateGitIgnore {
- my $path = shift;
- # Maybe better to accept an array of values
- my $ignoreValue = shift;
- my $logger = shift;
- checkPath($path,$logger);
- my $filename = $path . "/" . ".gitignore";
- # Make sure we're not appending/writing if entry already exists in gitignore
- if ( -f $filename ) {
- my $catCmd = findBin("cat",$logger);
- my @ignoreLines = split("\n",shellex("$catCmd $filename",$logger));
- if ( ! grep( /^$ignoreValue$/, @ignoreLines ) ) {
- # TODO: What if logger object is not passed in?
- open(my $fh, ">>", $filename) or die $logger->error("Couldn't open $filename, exiting...");
- chomp $ignoreValue;
- print $fh "$ignoreValue\n";
- close $fh;
- }
- } else {
- open(my $fh, ">", $filename) or die $logger->error("Couldn't open $filename, exiting...");
- chomp $ignoreValue;
- print $fh "$ignoreValue\n";
- close $fh;
- }
- }
- sub appendRepoUserConfig {
- }
|