realityforge-piston 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +81 -0
- data/LICENSE +19 -0
- data/README.rdoc +134 -0
- data/Rakefile +25 -0
- data/bin/piston +10 -0
- data/contrib/piston +43 -0
- data/lib/core_ext/range.rb +5 -0
- data/lib/core_ext/string.rb +9 -0
- data/lib/piston.rb +70 -0
- data/lib/piston/command.rb +68 -0
- data/lib/piston/command_error.rb +6 -0
- data/lib/piston/commands/convert.rb +80 -0
- data/lib/piston/commands/diff.rb +55 -0
- data/lib/piston/commands/import.rb +75 -0
- data/lib/piston/commands/lock.rb +30 -0
- data/lib/piston/commands/status.rb +82 -0
- data/lib/piston/commands/switch.rb +139 -0
- data/lib/piston/commands/unlock.rb +29 -0
- data/lib/piston/commands/update.rb +131 -0
- data/lib/piston/version.rb +9 -0
- data/lib/transat/parser.rb +189 -0
- data/piston.gemspec +22 -0
- metadata +95 -0
data/CHANGELOG
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
1.4.1 (Pending)
|
2
|
+
|
3
|
+
1.4.0 (2008-02-07)
|
4
|
+
* New piston diff subcommand, implemented by Graeme Mathieson.
|
5
|
+
http://rubyforge.org/tracker/index.php?func=detail&aid=17116&group_id=2105&atid=8179
|
6
|
+
* Per http://rubyforge.org/tracker/?func=detail&atid=8179&aid=10717&group_id=2105
|
7
|
+
Don't set LC_ALL, but set LANGUAGE so that repositories with foreign
|
8
|
+
characters can be used. Thanks go to Per Wigren.
|
9
|
+
|
10
|
+
1.3.3 (2007-03-22)
|
11
|
+
* Repaired problems with import subcommand. Wrote specifications to prevent
|
12
|
+
the same failure mode again.
|
13
|
+
|
14
|
+
1.3.2 (2007-03-09)
|
15
|
+
* piston switch had a bad constant access which caused failures.
|
16
|
+
|
17
|
+
1.3.1 (2007-03-09)
|
18
|
+
* piston switch would fail if the branch from which we are reading had been
|
19
|
+
deleted.
|
20
|
+
* piston switch had a major bug. It did not update the piston:root property
|
21
|
+
to remember the new repository root. Reported and fixed by Graeme
|
22
|
+
Mathieson.
|
23
|
+
* piston switch errors out early if not provided with the right arguments.
|
24
|
+
Thanks to Graeme Mathieson for the info and patch.
|
25
|
+
* New internal command parser. No visible external changes.
|
26
|
+
|
27
|
+
1.3.0 (2007-01-22)
|
28
|
+
* Piston status shows the revision number of locked repositories. Thanks to
|
29
|
+
Chris Wanstrath <http://errtheblog.com/>.
|
30
|
+
* New piston switch subcommand to switch repository locations. Thanks to
|
31
|
+
Greg Spurrier for the prompt which resulted in finally implementing this.
|
32
|
+
|
33
|
+
1.2.1 (2006-11-20)
|
34
|
+
* Import subcommand would fail with a "svn: Explicit target required
|
35
|
+
('vendor/rails' interpreted as prop value)" error. This was a minor
|
36
|
+
error in the import code. Reported by Daniel N.
|
37
|
+
* The import subcommand could import another revision than what was intended,
|
38
|
+
if HEAD was updated while the import is in progress.
|
39
|
+
|
40
|
+
1.2.0 (2006-11-17)
|
41
|
+
* New status subcommand. Shows M if locally or remotely modified. Applies to
|
42
|
+
one, many, all folders. This subcommand *requires* the use of a Subversion
|
43
|
+
1.2.0 client. Thanks to Chris Wanstrath for the inspiration. His Rake
|
44
|
+
tasks are available at http://errtheblog.com/post/38.
|
45
|
+
* Minor patch by Miguel Ibero Carreras to make Subversion always use the
|
46
|
+
C locale, instead of the current one. This allows Piston to be used
|
47
|
+
with internationalized versions of Subversion. David Bittencourt later
|
48
|
+
reported the same problem. Thanks!
|
49
|
+
* Better handle how update finds it's latest local revision to prevent
|
50
|
+
conflicts. If you had never locally changed your vendor repositories,
|
51
|
+
this fix will change nothing for you. This helps prevent local conflicts
|
52
|
+
if you had ever applied a local patch.
|
53
|
+
*CAVEAT*: See the release announcement at
|
54
|
+
http://blog.teksol.info/articles/2006/11/17/piston-1-2-0-status-better-update
|
55
|
+
for a required local operation.
|
56
|
+
|
57
|
+
1.1.1 (2006-08-30)
|
58
|
+
* Add contrib/piston [Michael Schuerig]
|
59
|
+
* Non-recursively add the root directory of the managed folder then set Piston
|
60
|
+
properties before adding the contents of the managed folder. This is to
|
61
|
+
help ease work along if an inconsistent EOL is encountered during the
|
62
|
+
import. The user can finish the import by svn add'ing the rest of the
|
63
|
+
folder until all files are added. Piston properties will already have been
|
64
|
+
set.
|
65
|
+
|
66
|
+
1.1.0 (2006-08-26)
|
67
|
+
* New 'convert' subcommand converts existing svn:externals to Piston managed
|
68
|
+
folders. Thanks to Dan Kubb for the idea.
|
69
|
+
* update now recursively finds the folders to process. It bases it's search
|
70
|
+
on the presence or absence of the piston:root property.
|
71
|
+
* Changed lock and unlock messages to be more detailed.
|
72
|
+
|
73
|
+
1.0.1 (2006-08-24)
|
74
|
+
* Corrected minor bug where the core extensions were in core_ext/core_ext
|
75
|
+
instead of being in core_ext.
|
76
|
+
* Require the parent working copy path be at HEAD before importing / updating.
|
77
|
+
* Don't do unnecessary merges if the file had not changed prior to the update.
|
78
|
+
* During the update, if adding a folder, do an svn mkdir instead of a cp_r.
|
79
|
+
|
80
|
+
1.0.0 (2006-08-24)
|
81
|
+
* Initial version
|
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2006 Francois Beausoleil <francois@teksol.info>
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
Piston is a utility that eases vendor branch management.
|
2
|
+
This is similar to <tt>svn:externals</tt>, except you have a local copy of
|
3
|
+
the files, which you can modify at will. As long as the changes are
|
4
|
+
mergeable, you should have no problems.
|
5
|
+
|
6
|
+
This tool has a similar purpose than svnmerge.py which you can find in the
|
7
|
+
contrib/client-side folder of the main Subversion repository at
|
8
|
+
http://svn.collab.net/repos/svn/trunk/contrib/client-side/svnmerge.py.
|
9
|
+
The main difference is that Piston is designed to work with remote
|
10
|
+
repositories. Another tool you might want to look at, SVK, which you can find
|
11
|
+
at http://svk.elixus.org/.
|
12
|
+
|
13
|
+
From Wikipedia's Piston page (http://en.wikipedia.org/wiki/Piston):
|
14
|
+
In general, a piston is a sliding plug that fits closely inside the bore
|
15
|
+
of a cylinder.
|
16
|
+
|
17
|
+
Its purpose is either to change the volume enclosed by the cylinder, or
|
18
|
+
to exert a force on a fluid inside the cylinder.
|
19
|
+
|
20
|
+
For this utility, I retain the second meaning, "to exert a force on a fluid
|
21
|
+
inside the cylinder." Piston forces the content of a remote repository
|
22
|
+
location back into our own.
|
23
|
+
|
24
|
+
|
25
|
+
= Installation
|
26
|
+
|
27
|
+
Nothing could be simpler:
|
28
|
+
|
29
|
+
$ gem install --include-dependencies piston
|
30
|
+
|
31
|
+
|
32
|
+
= Usage
|
33
|
+
|
34
|
+
First, you need to import the remote repository location:
|
35
|
+
|
36
|
+
$ piston import http://dev.rubyonrails.org/svn/rails/trunk vendor/rails
|
37
|
+
Exported r4720 from 'http://dev.rubyonrails.org/svn/rails/trunk' to 'vendor/rails'
|
38
|
+
|
39
|
+
$ svn commit -m "Importing local copy of Rails"
|
40
|
+
|
41
|
+
When you want to get the latest changes from the remote repository location:
|
42
|
+
|
43
|
+
$ piston update vendor/rails
|
44
|
+
Updated 'vendor/rails' to r4720.
|
45
|
+
|
46
|
+
$ svn commit -m "Updates vendor/rails to the latest revision"
|
47
|
+
|
48
|
+
You can prevent a local Piston-managed folder from updating by using the
|
49
|
+
+lock+ subcommand:
|
50
|
+
|
51
|
+
$ piston lock vendor/rails
|
52
|
+
'vendor/rails' locked at r4720.
|
53
|
+
|
54
|
+
When you want to update again, you unlock:
|
55
|
+
|
56
|
+
$ piston unlock vendor/rails
|
57
|
+
'vendor/rails' unlocked.
|
58
|
+
|
59
|
+
If the branch you are following moves, you should use the switch subcommand:
|
60
|
+
|
61
|
+
$ piston import http://dev.rubyonrails.org/svn/rails/branches/1-2-pre-release vendor/rails
|
62
|
+
$ svn commit vendor/rails
|
63
|
+
|
64
|
+
# Vendor branch is renamed, let's follow it
|
65
|
+
$ piston switch http://dev.rubyonrails.org/svn/rails/branches/1-2-stable vendor/rails
|
66
|
+
|
67
|
+
|
68
|
+
= Contributions
|
69
|
+
|
70
|
+
== Bash Shell Completion Script
|
71
|
+
|
72
|
+
Michael Schuerig contributed a Bash shell completion script. You should copy
|
73
|
+
+contrib/piston+ from your gem repository to the appropriate folder. Michael
|
74
|
+
said:
|
75
|
+
|
76
|
+
I've put together a bash completion function for piston. On Debian, I
|
77
|
+
just put it in /etc/bash_completion.d, alternatively, the contents can
|
78
|
+
be copied to ~/.bash_completion. I don't know how things are organized
|
79
|
+
on other Unix/Linux systems.
|
80
|
+
|
81
|
+
|
82
|
+
= Caveats
|
83
|
+
|
84
|
+
== Speed
|
85
|
+
|
86
|
+
This tool is SLOW. The update process particularly so. I use a brute force
|
87
|
+
approach. Subversion cannot merge from remote repositories, so instead I
|
88
|
+
checkout the folder at the initial revision, and then run svn update and
|
89
|
+
parse the results of that to determine what changes have occured.
|
90
|
+
|
91
|
+
If a local copy of a file was changed, it's changes will be merged back in.
|
92
|
+
If that introduces a conflict, Piston will not detect it. The commit will be
|
93
|
+
rejected by Subversion anyway.
|
94
|
+
|
95
|
+
== Copies / Renames
|
96
|
+
|
97
|
+
Piston *does not* track copies. Since Subversion does renames in two
|
98
|
+
phases (copy + delete), that is what Piston does.
|
99
|
+
|
100
|
+
== Local Operations Only
|
101
|
+
|
102
|
+
Piston only works if you have a working copy. It also never commits your
|
103
|
+
working copy directly. You are responsible for reviewing the changes and
|
104
|
+
applying any pending fixes.
|
105
|
+
|
106
|
+
== Remote Repository UUID
|
107
|
+
|
108
|
+
Piston caches the remote repository UUID, allowing it to know if the remote
|
109
|
+
repos is still the same. Piston refuses to work against a different
|
110
|
+
repository than the one we checked out from originally.
|
111
|
+
|
112
|
+
|
113
|
+
= Subversion Properties Used
|
114
|
+
|
115
|
+
* <tt>piston:uuid</tt>: The remote repository's UUID, which we always confirm
|
116
|
+
before doing any operations.
|
117
|
+
* <tt>piston:root</tt>: The repository root URL from which this Piston folder
|
118
|
+
was exported from.
|
119
|
+
* <tt>piston:remote-revision</tt>: The <tt>Last Changed Rev</tt> of the remote
|
120
|
+
repository.
|
121
|
+
* <tt>piston:local-revision</tt>: The <tt>Last Changed Rev</tt> of the Piston
|
122
|
+
managed folder, to enable us to know if we need to do any merging.
|
123
|
+
* <tt>piston:locked</tt>: The revision at which this folder is locked. If
|
124
|
+
this property is set and non-blank, Piston will skip the folder with
|
125
|
+
an appropriate message.
|
126
|
+
|
127
|
+
|
128
|
+
= Dependencies
|
129
|
+
|
130
|
+
Piston depends on the following libraries:
|
131
|
+
|
132
|
+
* yaml
|
133
|
+
* uri
|
134
|
+
* fileutils
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
require 'spec/rake/spectask'
|
5
|
+
require File.join(File.dirname(__FILE__), 'lib', 'piston', 'version')
|
6
|
+
|
7
|
+
gem_spec = Gem::Specification.load(File.expand_path('piston.gemspec', File.dirname(__FILE__)))
|
8
|
+
|
9
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
10
|
+
spec.libs << 'lib' << 'spec'
|
11
|
+
spec.spec_files = FileList['specs/**/*_spec.rb']
|
12
|
+
end
|
13
|
+
|
14
|
+
task :default => :spec
|
15
|
+
|
16
|
+
desc "Generate RDoc documentation in rdoc/"
|
17
|
+
Rake::RDocTask.new :rdoc do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = gem_spec.name
|
20
|
+
rdoc.options = gem_spec.rdoc_options.clone
|
21
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
22
|
+
rdoc.rdoc_files.include gem_spec.extra_rdoc_files
|
23
|
+
end
|
24
|
+
|
25
|
+
Rake::GemPackageTask.new(gem_spec).define
|
data/bin/piston
ADDED
data/contrib/piston
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
have piston &&
|
2
|
+
_piston()
|
3
|
+
{
|
4
|
+
local cur prev commands options command
|
5
|
+
|
6
|
+
COMPREPLY=()
|
7
|
+
cur=${COMP_WORDS[COMP_CWORD]}
|
8
|
+
|
9
|
+
commands='update convert help unlock lock import switch'
|
10
|
+
|
11
|
+
if [[ $COMP_CWORD -eq 1 ]] ; then
|
12
|
+
if [[ "$cur" == -* ]]; then
|
13
|
+
COMPREPLY=( $( compgen -W '--version' -- $cur ) )
|
14
|
+
else
|
15
|
+
COMPREPLY=( $( compgen -W "$commands" -- $cur ) )
|
16
|
+
fi
|
17
|
+
else
|
18
|
+
|
19
|
+
prev=${COMP_WORDS[COMP_CWORD-1]}
|
20
|
+
command=${COMP_WORDS[1]}
|
21
|
+
|
22
|
+
if [[ "$cur" == -* ]]; then
|
23
|
+
case $command in
|
24
|
+
@(update|import))
|
25
|
+
options='-r --revision --lock --verbose'
|
26
|
+
;;
|
27
|
+
esac
|
28
|
+
options="$options --verbose"
|
29
|
+
|
30
|
+
COMPREPLY=( $( compgen -W "$options" -- $cur ) )
|
31
|
+
else
|
32
|
+
if [[ "$command" == @(help|h|\?) ]]; then
|
33
|
+
COMPREPLY=( $( compgen -W "$commands" -- $cur ) )
|
34
|
+
else
|
35
|
+
_filedir
|
36
|
+
fi
|
37
|
+
fi
|
38
|
+
fi
|
39
|
+
|
40
|
+
return 0
|
41
|
+
}
|
42
|
+
|
43
|
+
[ -n "${have:-}" ] && complete -F _piston $default piston
|
data/lib/piston.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
# Copyright (c) 2006 Francois Beausoleil <francois@teksol.info>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
# $HeadURL: svn+ssh://rubyforge.org/var/svn/piston/tags/1.4.0/lib/piston.rb $
|
22
|
+
# $Id: piston.rb 139 2008-02-07 15:28:24Z fbos $
|
23
|
+
|
24
|
+
require 'yaml'
|
25
|
+
require 'uri'
|
26
|
+
require 'fileutils'
|
27
|
+
|
28
|
+
PISTON_ROOT = File.dirname(__FILE__)
|
29
|
+
Dir[File.join(PISTON_ROOT, 'core_ext', '*.rb')].each do |file|
|
30
|
+
require file
|
31
|
+
end
|
32
|
+
|
33
|
+
require "piston/version"
|
34
|
+
require "piston/command"
|
35
|
+
require "piston/command_error"
|
36
|
+
|
37
|
+
require "transat/parser"
|
38
|
+
Dir[File.join(PISTON_ROOT, "piston", "commands", "*.rb")].each do |file|
|
39
|
+
require file.gsub(PISTON_ROOT, "")[1..-4]
|
40
|
+
end
|
41
|
+
|
42
|
+
module Piston
|
43
|
+
ROOT = "piston:root"
|
44
|
+
UUID = "piston:uuid"
|
45
|
+
REMOTE_REV = "piston:remote-revision"
|
46
|
+
LOCAL_REV = "piston:local-revision"
|
47
|
+
LOCKED = "piston:locked"
|
48
|
+
end
|
49
|
+
|
50
|
+
PistonCommandLineProcessor = Transat::Parser.new do
|
51
|
+
program_name "Piston"
|
52
|
+
version [Piston::VERSION::STRING]
|
53
|
+
|
54
|
+
option :verbose, :short => :v, :default => true, :message => "Show subversion commands and results as they are executed"
|
55
|
+
option :quiet, :short => :q, :default => false, :message => "Do not output any messages except errors"
|
56
|
+
option :revision, :short => :r, :param_name => "REVISION", :type => :int
|
57
|
+
option :show_updates, :short => :u, :message => "Query the remote repository for out of dateness information"
|
58
|
+
option :lock, :short => :l, :message => "Close down and lock the imported directory from further changes"
|
59
|
+
option :dry_run, :message => "Does not actually execute any commands"
|
60
|
+
option :force, :message => "Force the command to run, even if Piston thinks it would cause a problem"
|
61
|
+
|
62
|
+
command :switch, Piston::Commands::Switch, :valid_options => %w(lock dry_run force revision quiet verbose)
|
63
|
+
command :update, Piston::Commands::Update, :valid_options => %w(lock dry_run force revision quiet verbose)
|
64
|
+
command :diff, Piston::Commands::Diff, :valid_options => %w(lock dry_run force revision quiet verbose)
|
65
|
+
command :import, Piston::Commands::Import, :valid_options => %w(lock dry_run force revision quiet verbose)
|
66
|
+
command :convert, Piston::Commands::Convert, :valid_options => %w(lock verbose dry_run)
|
67
|
+
command :unlock, Piston::Commands::Unlock, :valid_options => %w(force dry_run verbose)
|
68
|
+
command :lock, Piston::Commands::Lock, :valid_options => %w(force dry_run revision verbose)
|
69
|
+
command :status, Piston::Commands::Status, :valid_options => %w(show_updates verbose)
|
70
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "piston"
|
2
|
+
|
3
|
+
module Piston
|
4
|
+
# The base class which all commands subclass to obtain services from.
|
5
|
+
class Command
|
6
|
+
attr_accessor :revision, :dry_run, :quiet, :verbose, :force, :lock,
|
7
|
+
:recursive, :show_updates
|
8
|
+
attr_reader :args
|
9
|
+
attr_writer :logging_stream
|
10
|
+
|
11
|
+
def initialize(non_options, options)
|
12
|
+
@args = non_options
|
13
|
+
|
14
|
+
# Because the Windows shell does not process wildcards, we must do it
|
15
|
+
# here ourselves
|
16
|
+
@args.collect! do |arg|
|
17
|
+
next arg unless arg =~ /[*?]/
|
18
|
+
Dir[arg]
|
19
|
+
end
|
20
|
+
|
21
|
+
options.each do |option, value|
|
22
|
+
self.send("#{option}=", value)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Run a Subversion command using the shell. If the Subversion command
|
27
|
+
# returns an existstatus different from zero, a RuntimeError is raised.
|
28
|
+
def svn(*args)
|
29
|
+
args = args.flatten.compact.map do |arg|
|
30
|
+
if arg.to_s =~ /[ *?@]/ then
|
31
|
+
%Q("#{arg}")
|
32
|
+
else
|
33
|
+
arg
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
command = "svn #{args.join(' ')}"
|
38
|
+
logging_stream.puts command if verbose
|
39
|
+
return if dry_run
|
40
|
+
ENV['LANGUAGE'] = 'en_US'
|
41
|
+
result = `#{command}`
|
42
|
+
logging_stream.puts result if verbose
|
43
|
+
raise "Command #{command} resulted in an error:\n\n#{result}" unless $?.exitstatus.zero?
|
44
|
+
result
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns an IO-like object to which all information should be logged.
|
48
|
+
def logging_stream
|
49
|
+
@logging_stream ||= $stdout
|
50
|
+
end
|
51
|
+
|
52
|
+
def skip(dir, msg, header=true)
|
53
|
+
logging_stream.print "Skipping '#{dir}': " if header
|
54
|
+
logging_stream.puts msg
|
55
|
+
end
|
56
|
+
|
57
|
+
def find_targets
|
58
|
+
targets = Array.new
|
59
|
+
svn(:propget, '--recursive', Piston::ROOT).each_line do |line|
|
60
|
+
next unless line =~ /^([^ ]+)\s-\s.*$/
|
61
|
+
targets << $1
|
62
|
+
end
|
63
|
+
|
64
|
+
targets
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|