view release on metacpan or search on metacpan
lib/App/GitGot/Command.pm view on Meta::CPAN
}
else {
$scheme = "App::GitGot::Outputter::$scheme"
}
try {
eval "use $scheme";
die $@ if $@;
}
catch {
say "Failed to load color scheme '$scheme'.\nExitting now.\n";
exit(5);
};
return $scheme->new({ no_color => $self->no_color });
}
sub execute {
my( $self , $opt , $args ) = @_;
$self->_set_args( $args );
$self->_set_opt( $opt );
lib/App/GitGot/Command.pm view on Meta::CPAN
my $repo_type = $repo->type;
if ( $repo_type eq 'git' ) { $fxn = '_git_fetch' }
### FIXME elsif( $repo_type eq 'svn' ) { $fxn = 'svn_update' }
else { $status = $self->error("ERROR: repo type '$_' not supported") }
$status = $self->$fxn($repo) if ($fxn);
next REPO if $self->quiet and !$status;
say "$msg$status";
}
}
sub _find_repo_root {
my( $self , $path ) = @_;
my $dir = path( $path );
# find repo root
while ( ! grep { -d and $_->basename eq '.git' } $dir->children ) {
lib/App/GitGot/Command.pm view on Meta::CPAN
for my $repo ( $self->active_repos ) {
next unless $repo->path eq $dir->absolute;
my $repo_remote = ( $repo->repo and -d $repo->path ) ? $repo->repo
: ( $repo->repo ) ? $repo->repo . ' (Not checked out)'
: ( -d $repo->path ) ? 'NO REMOTE'
: 'ERROR: No remote and no repo?!';
printf "%3d) ", $repo->number;
if ( $self->quiet ) { say $repo->label }
else {
printf "%-${max_len}s %-4s %s\n",
$repo->label, $repo->type, $repo_remote;
if ( $self->verbose ) {
printf " tags: %s\n" , $repo->tags if $repo->tags;
}
}
return 1;
}
say "repository not in Got list";
return;
}
sub _read_config {
my $file = shift;
my $config;
if ( -e $file ) {
try { $config = LoadFile( $file ) }
catch { say "Failed to parse config..."; exit };
}
# if the config is completely empty, bootstrap _something_
return $config // [ {} ];
}
sub _run_git_cherry {
my( $self , $entry ) = @_;
my $msg = '';
lib/App/GitGot/Command.pm view on Meta::CPAN
### FIXME elsif( $repo_type eq 'svn' ) { $fxn = 'svn_status' }
else { $status = $self->error("ERROR: repo type '$repo_type' not supported") }
$status = $self->$fxn($repo) if ($fxn);
next REPO if $self->quiet and !$status;
}
elsif ( $repo->repo ) { $status = 'Not checked out' }
else { $status = $self->error("ERROR: repo '$label' does not exist") }
say "$msg$status";
}
}
sub _update {
my( $self , @repos ) = @_;
my $max_len = $self->max_length_of_an_active_repo_label;
REPO: for my $repo ( @repos ) {
next REPO unless $repo->repo;
lib/App/GitGot/Command.pm view on Meta::CPAN
my $repo_type = $repo->type;
if ( $repo_type eq 'git' ) { $fxn = '_git_update' }
### FIXME elsif( $repo_type eq 'svn' ) { $fxn = 'svn_update' }
else { $status = $self->error("ERROR: repo type '$_' not supported") }
$status = $self->$fxn($repo) if ($fxn);
next REPO if $self->quiet and !$status;
say "$msg$status";
}
}
# override this in commands that shouldn't use IO::Page -- i.e., ones that
# need to do incremental output
sub _use_io_page { 1 }
1;
lib/App/GitGot/Command/add.pm view on Meta::CPAN
@dirs = Path::Iterator::Rule->new->dir->is_git->all(@dirs);
}
$self->_process_dir($_) for map { path($_)->absolute } @dirs;
}
sub _build_new_entry_from_user_input {
my( $self, $path ) = @_;
unless ( -e "$path/.git" ) {
say STDERR "ERROR: Non-git repos not supported at this time.";
exit(1);
}
my( $repo, $type ) = $self->_init_for_git( $path );
# if 'defaults' option is true, tell IO::Prompt::Simple to use default choices
$ENV{PERL_IOPS_USE_DEFAULT} = $self->opt->defaults;
return unless prompt( "\nAdd repository at '$path'? ", { yn => 1, default => 'y' } );
lib/App/GitGot/Command/chdir.pm view on Meta::CPAN
use Moo;
extends 'App::GitGot::Command';
use namespace::autoclean;
sub command_names { qw/ chdir cd / }
sub _execute {
my( $self, $opt, $args ) = @_;
unless ( $self->active_repos and $self->active_repos == 1 ) {
say STDERR 'ERROR: You need to select a single repo';
exit(1);
}
my( $repo ) = $self->active_repos;
chdir $repo->path
or say STDERR "ERROR: Failed to chdir to repo ($!)" and exit(1);
exec $ENV{SHELL};
}
1;
### FIXME docs
__END__
lib/App/GitGot/Command/checkout.pm view on Meta::CPAN
my $repo_type = $repo->type;
if ( $repo_type eq 'git' ) { $fxn = '_git_checkout' }
### FIXME elsif( $repo_type eq 'svn' ) { $fxn = 'svn_update' }
else { $status = $self->error("ERROR: repo type '$_' not supported") }
$status = $self->$fxn($repo, $branch) if ($fxn);
next REPO if $self->quiet and !$status;
say "$msg$status";
}
}
sub _git_checkout {
my ( $self, $entry, $branch ) = @_
or die "Need entry";
# no callback because we need to run checkout even if just cloned
$self->_git_clone_or_callback( $entry , sub { '' } );
lib/App/GitGot/Command/clone.pm view on Meta::CPAN
);
}
sub _use_io_page { 0 }
sub _execute {
my ( $self, $opt, $args ) = @_;
my ( $repo , $path ) = @$args;
$repo // ( say STDERR 'ERROR: Need the URL to clone!' and exit(1) );
my $cwd = getcwd
or( say STDERR "ERROR: Couldn't determine path" and exit(1) );
my $name = path( $repo )->basename;
$name =~ s/.git$//;
$path //= "$cwd/$name";
$path = path( $path )->absolute;
my $tags;
unless ( $self->opt->defaults ) {
$name = prompt( 'Name: ' , $name );
while() {
$path = prompt( 'Path: ' , $path );
last if not path($path)->exists;
say "can't clone into '$path': directory already exists";
}
$tags = prompt( 'Tags: ' , $tags );
}
my $new_entry = App::GitGot::Repo::Git->new({ entry => {
repo => $repo,
name => $name,
type => 'git',
path => $path,
}});
$new_entry->{tags} = $tags if $tags;
say "Cloning into '$path'..." unless $self->quiet;
$new_entry->clone(
{ recursive => $self->opt->recursive },
$repo , $path
);
$self->add_repo( $new_entry );
$self->write_config;
}
1;
lib/App/GitGot/Command/do.pm view on Meta::CPAN
sub _run_in_repo {
my( $self, $repo, $cmd ) = @_;
if ( not -d $repo->path ) {
printf "repo %s: no repository found at path '%s'\n",
$repo->label, $repo->path;
return;
}
say "\n## repo ", $repo->label, "\n" unless $self->opt->with_repo;
my $prefix = $self->opt->with_repo ? $repo->label . ': ' : '';
say $prefix, $_ for split "\n", capture_stdout {
$CWD = $repo->path;
system $cmd;
};
}
1;
### FIXME docs
__END__
lib/App/GitGot/Command/fork.pm view on Meta::CPAN
return (
[ 'noclone|n' => 'If set, do not check out a local working copy of the forked repo' ] ,
[ 'noremoteadd|N' => 'If set, do not add the forked repo as the "upstream" repo in the new working copy' ] ,
);
}
sub _execute {
my( $self, $opt, $args ) = @_;
try_load_class('Net::GitHub') or
say "Sorry, Net::GitHub is required for 'got fork'. Please install it."
and exit(1);
my $github_url = shift @$args
or say STDERR "ERROR: Need the URL of a repo to fork!" and exit(1);
my( $owner , $repo_name ) = _parse_github_url( $github_url );
my %gh_args = _parse_github_identity();
say "Forking '$owner/$repo_name'..." unless $self->quiet;
my $resp = Net::GitHub->new( %gh_args )->repos->create_fork( $owner , $repo_name );
my $path = cwd() . "/$repo_name";
my $new_repo = App::GitGot::Repo::Git->new({ entry => {
name => $repo_name ,
path => $path ,
repo => $resp->{ssh_url} ,
type => 'git' ,
}});
if ( ! $self->opt->noclone ) {
say "Cloning into $path" unless $self->quiet;
$new_repo->clone( $resp->{ssh_url} );
if ( ! $self->opt->noremoteadd ) {
say "Adding '$github_url' as remote 'upstream'..."
unless $self->quiet;
$new_repo->remote( add => upstream => $github_url );
}
}
$self->add_repo( $new_repo );
$self->write_config;
}
sub _parse_github_identity {
my $file = path( File::HomeDir::Tiny::home() , '.github-identity' );
$file->exists or
say STDERR "ERROR: Can't find $file" and exit(1);
my @lines = $file->lines;
my %config;
foreach ( @lines ) {
chomp;
next unless $_;
my( $k , $v ) = split /\s/;
$config{$k} = $v;
}
if ( defined $config{access_token} ) {
return ( access_token => $config{access_token} )
}
elsif ( defined $config{pass} and defined $config{user} ) {
return ( login => $config{user} , pass => $config{pass} )
}
else {
say STDERR "Couldn't parse password or access_token info from ~/.github-identity"
and exit(1);
}
}
sub _parse_github_url {
my $url = shift;
my( $owner , $repo ) = $url =~ m|/github.com/([^/]+)/([^/]+?)(?:\.git)?$|
or say STDERR "ERROR: Can't parse '$url'.\nURL needs to be of the form 'github.com/OWNER/REPO'.\n"
and exit(1);
return( $owner , $repo );
}
1;
__END__
=pod
lib/App/GitGot/Command/gc.pm view on Meta::CPAN
REPO: for my $repo ( $self->active_repos ) {
next REPO unless $repo->type eq 'git';
try {
printf "%3d) %-${max_len}s : ", $repo->number , $repo->label unless $self->quiet;
# really wish this gave _some_ kind of output...
$repo->gc;
printf "%s\n", $self->major_change( 'COLLECTED' ) unless $self->quiet;
}
catch {
say STDERR $self->error( 'ERROR: Problem with GC on repo ' , $repo->label );
say STDERR "\n" , Dumper $_;
};
}
}
1;
## FIXME docs
__END__
lib/App/GitGot/Command/lib.pm view on Meta::CPAN
[ 'separator=s' => 'library path separator' => { default => ':' } ] ,
);
}
sub _execute {
my( $self, $opt, $args ) = @_;
my @libs = map { $self->_expand_lib($_) } $self->_raw_libs( $args );
no warnings; # $ENV{$self->opt->libvar} can be undefined
say join $self->opt->separator, uniq @libs, split ':', $ENV{$self->opt->libvar};
}
sub _expand_lib {
my( $self, $lib ) = @_;
return path($lib)->absolute if $lib =~ m#^(?:\.|/)#;
if ( $lib =~ s/^\@(\w+)// ) {
# it's a tag
lib/App/GitGot/Command/list.pm view on Meta::CPAN
sub _execute {
my( $self, $opt, $args ) = @_;
if ( $self->opt->json ) {
try_load_class( 'JSON::MaybeXS' )
or die "json serializing requires the module 'JSON::MaybeXS' to be installed\n";
my @data = map { {%$_} } $self->active_repos;
say JSON::MaybeXS->new(pretty => 1)->encode( \@data );
return;
}
for my $repo ( $self->active_repos ) {
my $repo_remote = ( $repo->repo and -d $repo->path ) ? $repo->repo
: ( $repo->repo ) ? $repo->repo . ' (Not checked out)'
: ( -d $repo->path ) ? 'NO REMOTE'
: 'ERROR: No remote and no repo?!';
printf "%3d) ", $repo->number;
if ( $self->quiet ) { say $repo->label }
else {
my $max_len = $self->max_length_of_an_active_repo_label;
printf "%-${max_len}s %-4s %s\n", $repo->label, $repo->type, $repo_remote;
if ( $self->verbose and $repo->tags ) {
printf " tags: %s\n" , $repo->tags
}
}
}
lib/App/GitGot/Command/move.pm view on Meta::CPAN
my $target_dir = -d $dest
? path($dest)->child( path($repo->path)->basename )
: $dest;
dirmove( $repo->path => $target_dir )
or die "couldn't move ", $repo->name, " to '$target_dir': $!";
$repo->{path} = "$target_dir";
$self->write_config;
say sprintf '%s moved to %s', $repo->name, $target_dir;
}
}
1;
## FIXME docs
__END__
=pod
lib/App/GitGot/Command/push.pm view on Meta::CPAN
next REPO;
}
try {
printf "%3d) %-${max_len}s : ", $repo->number , $repo->label;
# really wish this gave _some_ kind of output...
my @output = $repo->push;
printf "%s\n", $self->major_change( 'PUSHED' );
}
catch {
say STDERR $self->error( 'ERROR: Problem with push on repo ' , $repo->label );
say STDERR "\n" , Dumper $_;
};
}
}
1;
## FIXME docs
__END__
lib/App/GitGot/Command/remove.pm view on Meta::CPAN
[ 'force' => 'FIXME' ] ,
);
}
sub _use_io_page { 0 }
sub _execute {
my( $self, $opt, $args ) = @_;
unless ( $self->active_repos and @$args or $self->tags) {
say STDERR "ERROR: You need to select one or more repos to remove";
exit(1);
}
my @new_repo_list;
REPO: for my $repo ( $self->all_repos ) {
my $number = $repo->number;
if ( any { $number == $_->number } $self->active_repos ) {
my $name = $repo->label;
if ( $self->opt->force or $self->prompt_yn( "got rm: remove '$name'?" )) {
say "Removed repo '$name'" if $self->verbose;
next REPO;
}
}
push @new_repo_list , $repo;
}
$self->set_full_repo_list( \@new_repo_list );
$self->write_config();
}
lib/App/GitGot/Command/tag.pm view on Meta::CPAN
return (
[ 'add|a' => 'assign tags to the current repository' => { default => 0 } ] ,
[ 'all|A' => 'print out tags of all repositories' => { default => 0 } ] ,
[ 'remove|rm' => 'remove tags from the current repository' => { default => 0 } ] ,
);
}
sub _execute {
my( $self, $opt, $args ) = @_;
return say "not in a got-monitored repo" unless $self->local_repo;
return say "can't --add and --remove at the same time"
if $self->opt->add and $self->opt->remove;
if( $self->opt->add ) {
return $self->_add_tags( @$args );
}
if( $self->opt->remove ) {
return $self->_remove_tags( @$args );
}
$self->_print_tags;
}
sub _add_tags {
my( $self, @tags ) = @_;
$self->local_repo->add_tags( @tags );
$self->write_config;
say "tags added";
}
sub _print_tags {
my $self = shift;
my %tags = map { $_ => 1 } split ' ', $self->local_repo->tags;
if ( $self->opt->all ) {
$tags{$_} ||= 0 for map { split ' ', $_->tags } $self->all_repos
}
for my $t ( sort keys %tags ) {
say $t, ' *' x ( $self->opt->all and $tags{$t} );
}
}
sub _remove_tags {
my( $self, @tags ) = @_;
$self->local_repo->remove_tags(@tags);
$self->write_config;
say "tags removed";
}
1;
__END__
=pod
=encoding UTF-8
lib/App/GitGot/Command/that.pm view on Meta::CPAN
use Moo;
extends 'App::GitGot::Command';
use namespace::autoclean;
sub _execute {
my( $self, $opt, $args ) = @_;
my $path = pop @$args;
defined $path and -d $path
or say STDERR 'ERROR: You must provide a path to a repo to check' and exit 1;
$self->_path_is_managed( $path ) or exit 1;
}
1;
## FIXME docs
__END__
lib/App/GitGot/Command/update_status.pm view on Meta::CPAN
sub options {
my( $class , $app ) = @_;
return (
[ 'show-branch' => 'show which branch' => { default => 0 } ] ,
);
}
sub _execute {
my ( $self, $opt, $args ) = @_;
say "UPDATE";
$self->_update( $self->active_repos );
say "\nSTATUS";
$self->_status( $self->active_repos );
}
1;
## FIXME docs
__END__
=pod