francois-piston 2.0.0

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 (73) hide show
  1. data/History.txt +19 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +109 -0
  4. data/README.txt +136 -0
  5. data/VERSION.yml +4 -0
  6. data/bin/piston +5 -0
  7. data/lib/piston.rb +18 -0
  8. data/lib/piston/cli.rb +391 -0
  9. data/lib/piston/commands.rb +4 -0
  10. data/lib/piston/commands/base.rb +44 -0
  11. data/lib/piston/commands/convert.rb +26 -0
  12. data/lib/piston/commands/diff.rb +12 -0
  13. data/lib/piston/commands/import.rb +43 -0
  14. data/lib/piston/commands/info.rb +14 -0
  15. data/lib/piston/commands/lock_unlock.rb +21 -0
  16. data/lib/piston/commands/status.rb +40 -0
  17. data/lib/piston/commands/update.rb +34 -0
  18. data/lib/piston/commands/upgrade.rb +20 -0
  19. data/lib/piston/git.rb +13 -0
  20. data/lib/piston/git/client.rb +76 -0
  21. data/lib/piston/git/commit.rb +114 -0
  22. data/lib/piston/git/repository.rb +63 -0
  23. data/lib/piston/git/working_copy.rb +142 -0
  24. data/lib/piston/repository.rb +61 -0
  25. data/lib/piston/revision.rb +83 -0
  26. data/lib/piston/svn.rb +15 -0
  27. data/lib/piston/svn/client.rb +88 -0
  28. data/lib/piston/svn/repository.rb +67 -0
  29. data/lib/piston/svn/revision.rb +112 -0
  30. data/lib/piston/svn/working_copy.rb +182 -0
  31. data/lib/piston/version.rb +9 -0
  32. data/lib/piston/working_copy.rb +334 -0
  33. data/lib/subclass_responsibility_error.rb +2 -0
  34. data/test/integration_helpers.rb +35 -0
  35. data/test/spec_suite.rb +4 -0
  36. data/test/test_helper.rb +83 -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 +178 -0
