refactoring
[ghc.git] / sync-all
index deb971f..025b60d 100755 (executable)
--- a/sync-all
+++ b/sync-all
@@ -3,73 +3,6 @@
 use strict;
 use Cwd;
 
-# Usage:
-#
-# ./sync-all [-q] [-s] [--ignore-failure] [-r repo] [--checked-out] [--bare]
-#            [--nofib] [--extra] [--testsuite] [--resume] cmd [git flags]
-#
-# Applies the command "cmd" to each repository in the tree.
-# sync-all will try to do the right thing for both git and darcs repositories.
-#
-# e.g.
-#      ./sync-all -r http://darcs.haskell.org/ghc get
-#          To get any repos which do not exist in the local tree
-#
-#      ./sync-all pull
-#          To pull everything from the default repos
-#
-# -------------- Flags -------------------
-#   -q says to be quite, and -s to be silent.
-#
-#   --resume will restart a command that failed, from the repo at which
-#   it failed. This means you don't need to wait while, e.g., "pull"
-#   goes through all the repos it's just pulled, and tries to pull them
-#   again.
-#
-#   --ignore-failure says to ignore errors and move on to the next repository
-#
-#   -r repo says to use repo as the location of package repositories
-#
-#   --checked-out says that the remote repo is in checked-out layout, as
-#   opposed to the layout used for the main repo.  By default a repo on
-#   the local filesystem is assumed to be checked-out, and repos accessed
-#   via HTTP or SSH are assumed to be in the main repo layout; use
-#   --checked-out to override the latter.
-#
-#   --bare says that the local repo is in bare layout, same as the main repo.
-#   It also means that these repos are bare. You only have to use this flag if
-#   you don't have a bare ghc.git in the current directory and would like to 'get'
-#   all of the repos bare. Requires packages.conf to be present in the current
-#   directory (a renamed packages file from the main ghc repo).
-#
-#   --nofib, --testsuite also get the nofib and testsuite repos respectively
-#
-# ------------ Which repos to use -------------
-# sync-all uses the following algorithm to decide which remote repos to use
-#
-#  It always computes the remote repos from a single base, $repo_base
-#  How is $repo_base set?  
-#    If you say "-r repo", then that's $repo_base
-#    otherwise $repo_base is set by asking git where the ghc repo came
-#    from, and removing the last component (e.g. /ghc.git/ of /ghc/).
-#
-#  Then sync-all iterates over the package found in the file
-#  ./packages; see that file for a description of the contents.
-# 
-#    If $repo_base looks like a local filesystem path, or if you give
-#    the --checked-out flag, sync-all works on repos of form
-#          $repo_base/<local-path>
-#    otherwise sync-all works on repos of form
-#          $repo_base/<remote-path>
-#    This logic lets you say
-#      both    sync-all -r http://darcs.haskell.org/ghc-6.12 pull
-#      and     sync-all -r ../HEAD pull
-#    The latter is called a "checked-out tree".
-
-# NB: sync-all *ignores* the defaultrepo of all repos other than the
-# root one.  So the remote repos must be laid out in one of the two
-# formats given by <local-path> and <remote-path> in the file 'packages'.
-
 $| = 1; # autoflush stdout after each print, to avoid output after die
 
 my $defaultrepo;
