3 #=======================================================================
5 # File ID: 8ed5e844-cf09-11e4-b7ff-000df06acc56
7 # Execute command in remote Git repositories
10 # ©opyleft 2012– Øyvind A. Holm <sunny@sunbase.org>
11 # License: GNU General Public License version 2 or later, see end of
12 # file for legal stuff.
13 #=======================================================================
34 $progname =~ s/^.*\/(.*?)$/$1/;
35 our $VERSION = '0.2.0';
37 our $hostname = `hostname`;
40 Getopt
::Long
::Configure
('bundling');
43 'cmd|c=s' => \
$Opt{'cmd'},
44 'dry-run|n' => \
$Opt{'dry-run'},
45 'help|h' => \
$Opt{'help'},
46 'local|l' => \
$Opt{'local'},
47 'quiet|q+' => \
$Opt{'quiet'},
48 'verbose|v+' => \
$Opt{'verbose'},
49 'version' => \
$Opt{'version'},
51 ) || die("$progname: Option error. Use -h for help.\n");
53 $Opt{'verbose'} -= $Opt{'quiet'};
54 $Opt{'help'} && usage
(0);
55 if ($Opt{'version'}) {
60 if (!length($Opt{'cmd'})) {
61 die("$progname: -c/--cmd option not specified\n");
72 mysystem
($Opt{'cmd'});
73 $Opt{'verbose'} >= 0 && print("\n");
75 open(my $pipefp, 'git remote -v |') or die("$progname: git remote -v: Cannot open pipe: $!\n");
77 while (my $curr = <$pipefp>) {
78 if ($curr =~ /^(\S+)\s+(\S+)\s/) {
79 my ($remote, $url) = ($1, $2);
80 if ($url =~ /^(\S+)\@(\S+):(\S+)$/) {
81 # The URL looks SSHish
82 my ($username, $host, $userdir) = ($1, $2, $3);
83 next if ($userdir =~ /\.git$/); # Avoid bare repos
84 if (!defined($done{"$username$host$userdir"})) {
89 "cd $userdir && (ga-pwd; $Opt{'cmd'})",
92 $done{"$username$host$userdir"} = 1;
93 $Opt{'verbose'} >= 0 && print("\n");
95 } elsif (-d
"$url/.") {
96 if (!defined($done{"$url"}) && chdir($url)) {
97 next if (!-d
".git/."); # Avoid bare repos
98 msg
(0, "($hostname) chdir $url");
100 mysystem
($Opt{'cmd'});
102 $Opt{'verbose'} >= 0 && print("\n");
116 ($retval & 127) && die("\n$progname: Child process interrupted, aborting.\n");
124 msg
(0, sprintf("(%s) %s '", $hostname, $Opt{'dry-run'} ?
"Simulating" : "Executing") .
125 join(" ", @cmd) . "'...");
127 !$Opt{'dry-run'} && system(@cmd) && check_sig
($?
);
133 # Print program version {{{
134 print("$progname $VERSION\n");
140 # Send the help message to stdout {{{
143 if ($Opt{'verbose'}) {
149 Usage: $progname [options] -c COMMAND
151 Execute commands in remote repositories via ssh. Scans all available
152 remotes and checks if it looks SSHish. If it does, it logs in and
153 executes the command specified with the -c/--cmd option in the
158 -c COMMAND, --cmd COMMAND
159 Execute COMMAND in remote repositories.
163 Also execute the command in the local repository.
165 Simulate, don't actually execute any commands.
167 Be more quiet. Can be repeated to increase silence.
169 Increase level of verbosity. Can be repeated.
171 Print version information.
179 # Print a status message to stderr based on verbosity level {{{
180 my ($verbose_level, $Txt) = @_;
182 if ($Opt{'verbose'} >= $verbose_level) {
183 print(STDERR
"$progname: $Txt\n");
191 # This program is free software; you can redistribute it and/or modify
192 # it under the terms of the GNU General Public License as published by
193 # the Free Software Foundation; either version 2 of the License, or (at
194 # your option) any later version.
196 # This program is distributed in the hope that it will be useful, but
197 # WITHOUT ANY WARRANTY; without even the implied warranty of
198 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
199 # See the GNU General Public License for more details.
201 # You should have received a copy of the GNU General Public License
202 # along with this program.
203 # If not, see L<http://www.gnu.org/licenses/>.
205 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :