piston 1.4.0 → 2.0.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.
Files changed (85) hide show
  1. data/History.txt +24 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +109 -0
  4. data/{README → README.txt} +14 -10
  5. data/VERSION.yml +4 -0
  6. data/bin/piston +3 -8
  7. data/lib/piston/cli.rb +121 -0
  8. data/lib/piston/commands/base.rb +44 -0
  9. data/lib/piston/commands/convert.rb +23 -71
  10. data/lib/piston/commands/diff.rb +14 -46
  11. data/lib/piston/commands/import.rb +48 -57
  12. data/lib/piston/commands/info.rb +24 -0
  13. data/lib/piston/commands/lock_unlock.rb +26 -0
  14. data/lib/piston/commands/status.rb +29 -54
  15. data/lib/piston/commands/update.rb +35 -122
  16. data/lib/piston/commands/upgrade.rb +26 -0
  17. data/lib/piston/commands.rb +4 -0
  18. data/lib/piston/git/client.rb +76 -0
  19. data/lib/piston/git/commit.rb +114 -0
  20. data/lib/piston/git/repository.rb +63 -0
  21. data/lib/piston/git/working_copy.rb +145 -0
  22. data/lib/piston/git.rb +13 -0
  23. data/lib/piston/repository.rb +61 -0
  24. data/lib/piston/revision.rb +83 -0
  25. data/lib/piston/svn/client.rb +88 -0
  26. data/lib/piston/svn/repository.rb +67 -0
  27. data/lib/piston/svn/revision.rb +112 -0
  28. data/lib/piston/svn/working_copy.rb +184 -0
  29. data/lib/piston/svn.rb +15 -0
  30. data/lib/piston/version.rb +9 -7
  31. data/lib/piston/working_copy.rb +334 -0
  32. data/lib/piston.rb +13 -64
  33. data/lib/subclass_responsibility_error.rb +2 -0
  34. data/test/integration_helpers.rb +36 -0
  35. data/test/spec_suite.rb +4 -0
  36. data/test/test_helper.rb +92 -0
  37. data/test/unit/git/commit/test_checkout.rb +31 -0
  38. data/test/unit/git/commit/test_each.rb +30 -0
  39. data/test/unit/git/commit/test_rememberance.rb +22 -0
  40. data/test/unit/git/commit/test_validation.rb +34 -0
  41. data/test/unit/git/repository/test_at.rb +23 -0
  42. data/test/unit/git/repository/test_basename.rb +12 -0
  43. data/test/unit/git/repository/test_branchanme.rb +15 -0
  44. data/test/unit/git/repository/test_guessing.rb +32 -0
  45. data/test/unit/git/working_copy/test_copying.rb +25 -0
  46. data/test/unit/git/working_copy/test_creation.rb +22 -0
  47. data/test/unit/git/working_copy/test_existence.rb +18 -0
  48. data/test/unit/git/working_copy/test_finalization.rb +15 -0
  49. data/test/unit/git/working_copy/test_guessing.rb +35 -0
  50. data/test/unit/git/working_copy/test_rememberance.rb +22 -0
  51. data/test/unit/svn/repository/test_at.rb +19 -0
  52. data/test/unit/svn/repository/test_basename.rb +24 -0
  53. data/test/unit/svn/repository/test_guessing.rb +45 -0
  54. data/test/unit/svn/revision/test_checkout.rb +28 -0
  55. data/test/unit/svn/revision/test_each.rb +22 -0
  56. data/test/unit/svn/revision/test_rememberance.rb +38 -0
  57. data/test/unit/svn/revision/test_validation.rb +50 -0
  58. data/test/unit/svn/working_copy/test_copying.rb +26 -0
  59. data/test/unit/svn/working_copy/test_creation.rb +16 -0
  60. data/test/unit/svn/working_copy/test_existence.rb +23 -0
  61. data/test/unit/svn/working_copy/test_externals.rb +56 -0
  62. data/test/unit/svn/working_copy/test_finalization.rb +17 -0
  63. data/test/unit/svn/working_copy/test_guessing.rb +18 -0
  64. data/test/unit/svn/working_copy/test_rememberance.rb +26 -0
  65. data/test/unit/test_info.rb +37 -0
  66. data/test/unit/test_lock_unlock.rb +47 -0
  67. data/test/unit/test_repository.rb +51 -0
  68. data/test/unit/test_revision.rb +31 -0
  69. data/test/unit/working_copy/test_guessing.rb +35 -0
  70. data/test/unit/working_copy/test_info.rb +14 -0
  71. data/test/unit/working_copy/test_rememberance.rb +42 -0
  72. data/test/unit/working_copy/test_validate.rb +63 -0
  73. metadata +132 -31
  74. data/CHANGELOG +0 -81
  75. data/LICENSE +0 -19
  76. data/Rakefile +0 -63
  77. data/contrib/piston +0 -43
  78. data/lib/core_ext/range.rb +0 -5
  79. data/lib/core_ext/string.rb +0 -9
  80. data/lib/piston/command.rb +0 -68
  81. data/lib/piston/command_error.rb +0 -6
  82. data/lib/piston/commands/lock.rb +0 -30
  83. data/lib/piston/commands/switch.rb +0 -139
  84. data/lib/piston/commands/unlock.rb +0 -29
  85. data/lib/transat/parser.rb +0 -189