@@ -126,7 +59,7 @@ sub getrepo {
         #   http://darcs.haskell.org
         #
         # rather than
-        #   
+        #
         #   http://darcs.haskell.org/ghc
         #
         if (!$defaultrepo) {
@@ -220,7 +153,7 @@ sub scm {
 
 sub scmall {
     my $command = shift;
-    
+
     my $localpath;
     my $tag;
     my $remotepath;
@@ -251,16 +184,16 @@ sub scmall {
         while (@_ > 0 && $_[0] =~ /^-/) {
             push(@args,shift);
         }
-        if (@_ < 1) { help(); }
+        if (@_ < 1) { help(1); }
         $subcommand = shift;
         if ($subcommand ne 'add' && $subcommand ne 'rm' && $subcommand ne 'set-url') {
-            help();
+            help(1);
         }
         while (@_ > 0 && $_[0] =~ /^-/) {
             push(@args,shift);
         }
         if (($subcommand eq 'add' || $subcommand eq 'rm') && @_ < 1) {
-            help();
+            help(1);
         } elsif (@_ < 1) { # set-url
             $branch_name = 'origin';
         } else {
@@ -338,7 +271,7 @@ sub scmall {
             if ($tags{$tag} == 0) {
                 next;
             }
-            
+
             if (-d $localpath) {
                 warning("$localpath already present; omitting")
                     if $localpath ne ".";
@@ -456,6 +389,10 @@ sub scmall {
             scm ($localpath, $scm, "grep", @args)
                 unless $scm eq "darcs";
         }
+        elsif ($command =~ /^diff$/) {
+            scm ($localpath, $scm, "diff", @args)
+                unless $scm eq "darcs";
+        }
         elsif ($command =~ /^clean$/) {
             scm ($localpath, $scm, "clean", @args)
                 unless $scm eq "darcs";
@@ -464,10 +401,26 @@ sub scmall {
             scm ($localpath, $scm, "reset", @args)
                 unless $scm eq "darcs";
         }
+        elsif ($command =~ /^branch$/) {
+            scm ($localpath, $scm, "branch", @args)
+                unless $scm eq "darcs";
+        }
         elsif ($command =~ /^config$/) {
             scm ($localpath, $scm, "config", @args)
                 unless $scm eq "darcs";
         }
+        elsif ($command =~ /^repack$/) {
+            scm ($localpath, $scm, "repack", @args)
+                if $scm eq "git"
+        }
+        elsif ($command =~ /^format-patch$/) {
+            scm ($localpath, $scm, "format-patch", @args)
+                if $scm eq "git"
+        }
+        elsif ($command =~ /^gc$/) {
+            scm ($localpath, $scm, "gc", @args)
+                unless $scm eq "darcs";
+        }
         else {
             die "Unknown command: $command";
         }
@@ -476,41 +429,165 @@ sub scmall {
     unlink "resume";
 }
 
-sub help()
+sub help
 {
+        my $exit = shift;
+
         # Get the built in help
         my $help = <<END;
 Usage:
 
-  ./sync-all [-q] [-s] [--ignore-failure] [-r repo] [--checked-out] [--bare]
-             [--package-tag1] ... [--package-tagN] command
-
-Supported commands:
-
- * whatsnew
- * commit
- * push
- * pull
- * get, with options:
-  * --<package-tag>
-  * --complete
-  * --partial
- * fetch
- * send
- * new
- * remote add <remote-name>
- * remote rm <remote-name>
- * remote set-url [--push] <remote-name>
- * checkout
- * grep
- * clean
- * reset
- * config
- * log
-
-Note: --cheched-out and --bare flags are NOT the opposite of each other.
-      --checked-out: describes the layout of the remote repository tree.
-      --bare:        describes the layout of the local repository tree.
+./sync-all [-q] [-s] [--ignore-failure] [-r repo] [--checked-out] [--bare]
+           [--nofib] [--extra] [--testsuite] [--no-dph] [--resume]
+           cmd [git flags]
+
+Applies the command "cmd" to each repository in the tree.
+
+A full repository tree is obtained by first cloning the ghc
+repository, then getting the subrepositories with "sync-all get":
+
+  \$ git clone http://darcs.haskell.org/ghc.git
+  \$ cd ghc
+  \$ ./sync-all get
+
+After this, "./sync-all pull" will pull from the original repository
+tree.
+
+A remote pointing to another local repository tree can be added like
+this:
+
+  \$ ./sync-all -r /path/to/ghc remote add otherlocal
+
+and then we can pull from this other tree with
+
+  \$ ./sync-all pull otherlocal
+
+-------------- Commands -----------------
+get
+
+    Clones all sub-repositories from the same place that the ghc
+    repository was cloned from. See "which repos to use" below
+    for details of how the subrepositories are laid out.
+
+    There are various --<package-tag> options that can be given
+    before "get" that enable extra repositories. The full list is
+    given at the end of this help. For example:
+
+    ./sync-all --testsuite get
+
+    would get the testsuite repository in addition to the usual set of
+    subrepositories.
+
+remote add <remote-name>
+remote rm <remote-name>
+remote set-url [--push] <remote-name>
+
+    Runs a "git remote" command on each subrepository, adjusting the
+    repository location in each case appropriately. For example, to
+    add a new remote pointing to the upstream repositories:
+
+    ./sync-all -r http://darcs.haskell.org/ remote add upstream
+
+    The -r flag points to the root of the repository tree (see "which
+    repos to use" below). For a repository on the local filesystem it
+    would point to the ghc reposiroty, and for a remote repository it
+    points to the directory containing "ghc.git".
+
+These commands just run the equivalent git command on each repository, passing
+any extra arguments to git:
+
+  branch
+  checkout
+  clean
+  commit
+  config
+  diff
+  fetch
+  format-patch
+  gc
+  grep
+  log
+  new
+  pull
+  push
+  repack
+  reset
+  send
+  status
+
+-------------- Flags -------------------
+These flags are given *before* the command and modify the way sync-all behaves.
+Flags given *after* the command are passed to git.
+
+  -q says to be quiet, and -s to be silent.
+
+  --resume will restart a command that failed, from the repo at which it
+  failed. This means you don't need to wait while, e.g., "pull" goes through
+  all the repos it's just pulled, and tries to pull them again.
+
+  --ignore-failure says to ignore errors and move on to the next repository
+
+  -r repo says to use repo as the location of package repositories
+
+  --checked-out says that the remote repo is in checked-out layout, as opposed
+  to the layout used for the main repo. By default a repo on the local
+  filesystem is assumed to be checked-out, and repos accessed via HTTP or SSH
+  are assumed to be in the main repo layout; use --checked-out to override the
+  latter.
+
+  --bare says that the local repo is in bare layout, same as the main repo. It
+  also means that these repos are bare. You only have to use this flag if you
+  don't have a bare ghc.git in the current directory and would like to 'get'
+  all of the repos bare. Requires packages.conf to be present in the current
+  directory (a renamed packages file from the main ghc repo).
+
+  Note: --checked-out and --bare flags are NOT the opposite of each other.
+        --checked-out: describes the layout of the remote repository tree.
+        --bare:        describes the layout of the local repository tree.
+
+  --nofib also clones the nofib benchmark suite
+
+  --testsuite also clones the ghc testsuite 
+
+  --extra also clone some extra library packages
+
+  --no-dph avoids cloning the dph pacakges
+
+
+------------ Checking out a branch -------------
+To check out a branch you can run the following command:
+
+  \$ ./sync-all checkout ghc-7.4
+
+
+------------ Which repos to use -------------
+sync-all uses the following algorithm to decide which remote repos to use
+
+It always computes the remote repos from a single base, <repo_base> How is
+<repo_base> set? If you say "-r repo", then that's <repo_base> otherwise
+<repo_base> is set by asking git where the ghc repo came from, and removing the
+last component (e.g. /ghc.git/ or /ghc/).
+
+Then sync-all iterates over the package found in the file ./packages; see that
+file for a description of the contents.
+
+If <repo_base> looks like a local filesystem path, or if you give the
+--checked-out flag, sync-all works on repos of form:
+
+  <repo_base>/<local-path>
+
+otherwise sync-all works on repos of form:
+
+  <repo_base>/<remote-path>
+
+This logic lets you say
+  both    sync-all -r http://darcs.haskell.org/ghc-6.12 remote add ghc-6.12
+  and     sync-all -r ../working remote add working
+The latter is called a "checked-out tree".
+
+sync-all *ignores* the defaultrepo of all repos other than the root one. So the
+remote repos must be laid out in one of the two formats given by <local-path>
+and <remote-path> in the file 'packages'.
 
 Available package-tags are:
 END
@@ -532,11 +609,11 @@ END
             }
         }
         close IN;
-        
+
         # Show those tags and the help text
         my @available_tags = keys %available_tags;
-        print "$help@available_tags\n";
-        exit 1;
+        print "$help@available_tags\n\n";
+        exit $exit;
 }
 
 sub main {
@@ -576,6 +653,9 @@ sub main {
         elsif ($arg eq "--bare") {
             $bare_flag = $arg;
         }
+        elsif ($arg eq "--help") {
+            help(0);
+        }
         # --<tag> says we grab the libs tagged 'tag' with
         # 'get'. It has no effect on the other commands.
         elsif ($arg =~ m/^--no-(.*)$/) {
@@ -610,7 +690,7 @@ sub main {
     }
 
     if ($#_ eq -1) {
-        help();
+        help(1);
     }
     else {
         # Give the command and rest of the arguments to the main loop
@@ -633,7 +713,7 @@ ATTENTION!
 You have an old haddock repository in your GHC tree!
 
 Please remove it (e.g. "rm -r utils/haddock"), and then run
-"./syncs-all get" to get the new repository.
+"./sync-all get" to get the new repository.
 ============================
 EOF
         }
@@ -651,7 +731,7 @@ ATTENTION!
 You have an old binary repository in your GHC tree!
 
 Please remove it (e.g. "rm -r libraries/binary"), and then run
-"./syncs-all get" to get the new repository.
+"./sync-all get" to get the new repository.
 ============================
 EOF
         }