piston 1.0.1 → 1.1.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.
data/CHANGELOG CHANGED
@@ -1,5 +1,12 @@
1
1
  *SVN*
2
2
 
3
+ 2006-08-26 1.1.0
4
+ * New 'convert' subcommand converts existing svn:externals to Piston managed
5
+ folders. Thanks to Dan Kubb for the idea.
6
+ * update now recursively finds the folders to process. It bases it's search
7
+ on the presence or absence of the piston:root property.
8
+ * Changed lock and unlock messages to be more detailed.
9
+
3
10
  2006-08-24 1.0.1
4
11
  * Corrected minor bug where the core extensions were in core_ext/core_ext
5
12
  instead of being in core_ext.
@@ -2,7 +2,7 @@ module Piston
2
2
  # The base class which all commands subclass to obtain services from.
3
3
  class Command
4
4
  attr_accessor :revision, :dry_run, :quiet, :verbose, :force, :lock,
5
- :logging_stream
5
+ :recursive, :logging_stream
6
6
 
7
7
  # Execute this command. The arguments are pre-processed to expand any
8
8
  # wildcards using Dir#[]. This is because the Windows shell does not
@@ -0,0 +1,88 @@
1
+ require 'piston/commands/import'
2
+
3
+ module Piston
4
+ module Commands
5
+ class Convert < Piston::Command
6
+ def run(args)
7
+ if args.empty? then
8
+ svn(:propget, '--recursive', 'svn:externals').each_line do |line|
9
+ next unless line =~ /^([^ ]+)\s-\s/
10
+ args << $1
11
+ end
12
+ end
13
+
14
+ return logging_stream.puts("No svn:externals defined in this folder or any of it's subfolders") if args.empty?
15
+
16
+ args.each do |dir|
17
+ externals = svn(:propget, 'svn:externals', dir)
18
+ next skip_no_externals(dir) if externals.chomp.empty?
19
+
20
+ operations = Array.new
21
+ externals.each_line do |external|
22
+ external.chomp!
23
+ next if external.empty?
24
+ next skip_no_match(external) unless external =~ /^([^ ]+)\s+(?:-r(\d+)\s+)?(.*)$/
25
+
26
+ local, revision, repos = $1, $2, $3
27
+ lock = true if revision
28
+ local_dir = File.join(dir, local)
29
+ if File.exists?(local_dir)
30
+ raise Piston::CommandError, "'#{local_dir}' is not a directory" unless File.directory?(local_dir)
31
+ status = svn(:status, local_dir)
32
+ raise Piston::CommandError, "'#{local_dir}' has local modifications. Revert before trying again." unless status.empty?
33
+ info = YAML::load(svn(:info, local_dir))
34
+ revision = info['Last Changed Rev'] unless revision
35
+ FileUtils.rm_rf(local_dir)
36
+ end
37
+
38
+ operations << [local_dir, revision, repos, lock]
39
+ end
40
+
41
+ operations.each do |local_dir, revision, repos, lock|
42
+ logging_stream.puts "Importing '#{repos}' to #{local_dir} (-r #{revision || 'HEAD'}#{' locked' if lock})"
43
+ import = Piston::Commands::Import.new
44
+ import.revision = revision
45
+ import.verbose, import.quiet, import.logging_stream = self.verbose, self.quiet, self.logging_stream
46
+ import.lock = lock
47
+ import.run([repos, local_dir])
48
+ logging_stream.puts
49
+ end
50
+ end
51
+
52
+ svn :propdel, 'svn:externals', *args
53
+ logging_stream.puts "Done converting existing svn:externals to Piston"
54
+ end
55
+
56
+ def skip_no_externals(dir)
57
+ logging_stream.puts "Skipping '#{dir}' - no svn:externals definition"
58
+ end
59
+
60
+ def skip_no_match(external)
61
+ logging_stream.puts "#{external.inspect} did not match Regexp"
62
+ end
63
+
64
+ def self.help
65
+ "Converts existing svn:externals into Piston managed folders"
66
+ end
67
+
68
+ def self.detailed_help(stream)
69
+ stream.puts <<EOF
70
+ convert: #{help}
71
+ usage: convert [DIR [...]]
72
+
73
+ Converts folders which have the svn:externals property set to Piston managed
74
+ folders.
75
+
76
+ Valid options:
77
+ --verbose : Show Subversion commands and results as they
78
+ are executed
79
+
80
+ EOF
81
+ end
82
+
83
+ def self.aliases
84
+ %w(convert)
85
+ end
86
+ end
87
+ end
88
+ end
@@ -15,8 +15,8 @@ module Piston
15
15
  end