data/History.txt ADDED
@@ -0,0 +1,24 @@
1
+ == 2.0.1 2009-04-01
2
+
3
+ * Finished testing on Ruby 1.9.1.
4
+ * Released new website.
5
+
6
+ == 1.9.5 2008-11-12
7
+
8
+ * Merged everything that was relevant from the community.
9
+ * Thanks to scambra for fixing many problems with piston update.
10
+
11
+ == 1.9.4
12
+
13
+ * Thanks to scambra for fixing lock/unlock errors.
14
+ * Thanks to Geoffrey Grosenbach (topfunky), piston has a gemspec for use on GitHub.
15
+ * Thanks to Brian Takita (btakita), piston update with a Git repository works!
16
+ * Thanks to mattknox and scambra for manifest updates.
17
+ * Thanks to Marcos Tapajós (tapajos) for many small improvements.
18
+
19
+ == 1.9.3 2008-06-03
20
+
21
+ * Import git branches using --revision origin/BRANCH_NAME, or a tag
22
+ using --revision TAG_NAME, or even a specific commit using
23
+ --revision COMMIT_ID. In fact, use a committish and you'll be fine,
24
+ even HEAD^3.
data/License.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2006-2008 François Beausoleil <francois@teksol.info>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt ADDED
@@ -0,0 +1,109 @@
1
+ .gitignore
2
+ bin/piston
3
+ config/hoe.rb
4
+ config/requirements.rb
5
+ features/import_to_git.feature
6
+ features/import_to_svn.feature
7
+ features/step_definitions/repository.rb
8
+ features/support/env.rb
9
+ features/support/svn.rb
10
+ features/update_to_git.feature
11
+ features/update_to_svn.feature
12
+ History.txt
13
+ lib/piston/cli.rb
14
+ lib/piston/commands/base.rb
15
+ lib/piston/commands/convert.rb
16
+ lib/piston/commands/import.rb
17
+ lib/piston/commands/info.rb
18
+ lib/piston/commands/lock_unlock.rb
19
+ lib/piston/commands/status.rb
20
+ lib/piston/commands/update.rb
21
+ lib/piston/commands/upgrade.rb
22
+ lib/piston/commands.rb
23
+ lib/piston/git/client.rb
24
+ lib/piston/git/commit.rb
25
+ lib/piston/git/repository.rb
26
+ lib/piston/git/working_copy.rb
27
+ lib/piston/git.rb
28
+ lib/piston/repository.rb
29
+ lib/piston/revision.rb
30
+ lib/piston/svn/client.rb
31
+ lib/piston/svn/repository.rb
32
+ lib/piston/svn/revision.rb
33
+ lib/piston/svn/working_copy.rb
34
+ lib/piston/svn.rb
35
+ lib/piston/version.rb
36
+ lib/piston/working_copy.rb
37
+ lib/piston.rb
38
+ lib/subclass_responsibility_error.rb
39
+ License.txt
40
+ log/.gitignore
41
+ Manifest.txt
42
+ piston.gemspec
43
+ Rakefile
44
+ README.txt
45
+ samples/common.rb
46
+ samples/import_git_git.rb
47
+ samples/import_git_svn.rb
48
+ samples/import_svn_git.rb
49
+ samples/import_svn_svn.rb
50
+ script/destroy
51
+ script/generate
52
+ script/txt2html
53
+ setup.rb
54
+ tasks/deployment.rake
55
+ tasks/environment.rake
56
+ tasks/manifest.rake
57
+ tasks/samples.rake
58
+ tasks/test.rake
59
+ tasks/website.rake
60
+ test/integration/test_git_git.rb
61
+ test/integration/test_git_svn.rb
62
+ test/integration/test_import_svn_git.rb
63
+ test/integration/test_svn_svn.rb
64
+ test/integration_helpers.rb
65
+ test/spec_suite.rb
66
+ test/test_helper.rb
67
+ test/unit/git/commit/test_checkout.rb
68
+ test/unit/git/commit/test_each.rb
69
+ test/unit/git/commit/test_rememberance.rb
70
+ test/unit/git/commit/test_validation.rb
71
+ test/unit/git/repository/test_at.rb
72
+ test/unit/git/repository/test_basename.rb
73
+ test/unit/git/repository/test_branchanme.rb
74
+ test/unit/git/repository/test_guessing.rb
75
+ test/unit/git/working_copy/test_copying.rb
76
+ test/unit/git/working_copy/test_creation.rb
77
+ test/unit/git/working_copy/test_existence.rb
78
+ test/unit/git/working_copy/test_finalization.rb
79
+ test/unit/git/working_copy/test_guessing.rb
80
+ test/unit/git/working_copy/test_rememberance.rb
81
+ test/unit/svn/repository/test_at.rb
82
+ test/unit/svn/repository/test_basename.rb
83
+ test/unit/svn/repository/test_guessing.rb
84
+ test/unit/svn/revision/test_checkout.rb
85
+ test/unit/svn/revision/test_each.rb
86
+ test/unit/svn/revision/test_rememberance.rb
87
+ test/unit/svn/revision/test_validation.rb
88
+ test/unit/svn/working_copy/test_copying.rb
89
+ test/unit/svn/working_copy/test_creation.rb
90
+ test/unit/svn/working_copy/test_existence.rb
91
+ test/unit/svn/working_copy/test_externals.rb
92
+ test/unit/svn/working_copy/test_finalization.rb
93
+ test/unit/svn/working_copy/test_guessing.rb
94
+ test/unit/svn/working_copy/test_rememberance.rb
95
+ test/unit/test_info.rb
96
+ test/unit/test_lock_unlock.rb
97
+ test/unit/test_repository.rb
98
+ test/unit/test_revision.rb
99
+ test/unit/working_copy/test_guessing.rb
100
+ test/unit/working_copy/test_info.rb
101
+ test/unit/working_copy/test_rememberance.rb
102
+ test/unit/working_copy/test_validate.rb
103
+ tmp/.gitignore
104
+ TODO
105
+ website/index.html
106
+ website/index.txt
107
+ website/javascripts/rounded_corners_lite.inc.js
108
+ website/stylesheets/screen.css
109
+ website/template.rhtml
@@ -3,6 +3,8 @@ This is similar to <tt>svn:externals</tt>, except you have a local copy of
3
3
  the files, which you can modify at will. As long as the changes are
