realityforge-piston 1.4.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|