16
16
 
17
17
  my_info = YAML::load(svn(:info, File.join(dir, '..')))
18
- my_revision = YAML::load(svn(:info, my_info['URL']))['Revision']
19
- raise Piston::CommandError, "#{File.expand_path(File.join(dir, '..'))} is out of date - run svn update" unless my_info['Revision'] == my_revision
18
+ my_revision = YAML::load(svn(:info, my_info['URL']))['Revision']
19
+ raise Piston::CommandError, "#{File.expand_path(File.join(dir, '..'))} is out of date - run svn update" unless my_info['Revision'] == my_revision
20
20
 
21
21
  info = YAML::load(svn(:info, repos))
22
22
  options = [:export]
@@ -7,13 +7,12 @@ module Piston
7
7
  args.each do |dir|
8
8
  remote_rev = svn(:propget, Piston::REMOTE_REV, dir).chomp.to_i
9
9
  svn :propset, Piston::LOCKED, remote_rev, dir
10
+ logging_stream.puts "'#{dir}' locked at revision #{remote_rev}"
10
11
  end
11
-
12
- logging_stream.puts "Locked #{args.size} folder(s)"
13
12
  end
14
13
 
15
14
  def self.help
16
- "Lock one or more folders to a specific revision"
15
+ "Lock one or more folders to their current revision"
17
16
  end
18
17
 
19
18
  def self.detailed_help(stream)
@@ -4,7 +4,9 @@ module Piston
4
4
  def run(args)
5
5
  raise Piston::CommandError, "No targets to run against" if args.empty?
6
6
  svn :propdel, Piston::LOCKED, *args
7
- logging_stream.puts "Unlocked #{args.size} folder(s)"
7
+ args.each do |dir|
8
+ logging_stream.puts "Unlocked '#{dir}'"
9
+ end
8
10
  end
9
11
 
10
12
  def self.help
@@ -1,17 +1,29 @@
1
+ require 'find'
2
+
1
3
  module Piston
2
4
  module Commands
3
5
  class Update < Piston::Command
4
6
  def run(args)
5
- args.each do |dir|
7
+ (args.empty? ? find_targets : args).each do |dir|
6
8
  update dir
7
9
  end
8
10
  end
9
11
 
12
+ def find_targets
13
+ targets = Array.new
14
+ svn(:propget, '--recursive', Piston::ROOT).each_line do |line|
15
+ next unless line =~ /^([^ ]+)\s-\s.*$/
16
+ targets << $1
17
+ end
18
+
19
+ targets
20
+ end
21
+
10
22
  def update(dir)
11
- next unless File.directory?(dir)
12
- next skip(dir, "locked") unless svn(:propget, LOCKED, dir) == ''
23
+ return unless File.directory?(dir)
24
+ return skip(dir, "locked") unless svn(:propget, LOCKED, dir) == ''
13
25
  status = svn :status, '--show-updates', dir
14
- next skip(dir, "pending updates -- run \"svn update #{dir}\"") if status.split("\n").size > 1
26
+ return skip(dir, "pending updates -- run \"svn update #{dir}\"") if status.split("\n").size > 1
15
27
 
16
28
  logging_stream.print "Processing '#{dir}'... "
17
29
  repos = svn(:propget, Piston::ROOT, dir).chomp
@@ -20,10 +32,10 @@ module Piston
20
32
  local_revision = svn(:propget, Piston::LOCAL_REV, dir).chomp.to_i
21
33
 
22
34
  info = YAML::load(svn(:info, repos))
23
- next skip(dir, "Repository UUID changed\n Expected #{uuid}\n Found #{info['Repository UUID']}\n Repository: #{repos}") unless uuid == info['Repository UUID']
35
+ return skip(dir, "Repository UUID changed\n Expected #{uuid}\n Found #{info['Repository UUID']}\n Repository: #{repos}") unless uuid == info['Repository UUID']
24
36
 