4
4
  mergeable, you should have no problems.
5
5
 
6
+ Piston is Ruby 1.9.1 compatible.
7
+
6
8
  This tool has a similar purpose than svnmerge.py which you can find in the
7
9
  contrib/client-side folder of the main Subversion repository at
8
10
  http://svn.collab.net/repos/svn/trunk/contrib/client-side/svnmerge.py.
@@ -22,11 +24,22 @@ inside the cylinder." Piston forces the content of a remote repository
22
24
  location back into our own.
23
25
 
24
26
 
27
+ = Notes on 2.0
28
+
29
+ In the 1.0 era, Piston was exclusively geared towards Subversion repositories.
30
+ In early 2008, Git gained a lot of popularity among Ruby and Rails coders.
31
+ Piston was rewritten during that period to allow many repositories and working
32
+ copies to be used together.
33
+
34
+ The documentation still refers to Subversion throughout, but 2.0 allows any
35
+ repository to be used with any working copy.
36
+
37
+
25
38
  = Installation
26
39
 
27
40
  Nothing could be simpler:
28
41
 
29
- $ gem install --include-dependencies piston
42
+ $ gem install piston
30
43
 
31
44
 
32
45
  = Usage
@@ -123,12 +136,3 @@ repository than the one we checked out from originally.
123
136
  * <tt>piston:locked</tt>: The revision at which this folder is locked. If
124
137
  this property is set and non-blank, Piston will skip the folder with
125
138
  an appropriate message.