data/History.txt ADDED
@@ -0,0 +1,19 @@
1
+ == 1.9.5 2008-11-12
2
+
3
+ * Merged everything that was relevant from the community.
4
+ * Thanks to scambra for fixing many problems with piston update.
5
+
6
+ == 1.9.4
7
+
8
+ * Thanks to scambra for fixing lock/unlock errors.
9
+ * Thanks to Geoffrey Grosenbach (topfunky), piston has a gemspec for use on GitHub.
10
+ * Thanks to Brian Takita (btakita), piston update with a Git repository works!
11
+ * Thanks to mattknox and scambra for manifest updates.
12
+ * Thanks to Marcos Tapajós (tapajos) for many small improvements.
13
+
14
+ == 1.9.3 2008-06-03
15
+
16
+ * Import git branches using --revision origin/BRANCH_NAME, or a tag
17
+ using --revision TAG_NAME, or even a specific commit using
18
+ --revision COMMIT_ID. In fact, use a committish and you'll be fine,
19
+ 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
data/README.txt ADDED
@@ -0,0 +1,136 @@
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
+ = Notes on 2.0
26
+
27
+ In the 1.0 era, Piston was exclusively geared towards Subversion repositories.
28
+ In early 2008, Git gained a lot of popularity among Ruby and Rails coders.
29
+ Piston was rewritten during that period to allow many repositories and working
30
+ copies to be used together.
31
+
32
+ The documentation still refers to Subversion throughout, but 2.0 allows any
33
+ repository to be used with any working copy.
34
+
35
+
36
+ = Installation
37
+
38
+ Nothing could be simpler:
39
+
40
+ $ gem install piston
41
+
42
+
43
+ = Usage
44
+
45
+ First, you need to import the remote repository location:
46
+
47
+ $ piston import http://dev.rubyonrails.org/svn/rails/trunk vendor/rails
48
+ Exported r4720 from 'http://dev.rubyonrails.org/svn/rails/trunk' to 'vendor/rails'
49
+
50
+ $ svn commit -m "Importing local copy of Rails"
51
+
52
+ When you want to get the latest changes from the remote repository location:
53
+
54
+ $ piston update vendor/rails
55
+ Updated 'vendor/rails' to r4720.
56
+
57
+ $ svn commit -m "Updates vendor/rails to the latest revision"
58
+
59
+ You can prevent a local Piston-managed folder from updating by using the
60
+ +lock+ subcommand:
61
+
62
+ $ piston lock vendor/rails
63
+ 'vendor/rails' locked at r4720.
64
+
65
+ When you want to update again, you unlock:
66
+
67
+ $ piston unlock vendor/rails
68
+ 'vendor/rails' unlocked.
69
+
70
+ If the branch you are following moves, you should use the switch subcommand:
71
+
72
+ $ piston import http://dev.rubyonrails.org/svn/rails/branches/1-2-pre-release vendor/rails
73
+ $ svn commit vendor/rails
74
+
75
+ # Vendor branch is renamed, let's follow it
76
+ $ piston switch http://dev.rubyonrails.org/svn/rails/branches/1-2-stable vendor/rails
77
+
78
+
79
+ = Contributions
80
+
81
+ == Bash Shell Completion Script
82
+
83
+ Michael Schuerig contributed a Bash shell completion script. You should copy
84
+ +contrib/piston+ from your gem repository to the appropriate folder. Michael
85
+ said:
86
+
87
+ I've put together a bash completion function for piston. On Debian, I
88
+ just put it in /etc/bash_completion.d, alternatively, the contents can
89
+ be copied to ~/.bash_completion. I don't know how things are organized
90
+ on other Unix/Linux systems.
91
+
92
+
93
+ = Caveats
94
+
95
+ == Speed
96
+
97
+ This tool is SLOW. The update process particularly so. I use a brute force
98
+ approach. Subversion cannot merge from remote repositories, so instead I
99
+ checkout the folder at the initial revision, and then run svn update and
100
+ parse the results of that to determine what changes have occured.
101
+
102
+ If a local copy of a file was changed, it's changes will be merged back in.
103
+ If that introduces a conflict, Piston will not detect it. The commit will be
104
+ rejected by Subversion anyway.
105
+
106
+ == Copies / Renames
107
+
108
+ Piston *does not* track copies. Since Subversion does renames in two
109
+ phases (copy + delete), that is what Piston does.
110
+
111
+ == Local Operations Only
112
+
113
+ Piston only works if you have a working copy. It also never commits your
114
+ working copy directly. You are responsible for reviewing the changes and
115
+ applying any pending fixes.
116
+
117
+ == Remote Repository UUID
118
+
119
+ Piston caches the remote repository UUID, allowing it to know if the remote
120
+ repos is still the same. Piston refuses to work against a different
121
+ repository than the one we checked out from originally.
122
+
123
+
124
+ = Subversion Properties Used
125
+
126
+ * <tt>piston:uuid</tt>: The remote repository's UUID, which we always confirm
127
+ before doing any operations.
128
+ * <tt>piston:root</tt>: The repository root URL from which this Piston folder
129
+ was exported from.
130
+ * <tt>piston:remote-revision</tt>: The <tt>Last Changed Rev</tt> of the remote
131
+ repository.
132
+ * <tt>piston:local-revision</tt>: The <tt>Last Changed Rev</tt> of the Piston
133
+ managed folder, to enable us to know if we need to do any merging.
134
+ * <tt>piston:locked</tt>: The revision at which this folder is locked. If
135
+ this property is set and non-blank, Piston will skip the folder with
136
+ an appropriate message.
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 0
3
+ :patch: 0
4
+ :major: 2
data/bin/piston ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require "piston"
3
+
4
+ # Chain to the real command-line client
5
+ require "piston/cli"
data/lib/piston.rb ADDED
@@ -0,0 +1,18 @@
1
+ require "subclass_responsibility_error"
2
+
3
+ require "piston/repository"
4
+ require "piston/revision"
5
+ require "piston/working_copy"
6
+
7
+ require "piston/git"
8
+ require "piston/svn"
9
+
10
+ require "pathname"
11
+
12
+ module Piston
13
+ class << self
14
+ def version_message
15
+ "Piston %s\nCopyright 2006-2008, François Beausoleil <francois@teksol.info>\nhttp://piston.rubyforge.org/\nDistributed under an MIT-like license." % Piston::VERSION::STRING
16
+ end
17
+ end
18
+ end
data/lib/piston/cli.rb ADDED
@@ -0,0 +1,391 @@
1
+ require "main"
2
+ require "log4r"
3
+ require "activesupport"
4
+ require "piston/version"
5
+ require "piston/commands"
6
+
7
+ Main {
8
+ program "piston"
9
+ author "François Beausoleil <francois@teksol.info>"
10
+ version Piston::VERSION::STRING
11
+
12
+ mixin :standard_options do
13
+ option("verbose", "v") {
14
+ argument_optional
15
+ cast :integer
16
+ default 0
17
+ validate {|value| (0..5).include?(value)}
18
+ description "Verbosity level (0 to 5, 0 being the default)"
19
+ }
20
+ option("quiet", "q") { default false }
21
+ option("force") { default false }
22
+ option("dry-run") { default false }
23
+ end
24
+
25
+ mixin :revision_or_commit do
26
+ option "revision", "r" do
27
+ argument_required
28
+ description "The revision you wish to operate on"
29
+ end
30
+
31
+ option "commit" do
32
+ argument_required
33
+ description "The commit you wish to operate on"
34
+ end
35
+
36
+ def target_revision
37
+ case
38
+ when params["revision"].given?
39
+ params["revision"].value
40
+ when params["commit"].given?
41
+ params["commit"].value
42
+ else
43
+ :head
44
+ end
45
+ end
46
+ end
47
+
48
+ mixin :lock_options do
49
+ option("lock") do
50
+ default false
51
+ description "Automatically lock down the revision/commit to protect against blanket updates"
52
+ end
53
+ end
54
+
55
+ mode "import" do
56
+ mixin :standard_options
57
+ mixin :revision_or_commit
58
+ mixin :lock_options
59
+
60
+ argument "repository" do
61
+ required
62
+ description "The repository you wish to Pistonize"
63
+ end
64
+
65
+ argument "directory" do
66
+ optional
67
+ default nil
68
+ description "Where to put the Pistonized repository"
69
+ end
70
+
71
+ option("repository-type") do
72
+ argument :required
73
+ default nil
74
+ description "Force a specific repository type, for when it's not possible to guess"
75
+ end
76
+
77
+ logger_level Logger::DEBUG
78
+ def run
79
+ configure_logging!
80
+
81
+ if params["revision"].given? && params["commit"].given? then
82
+ raise ArgumentError, "Only one of --revision or --commit can be given. Received both."
83
+ end
84
+
85
+ cmd = Piston::Commands::Import.new(:verbose => params["verbose"].value,
86
+ :quiet => params["quiet"].value,
87
+ :force => params["force"].value,
88
+ :dry_run => params["dry-run"].value,
89
+ :repository_type => params["repository-type"].value)
90
+
91
+ begin
92
+ cmd.run(params[:repository].value, self.target_revision, params[:directory].value)
93
+ rescue Piston::Repository::UnhandledUrl => e
94
+ supported_types = Piston::Repository.handlers.collect do |handler|
95
+ handler.repository_type
96
+ end
97
+ puts "Unsure how to handle:"
98
+ puts "\t#{params[:repository].value.inspect}."
99
+ puts "You should try using --repository-type. Supported types are:"
100
+ supported_types.each do |type|
101
+ puts "\t#{type}"
102
+ end
103
+ exit_failure!
104
+ end
105
+
106
+ # Lock the working copy, if the user asked for it
107
+ cmd = Piston::Commands::LockUnlock.new(:verbose => params["verbose"].value,
108
+ :quiet => params["quiet"].value,
109
+ :force => params["force"].value,
110
+ :dry_run => params["dry-run"].value)
111
+ cmd.run(params["directory"].value, params["lock"].value) if params["lock"].value
112
+ end
113
+ end
114
+
115
+ mode "convert" do
116
+ mixin :standard_options
117
+
118
+ argument "directories" do
119
+ argument_required
120
+ optional
121
+ arity -1
122
+ description "Which directory/directories to convert from svn:externals to Piston. Not specifying this argument recursively converts the whole directory tree starting from the current dir."
123
+ end
124
+
125
+ logger_level Logger::DEBUG
126
+ def run
127
+ configure_logging!
128
+
129
+ cmd = Piston::Commands::Convert.new(:verbose => params["verbose"].value,
130
+ :quiet => params["quiet"].value,
131
+ :force => params["force"].value)
132
+ dirs = cmd.run(params["directories"].values.map {|dir| Pathname.new(dir)})
133
+ puts "#{dirs.length} directories converted"
134
+ end
135
+ end
136
+
137
+ mode "upgrade" do
138
+ mixin :standard_options
139
+
140
+ argument "directories" do
141
+ optional
142
+ default '.'
143
+ arity -1
144
+ description "Which directory/directories to convert from Piston 1.x to Piston 2.x. Not specifying this argument recursively converts the whole directory tree starting from the current dir."
145
+ end
146
+
147
+ logger_level Logger::DEBUG
148
+ def run
149
+ configure_logging!
150
+
151
+ cmd = Piston::Commands::Upgrade.new(:verbose => params["verbose"].value,
152
+ :quiet => params["quiet"].value,
153
+ :force => params["force"].value)
154
+ dirs = cmd.run(params["directories"].values.map { |dir| Pathname.new(dir).expand_path })
155
+ puts "#{dirs.length} directories upgraded"
156
+ end
157
+ end
158
+
159
+ mode "lock" do
160
+ mixin :standard_options
161
+
162
+ argument "directory" do
163
+ argument_required
164
+ optional
165
+ description "Which directory to lock"
166
+ end
167
+
168
+ logger_level Logger::DEBUG
169
+ def run
170
+ configure_logging!
171
+
172
+ cmd = Piston::Commands::LockUnlock.new(:wcdir => params["directory"].value,
173
+ :verbose => params["verbose"].value,
174
+ :quiet => params["quiet"].value,
175
+ :force => params["force"].value)
176
+ begin
177
+ cmd.run(true)
178
+ puts "#{params["directory"].value} locked"
179
+ rescue Piston::WorkingCopy::NotWorkingCopy
180
+ puts "The #{params["directory"].value} is not Pistonized"
181
+ end
182
+ end
183
+ end
184
+
185
+ mode "unlock" do
186
+ mixin :standard_options
187
+
188
+ argument "directory" do
189
+ argument_required
190
+ optional
191
+ description "Which directory to lock"
192
+ end
193
+
194
+ logger_level Logger::DEBUG
195
+ def run
196
+ configure_logging!
197
+
198
+ cmd = Piston::Commands::LockUnlock.new(:wcdir => params["directory"].value,
199
+ :verbose => params["verbose"].value,
200
+ :quiet => params["quiet"].value,
201
+ :force => params["force"].value)
202
+ begin
203
+ cmd.run(false)
204
+ puts "#{params["directory"].value} unlocked"
205
+ rescue Piston::WorkingCopy::NotWorkingCopy
206
+ puts "The #{params["directory"].value} is not Pistonized"
207
+ end
208
+ end
209
+ end
210
+
211
+ mode "status" do
212
+ mixin :standard_options
213
+
214
+ option "show-updates", "s" do
215
+ default false
216
+ description "Query the remote repository for out of dateness information"
217
+ end
218
+
219
+ argument "directories" do
220
+ optional
221
+ default '.'
222
+ arity -1
223
+ description "Which directory/directories to get status. Not specifying this argument recursively gets status from the whole directory tree starting from the current dir."
224
+ end
225
+
226
+ logger_level Logger::DEBUG
227
+ def run
228
+ configure_logging!
229
+
230
+ cmd = Piston::Commands::Status.new(:show_updates => params["show-updates"].value,
231
+ :verbose => params["verbose"].value,
232
+ :quiet => params["quiet"].value,
233
+ :force => params["force"].value)
234
+ params["directories"].values.each do |path|
235
+ begin
236
+ cmd.run(Pathname.new(path).expand_path)
237
+ rescue Piston::WorkingCopy::NotWorkingCopy
238
+ puts "#{path} is not a working copy"
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ mode "diff" do
245
+ mixin :standard_options
246
+
247
+ argument "directory" do
248
+ argument_required
249
+ description "Which directory to get differences between local and remote repositories."
250
+ end
251
+
252
+ logger_level Logger::DEBUG
253
+ def run
254
+ configure_logging!
255
+
256
+ cmd = Piston::Commands::Diff.new(:wcdir => File.expand_path(params["directory"].value),
257
+ :verbose => params["verbose"].value,
258
+ :quiet => params["quiet"].value,
259
+ :force => params["force"].value)
260
+ begin
261
+ cmd.run
262
+ rescue Piston::WorkingCopy::NotWorkingCopy
263
+ puts "#{params["directory"].value} is not Pistonized"
264
+ end
265
+ end
266
+ end
267
+
268
+ mode "info" do
269
+ mixin :standard_options
270
+
271
+ argument "directory" do
272
+ argument_required
273
+ optional
274
+ description "Which directory to get info"
275
+ end
276
+
277
+ logger_level Logger::DEBUG
278
+ def run
279
+ configure_logging!
280
+
281
+ cmd = Piston::Commands::Info.new(:wcdir => params["directory"].value,
282
+ :verbose => params["verbose"].value,
283
+ :quiet => params["quiet"].value,
284
+ :force => params["force"].value)
285
+ begin
286
+ puts cmd.run(params["directory"].value)
287
+ rescue Piston::WorkingCopy::NotWorkingCopy
288
+ puts "#{params["directory"].value} is not Pistonized"
289
+ end
290
+ end
291
+ end
292
+
293
+ mode "update" do
294
+ mixin :standard_options
295
+ mixin :revision_or_commit
296
+ mixin :lock_options
297
+
298
+ argument("directory") do
299
+ optional
300
+ default '.'
301
+ end
302
+
303
+ logger_level Logger::DEBUG
304
+ def run
305
+ configure_logging!
306
+
307
+ if params["revision"].given? && params["commit"].given? then
308
+ raise ArgumentError, "Only one of --revision or --commit can be given. Received both."
309
+ end
310
+
311
+ cmd = Piston::Commands::Update.new(:lock => params["lock"].value,
312
+ :verbose => params["verbose"].value,
313
+ :quiet => params["quiet"].value,
314
+ :force => params["force"].value,
315
+ :dry_run => params["dry-run"].value)
316
+
317
+ begin
318
+ cmd.run(File.expand_path(params["directory"].value), target_revision)
319
+ rescue
320
+ $stderr.puts $!.message
321
+ $stderr.puts $!.backtrace.join("\n")
322
+ exit_failure!
323
+ end
324
+ end
325
+ end
326
+
327
+ option("version", "v")
328
+
329
+ def run
330
+ if params["version"].given? || ARGV.first == "version" then
331
+ puts Piston.version_message
332
+ exit_success!
333
+ elsif ARGV.empty?
334
+ puts Piston.version_message
335
+ puts "\nNo mode given. Call with help to find out the available options."
336
+ exit_failure!
337
+ else
338
+ puts "Unrecognized mode: #{ARGV.first.inspect}. Use the help mode to find the available options."
339
+ exit_warn!
340
+ end
341
+ end
342
+
343
+ def configure_logging!
344
+ Log4r::Logger.root.level = Log4r::DEBUG
345
+
346
+ case params["verbose"].value
347
+ when 0
348
+ main_level = Log4r::INFO
349
+ handler_level = Log4r::WARN
350
+ client_level = Log4r::WARN
351
+ client_out_level = Log4r::WARN
352
+ stdout_level = Log4r::INFO
353
+ when 1
354
+ main_level = Log4r::DEBUG
355
+ handler_level = Log4r::INFO
356
+ client_level = Log4r::WARN
357
+ client_out_level = Log4r::WARN
358
+ stdout_level = Log4r::DEBUG
359
+ when 2
360
+ main_level = Log4r::DEBUG
361
+ handler_level = Log4r::DEBUG
362
+ client_level = Log4r::INFO
363
+ client_out_level = Log4r::WARN
364
+ stdout_level = Log4r::DEBUG
365
+ when 3
366
+ main_level = Log4r::DEBUG
367
+ handler_level = Log4r::DEBUG
368
+ client_level = Log4r::DEBUG
369
+ client_out_level = Log4r::INFO
370
+ stdout_level = Log4r::DEBUG
371
+ when 4, 5
372
+ main_level = Log4r::DEBUG
373
+ handler_level = Log4r::DEBUG
374
+ client_level = Log4r::DEBUG
375
+ client_out_level = Log4r::DEBUG
376
+ stdout_level = Log4r::DEBUG
377
+ else
378
+ raise ArgumentError, "Did not expect verbosity to be outside 0..5: #{params["verbose"].value}"
379
+ end
380
+
381
+ Log4r::Logger.new("main", main_level)
382
+ Log4r::Logger.new("handler", handler_level)
383
+ Log4r::Logger.new("handler::client", client_level)
384
+ Log4r::Logger.new("handler::client::out", client_out_level)
385
+
386
+ Log4r::StdoutOutputter.new("stdout", :level => stdout_level)
387
+
388
+ Log4r::Logger["main"].add "stdout"
389
+ Log4r::Logger["handler"].add "stdout"
390
+ end
391
+ }