25
37
  new_remote_rev = info['Last Changed Rev'].to_i
26
- next skip(dir, "unchanged from revision #{remote_revision}") if remote_revision == new_remote_rev
38
+ return skip(dir, "unchanged from revision #{remote_revision}", false) if remote_revision == new_remote_rev
27
39
 
28
40
  info = YAML::load(svn(:info, File.join(dir, '..')))
29
41
  new_local_rev = info['Revision']
@@ -41,11 +53,11 @@ module Piston
41
53
  case op
42
54
  when 'A'
43
55
  if File.directory?(File.join(dir.tmp, file)) then
44
- svn :mkdir, File.join(dir, file)
45
- else
56
+ svn :mkdir, File.join(dir, file)
57
+ else
46
58
  copy(dir, file)
47
59
  svn :add, '--force', File.join(dir, file)
48
- end
60
+ end
49
61
  when 'D'
50
62
  svn :remove, '--force', File.join(dir, file)
51
63
  else
@@ -55,11 +67,11 @@ module Piston
55
67
  end
56
68
 
57
69
  merges.each do |file|
58
- begin
70
+ begin
59
71
  svn :merge, '--quiet', '--revision', (local_revision.succ .. new_local_rev).to_svn, File.join(dir, file), File.join(dir, file)
60
- rescue RuntimeError
61
- next if $!.message =~ /Unable to find repository location for/
62
- end
72
+ rescue RuntimeError
73
+ next if $!.message =~ /Unable to find repository location for/
74
+ end
63
75
  end unless local_revision.succ == new_local_rev
64
76
 
65
77
  FileUtils.rm_rf dir.tmp
@@ -68,25 +80,26 @@ module Piston
68
80
  svn :propset, Piston::LOCAL_REV, new_local_rev, dir
69
81
  svn :propset, Piston::LOCKED, revisions.last, dir if lock
70
82
 
71
- logging_stream.puts "Updated to #{revisions.last} (#{changes} changed files)"
83
+ logging_stream.puts "Updated to #{revisions.last} (#{changes} changes)"
72
84
  end
73
85
 
74
86
  def copy(dir, file)
75
87
  FileUtils.cp(File.join(dir.tmp, file), File.join(dir, file))
76
88
  end
77
89
 
78
- def skip(dir, msg)
79
- logging_stream.puts "Skipping '#{dir}': #{msg}"
90
+ def skip(dir, msg, header=true)
91
+ logging_stream.print "Skipping '#{dir}': " if header
92
+ logging_stream.puts msg
80
93
  end
81
94
 
82
95
  def self.help
83
- "Updates one or more folders to the latest revision"
96
+ "Updates all or specified folders to the latest revision"
84
97
  end
85
98
 
86
99
  def self.detailed_help(stream)
87
100
  stream.puts <<EOF
88
101
  update: #{help}
89
- usage: update DIR [...]
102
+ usage: update [DIR [...]]
90
103
 
91
104
  This operation has the effect of downloading all remote changes back to our
92
105
  working copy. If any local modifications were done, they will be preserved.
@@ -67,3 +67,5 @@ module Piston
67
67
  end
68
68
  end
69
69
  end
70
+
71
+ Piston::Ui::CommandLine.start if $0 == __FILE__
@@ -1,8 +1,8 @@
1
1
  module Piston
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 1
4
- MINOR = 0
5
- TINY = 1
4
+ MINOR = 1
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: piston
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.1
7
- date: 2006-08-25 00:00:00 +00:00
6
+ version: 1.1.0
7
+ date: 2006-08-27 00:00:00 +00:00
8
8
  summary: Piston is a utility that enables merge tracking of remote repositories.
9
9
  require_paths:
10
10
  - lib
@@ -49,6 +49,7 @@ files:
49
49
  - lib/piston/commands/lock.rb
50
50
  - lib/piston/commands/import.rb
51
51
  - lib/piston/commands/unlock.rb
52
+ - lib/piston/commands/convert.rb
52
53
  - lib/piston/ui/command_line.rb
53
54
  test_files: []
54
55