126
-
127
-
128
- = Dependencies
129
-
130
- Piston depends on the following libraries:
131
-
132
- * yaml
133
- * uri
134
- * fileutils
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 2
3
+ :minor: 0
4
+ :patch: 1
data/bin/piston CHANGED
@@ -1,10 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ require "piston"
2
3
 
3
- begin
4
- require 'rubygems'
5
- rescue LoadError
6
- # no rubygems to load, so we fail silently
7
- end
8
-
9
- require 'piston'
10
- PistonCommandLineProcessor.parse_and_execute
4
+ # Chain to the real command-line client
5
+ require "piston/cli"
data/lib/piston/cli.rb ADDED
@@ -0,0 +1,121 @@
1
+ require "log4r"
2
+ require "activesupport"
3
+ require "piston/version"
4
+ require "optparse"
5
+
6
+ module Piston
7
+ class Cli
8
+ def self.start(args=ARGV)
9
+ options = {:lock => false, :force => false, :dry_run => false, :quiet => false, :verbose => 0}
10
+ opts = OptionParser.new do |opts|
11
+ opts.banner = "Usage: piston COMMAND [options]"
12
+ opts.version = Piston::VERSION::STRING
13
+
14
+ # Many!!!
15
+ opts.on("-r", "--revision REVISION", "Revision to operate on") do |r|
16
+ options[:revision] = r.to_i
17
+ end
18
+
19
+ opts.on("--commit TREEISH", "Commit to operate on") do |c|
20
+ options[:commit] = c
21
+ end
22
+
23
+ # Import
24
+ opts.on("--repository-type TYPE", [:git, :svn], "Force selection of a repository handler (git or svn)") do |type|
25
+ options[:repository_type] = type
26
+ end
27
+
28
+ # Import, Update and Switch
29
+ opts.on("--lock", "Lock down the revision against mass-updates") do
30
+ options[:lock] = true
31
+ end
32
+
33
+ opts.on("--show-updates", "Query the remote repository for out-of-dateness information") do
34
+ options[:show_updates] = true
35
+ end
36
+
37
+ # All
38
+ opts.on("--force", "Force the operation to go ahead") do
39
+ options[:force] = true
40
+ end
41
+
42
+ opts.on("--dry-run", "Run but do not change anything") do
43
+ options[:dry_run] = true
44
+ end
45
+
46
+ opts.on("-q", "--quiet", "Operate silently") do
47
+ options[:quiet] = true
48
+ end
49
+
50
+ opts.on("-v", "--verbose [LEVEL]", ("0".."5").to_a, "Increase verbosity (default 0)") do |level|
51
+ options[:verbose] = level.to_i || 1
52
+ end
53
+ end
54
+ opts.parse!(args)
55
+
56
+ if args.empty?
57
+ puts opts.help
58
+ exit 0
59
+ end
60
+
61
+ if options.has_key?(:revision) && options.has_key?(:commit) then
62
+ raise ArgumentError, "Only one of --revision or --commit can be given. Received both."
63
+ end
64
+
65
+ configure_logging(options)
66
+ command = Piston::Commands.const_get(args.shift.classify).new(options)
67
+ command.start(*args)
68
+ end
69
+
70
+ def self.configure_logging(options)
71
+ Log4r::Logger.root.level = Log4r::DEBUG
72
+
73
+ case options[:verbose]
74
+ when 0
75
+ main_level = Log4r::INFO
76
+ handler_level = Log4r::WARN
77
+ client_level = Log4r::WARN
78
+ client_out_level = Log4r::WARN
79
+ stdout_level = Log4r::INFO
80
+ when 1
81
+ main_level = Log4r::DEBUG
82
+ handler_level = Log4r::INFO
83
+ client_level = Log4r::WARN
84
+ client_out_level = Log4r::WARN
85
+ stdout_level = Log4r::DEBUG
86
+ when 2
87
+ main_level = Log4r::DEBUG
88
+ handler_level = Log4r::DEBUG
89
+ client_level = Log4r::INFO
90
+ client_out_level = Log4r::WARN
91
+ stdout_level = Log4r::DEBUG
92
+ when 3
93
+ main_level = Log4r::DEBUG
94
+ handler_level = Log4r::DEBUG
95
+ client_level = Log4r::DEBUG
96
+ client_out_level = Log4r::INFO
97
+ stdout_level = Log4r::DEBUG
98
+ when 4, 5
99
+ main_level = Log4r::DEBUG
100
+ handler_level = Log4r::DEBUG
101
+ client_level = Log4r::DEBUG
102
+ client_out_level = Log4r::DEBUG
103
+ stdout_level = Log4r::DEBUG
104
+ else
105
+ raise ArgumentError, "Did not expect verbosity to be outside 0..5: #{options[:verbose]}"
106
+ end
107
+
108
+ Log4r::Logger.new("main", main_level)
109
+ Log4r::Logger.new("handler", handler_level)
110
+ Log4r::Logger.new("handler::client", client_level)
111
+ Log4r::Logger.new("handler::client::out", client_out_level)
112
+
113
+ Log4r::StdoutOutputter.new("stdout", :level => stdout_level)
114
+
115
+ Log4r::Logger["main"].add "stdout"
116
+ Log4r::Logger["handler"].add "stdout"
117
+ end
118
+ end
119
+ end
120
+
121
+ Piston::Cli.start
@@ -0,0 +1,44 @@
1
+ module Piston
2
+ module Commands
3
+ class Base
4
+ class << self
5
+ def logger
6
+ @@logger ||= Log4r::Logger["main"]
7
+ end
8
+ end
9
+
10
+ attr_reader :options
11
+
12
+ def initialize(options={})
13
+ @options = options
14
+ logger.debug {"#{self.class.name} with options #{options.inspect}"}
15
+ end
16
+
17
+ def verbose
18
+ @options[:verbose]
19
+ end
20
+
21
+ def force
22
+ @options[:force]
23
+ end
24
+
25
+ def quiet
26
+ @options[:quiet]
27
+ end
28
+
29
+ def logger
30
+ self.class.logger
31
+ end
32
+
33
+ def guess_wc(wcdir)
34
+ Piston::WorkingCopy.guess(wcdir)
35
+ end
36
+
37
+ def working_copy!(wcdir)
38
+ wc = guess_wc(wcdir)
39
+ wc.validate!
40
+ wc
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,80 +1,32 @@
1
- require "piston"
2
- require "piston/command"
3
- require "piston/commands/import"
1
+ require "piston/commands/base"
4
2
 
5
3
  module Piston
6
4
  module Commands
7
- class Convert < Piston::Command
8
- def run
9
- if args.empty? then
10
- svn(:propget, '--recursive', 'svn:externals').each_line do |line|
11
- next unless line =~ /^([^ ]+)\s-\s/
12
- args << $1
5
+ class Convert < Piston::Commands::Base
6
+ attr_reader :options
7
+
8
+ def run(targets)
9
+ targets = Array.new unless targets
10
+ wc = Piston::Svn::WorkingCopy.new(Dir.pwd)
11
+ importer = Piston::Commands::Import.new(options)
12
+ returning(Array.new) do |conversions|
13
+ wc.externals.each_pair do |dir, args|
14
+ next unless targets.empty? || targets.detect {|target| dir.to_s.include?(target.to_s) }
15
+ conversions << dir
16
+
17
+ logger.info "Importing #{dir.relative_path_from(wc.path)} from #{args[:url]}"
18
+ importer.run(args[:url], args[:revision], dir)
13
19
  end
14
- end
15
-
16
- return logging_stream.puts("No svn:externals defined in this folder or any of it's subfolders") if args.empty?
17
-
18
- args.each do |dir|
19
- externals = svn(:propget, 'svn:externals', dir)
20
- next skip_no_externals(dir) if externals.chomp.empty?
21
-
22
- operations = Array.new
23
- externals.each_line do |external|
24
- external.chomp!
25
- next if external.empty?
26
- next skip_no_match(external) unless external =~ /^([^ ]+)\s+(?:-r\s*(\d+)\s+)?(.*)$/
27
-
28
- local, revision, repos = $1, $2, $3
29
- lock = true if revision
30
- local_dir = File.join(dir, local)
31
- if File.exists?(local_dir)
32
- raise Piston::CommandError, "#{local_dir.inspect} is not a directory" unless File.directory?(local_dir)
33
- status = svn(:status, local_dir)
34
- raise Piston::CommandError, "#{local_dir.inspect} has local modifications:\n#{status}\nYour must revert or commit before trying again." unless status.empty?
35
- info = YAML::load(svn(:info, local_dir))
36
- revision = info['Last Changed Rev'] unless revision
37
- FileUtils.rm_rf(local_dir)
38
- end
39
20
 
40
- operations << [local_dir, revision, repos, lock]
41
- end
42
-
43
- operations.each do |local_dir, revision, repos, lock|
44
- logging_stream.puts "Importing '#{repos}' to #{local_dir} (-r #{revision || 'HEAD'}#{' locked' if lock})"
45
- import = Piston::Commands::Import.new([repos, local_dir], {})
46
- import.revision = revision
47
- import.verbose, import.quiet, import.logging_stream = self.verbose, self.quiet, self.logging_stream
48
- import.lock = lock
49
- import.run
50
- logging_stream.puts
51
- end
21
+ wc.remove_external_references(*targets)
52
22
  end
53
-
54
- svn :propdel, 'svn:externals', *args
55
- logging_stream.puts "Done converting existing svn:externals to Piston"
56
23
  end
57
24
 
58
- def skip_no_externals(dir)
59
- logging_stream.puts "Skipping '#{dir}' - no svn:externals definition"
60
- end
61
-
62
- def skip_no_match(external)
63
- logging_stream.puts "#{external.inspect} did not match Regexp"
64
- end
65
-
66
- def self.help
67
- "Converts existing svn:externals into Piston managed folders"
68
- end
69
-
70
- def self.detailed_help
71
- <<EOF
72
- usage: convert [DIR [...]]
73
-
74
- Converts folders which have the svn:externals property set to Piston managed
75
- folders.
76
- EOF
77
- end
78
- end
79
- end
25
+ def start(*args)
26
+ targets = args.flatten.map {|d| Pathname.new(d).expand_path}
27
+ run(targets)
28
+ puts "#{targets.length} directories converted"
29
+ end
30
+ end
31
+ end
80
32
  end
@@ -1,55 +1,23 @@
1
- require "piston"
2
- require "piston/command"
3
- require 'find'
1
+ require "piston/commands/base"
4
2
 
5
3
  module Piston
6
4
  module Commands
7
- class Diff < Piston::Command
5
+ class Diff < Piston::Commands::Base
8
6
  def run
9
- (args.empty? ? find_targets : args).each do |dir|
10
- diff dir
11
- end
7
+ working_copy = working_copy!(options[:wcdir])
8
+ working_copy.diff
12
9
  end
13
10
 
14
- def diff(dir)
15
- return unless File.directory?(dir)
16
- logging_stream.puts "Processing '#{dir}'..."
17
- repos = svn(:propget, Piston::ROOT, dir).chomp
18
- uuid = svn(:propget, Piston::UUID, dir).chomp
19
- remote_revision = svn(:propget, Piston::REMOTE_REV, dir).chomp.to_i
20
-
21
- logging_stream.puts " Fetching remote repository's latest revision and UUID"
22
- info = YAML::load(svn(:info, repos))
23
- return skip(dir, "Repository UUID changed\n Expected #{uuid}\n Found #{info['Repository UUID']}\n Repository: #{repos}") unless uuid == info['Repository UUID']
24
-
25
- logging_stream.puts " Checking out repository at revision #{remote_revision}"
26
- svn :checkout, '--ignore-externals', '--quiet', '--revision', remote_revision, repos, dir.tmp
27
-
28
- puts run_diff(dir.tmp, dir)
29
-
30
- logging_stream.puts " Removing temporary files / folders"
31
- FileUtils.rm_rf dir.tmp
32
-
33
- end
34
-
35
- def run_diff(dir1, dir2)
36
- `diff -urN --exclude=.svn #{dir1} #{dir2}`
37
- end
38
-
39
- def self.help
40
- "Shows the differences between the local repository and the pristine upstream"
41
- end
42
-
43
- def self.detailed_help
44
- <<EOF
45
- usage: diff [DIR [...]]
46
-
47
- This operation has the effect of producing a diff between the pristine upstream
48
- (at the last updated revision) and your local version. In other words, it
49
- gives you the changes you have made in your repository that have not been
50
- incorporated upstream.
51
- EOF
52
- end
11
+ def start(*args)
12
+ args.flatten.map {|d| Pathname.new(d).expand_path}.each do |wcdir|
13
+ begin
14
+ options[:wcdir] = wcdir
15
+ run
16
+ rescue Piston::WorkingCopy::NotWorkingCopy
17
+ puts "#{wcdir} is not a working copy"
18
+ end
19
+ end
20
+ end
53
21
  end
54
22
  end
55
23
  end