pivotal-piston 1.9.4

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 (96) hide show
  1. data/.gitignore +8 -0
  2. data/History.txt +11 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +85 -0
  5. data/README.txt +136 -0
  6. data/Rakefile +4 -0
  7. data/bin/piston +5 -0
  8. data/config/hoe.rb +79 -0
  9. data/config/requirements.rb +18 -0
  10. data/lib/piston.rb +18 -0
  11. data/lib/piston/cli.rb +315 -0
  12. data/lib/piston/commands.rb +4 -0
  13. data/lib/piston/commands/base.rb +44 -0
  14. data/lib/piston/commands/import.rb +42 -0
  15. data/lib/piston/commands/info.rb +14 -0
  16. data/lib/piston/commands/lock_unlock.rb +21 -0
  17. data/lib/piston/commands/update.rb +29 -0
  18. data/lib/piston/git.rb +12 -0
  19. data/lib/piston/git/client.rb +77 -0
  20. data/lib/piston/git/commit.rb +74 -0
  21. data/lib/piston/git/repository.rb +63 -0
  22. data/lib/piston/git/working_copy.rb +86 -0
  23. data/lib/piston/repository.rb +57 -0
  24. data/lib/piston/revision.rb +53 -0
  25. data/lib/piston/svn.rb +14 -0
  26. data/lib/piston/svn/client.rb +88 -0
  27. data/lib/piston/svn/repository.rb +67 -0
  28. data/lib/piston/svn/revision.rb +74 -0
  29. data/lib/piston/svn/working_copy.rb +108 -0
  30. data/lib/piston/version.rb +9 -0
  31. data/lib/piston/working_copy.rb +183 -0
  32. data/lib/subclass_responsibility_error.rb +2 -0
  33. data/log/.gitignore +0 -0
  34. data/samples/common.rb +19 -0
  35. data/samples/import_git_git.rb +39 -0
  36. data/samples/import_git_svn.rb +36 -0
  37. data/samples/import_svn_git.rb +29 -0
  38. data/samples/import_svn_svn.rb +24 -0
  39. data/script/destroy +14 -0
  40. data/script/generate +14 -0
  41. data/script/txt2html +74 -0
  42. data/setup.rb +1585 -0
  43. data/tasks/deployment.rake +34 -0
  44. data/tasks/environment.rake +7 -0
  45. data/tasks/samples.rake +6 -0
  46. data/tasks/test.rake +69 -0
  47. data/tasks/website.rake +17 -0
  48. data/test/integration/test_git_git.rb +99 -0
  49. data/test/integration/test_git_svn.rb +121 -0
  50. data/test/integration/test_import_svn_git.rb +47 -0
  51. data/test/integration/test_import_svn_svn.rb +38 -0
  52. data/test/integration_helpers.rb +33 -0
  53. data/test/test_helper.rb +83 -0
  54. data/test/unit/git/commit/test_checkout.rb +31 -0
  55. data/test/unit/git/commit/test_each.rb +30 -0
  56. data/test/unit/git/commit/test_rememberance.rb +21 -0
  57. data/test/unit/git/commit/test_validation.rb +34 -0
  58. data/test/unit/git/repository/test_at.rb +23 -0
  59. data/test/unit/git/repository/test_basename.rb +12 -0
  60. data/test/unit/git/repository/test_branchanme.rb +15 -0
  61. data/test/unit/git/repository/test_guessing.rb +32 -0
  62. data/test/unit/git/working_copy/test_copying.rb +25 -0
  63. data/test/unit/git/working_copy/test_creation.rb +22 -0
  64. data/test/unit/git/working_copy/test_existence.rb +18 -0
  65. data/test/unit/git/working_copy/test_finalization.rb +15 -0
  66. data/test/unit/git/working_copy/test_guessing.rb +35 -0
  67. data/test/unit/git/working_copy/test_rememberance.rb +21 -0
  68. data/test/unit/svn/repository/test_at.rb +19 -0
  69. data/test/unit/svn/repository/test_basename.rb +24 -0
  70. data/test/unit/svn/repository/test_guessing.rb +45 -0
  71. data/test/unit/svn/revision/test_checkout.rb +28 -0
  72. data/test/unit/svn/revision/test_each.rb +22 -0
  73. data/test/unit/svn/revision/test_rememberance.rb +38 -0
  74. data/test/unit/svn/revision/test_validation.rb +50 -0
  75. data/test/unit/svn/working_copy/test_copying.rb +26 -0
  76. data/test/unit/svn/working_copy/test_creation.rb +16 -0
  77. data/test/unit/svn/working_copy/test_existence.rb +23 -0
  78. data/test/unit/svn/working_copy/test_externals.rb +56 -0
  79. data/test/unit/svn/working_copy/test_finalization.rb +17 -0
  80. data/test/unit/svn/working_copy/test_guessing.rb +18 -0
  81. data/test/unit/svn/working_copy/test_merging.rb +47 -0
  82. data/test/unit/svn/working_copy/test_rememberance.rb +26 -0
  83. data/test/unit/test_info.rb +37 -0
  84. data/test/unit/test_lock_unlock.rb +47 -0
  85. data/test/unit/test_repository.rb +51 -0
  86. data/test/unit/test_revision.rb +31 -0
  87. data/test/unit/working_copy/test_guessing.rb +35 -0
  88. data/test/unit/working_copy/test_info.rb +14 -0
  89. data/test/unit/working_copy/test_rememberance.rb +42 -0
  90. data/test/unit/working_copy/test_validate.rb +63 -0
  91. data/website/index.html +11 -0
  92. data/website/index.txt +39 -0
  93. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  94. data/website/stylesheets/screen.css +138 -0
  95. data/website/template.rhtml +48 -0
  96. metadata +244 -0
@@ -0,0 +1,9 @@
1
+ module Piston #:nodoc:
2
+ module VERSION #:nodoc:
3
+ MAJOR = 1
4
+ MINOR = 9
5
+ TINY = 4
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join(".")
8
+ end
9
+ end
@@ -0,0 +1,183 @@
1
+ module Piston
2
+ class WorkingCopy
3
+ class UnhandledWorkingCopy < RuntimeError; end
4
+ class NotWorkingCopy < RuntimeError; end
5
+
6
+ class << self
7
+ def logger
8
+ @@logger ||= Log4r::Logger["handler"]
9
+ end
10
+
11
+ def guess(path)
12
+ path = path.kind_of?(Pathname) ? path : Pathname.new(path.to_s)
13
+ try_path = path.exist? ? path : path.parent
14
+ logger.info {"Guessing the working copy type of #{try_path.inspect}"}
15
+ handler = handlers.detect do |handler|
16
+ logger.debug {"Asking #{handler.name} if it understands #{try_path}"}
17
+ handler.understands_dir?(try_path)
18
+ end
19
+
20
+ raise UnhandledWorkingCopy, "Don't know what working copy type #{path} is." if handler.nil?
21
+ handler.new(path)
22
+ end
23
+
24
+ @@handlers = Array.new
25
+ def add_handler(handler)
26
+ @@handlers << handler
27
+ end
28
+
29
+ def handlers
30
+ @@handlers
31
+ end
32
+ private :handlers
33
+ end
34
+
35
+ attr_reader :path
36
+
37
+ def initialize(path)
38
+ if path.kind_of?(Pathname)
39
+ raise ArgumentError, "#{path} must be absolute" unless path.absolute?
40
+ @path = path
41
+ else
42
+ @path = Pathname.new(File.expand_path(path))
43
+ end
44
+ logger.debug {"Initialized on #{@path}"}
45
+ end
46
+
47
+ def logger
48
+ self.class.logger
49
+ end
50
+
51
+ def to_s
52
+ "Piston::WorkingCopy(#{@path})"
53
+ end
54
+
55
+ def exist?
56
+ @path.exist? && @path.directory?
57
+ end
58
+
59
+ def pistonized?
60
+ yaml_path.exist? && yaml_path.file?
61
+ end
62
+
63
+ def validate!
64
+ raise NotWorkingCopy unless self.pistonized?
65
+ self
66
+ end
67
+
68
+ # Creates the initial working copy for pistonizing a new repository.
69
+ def create
70
+ logger.debug {"Creating working copy at #{path}"}
71
+ end
72
+
73
+ # Copy files from +revision+. +revision+ must
74
+ # #respond_to?(:each), and return each file that is to be copied.
75
+ # Only files must be returned.
76
+ #
77
+ # Each item yielded by Revision#each must be a relative path.
78
+ #
79
+ # WorkingCopy will call Revision#copy_to with the full path to where the
80
+ # file needs to be copied.
81
+ def copy_from(revision)
82
+ revision.each do |relpath|
83
+ target = path + relpath
84
+ target.dirname.mkdir rescue nil
85
+
86
+ logger.debug {"Copying #{relpath} to #{target}"}
87
+ revision.copy_to(relpath, target)
88
+ end
89
+ end
90
+
91
+ # Stores a Hash of values that can be retrieved later.
92
+ def remember(values, handler_values)
93
+ values["format"] = 1
94
+
95
+ # Stringify keys
96
+ values.keys.each do |key|
97
+ values[key.to_s] = values.delete(key)
98
+ end
99
+
100
+ logger.debug {"Remembering #{values.inspect} as well as #{handler_values.inspect}"}
101
+ File.open(yaml_path, "w+") do |f|
102
+ f.write(values.merge("handler" => handler_values).to_yaml)
103
+ end
104
+
105
+ logger.debug {"Calling \#after_remember on #{yaml_path}"}
106
+ after_remember(yaml_path)
107
+ end
108
+
109
+ # Callback after #remember is done, to do whatever the
110
+ # working copy needs to do with the file.
111
+ def after_remember(path)
112
+ end
113
+
114
+ # Recalls a Hash of values from the working copy.
115
+ def recall
116
+ YAML.load_file(yaml_path)
117
+ end
118
+
119
+ def finalize
120
+ logger.debug {"Finalizing #{path}"}
121
+ end
122
+
123
+ # Returns basic information about this working copy.
124
+ def info
125
+ recall
126
+ end
127
+
128
+ def import(revision, lock)
129
+ repository = revision.repository
130
+ tmpdir = temp_dir_name
131
+ begin
132
+ logger.info {"Checking out the repository"}
133
+ revision.checkout_to(tmpdir)
134
+
135
+ logger.debug {"Creating the local working copy"}
136
+ create
137
+
138
+ logger.info {"Copying from #{revision}"}
139
+ copy_from(revision)
140
+
141
+ logger.debug {"Remembering values"}
142
+ remember(
143
+ {:repository_url => repository.url, :lock => lock, :repository_class => repository.class.name},
144
+ revision.remember_values
145
+ )
146
+
147
+ logger.debug {"Finalizing working copy"}
148
+ finalize
149
+
150
+ logger.info {"Checked out #{repository.url.inspect} #{revision.name} to #{path.to_s}"}
151
+ ensure
152
+ logger.debug {"Removing temporary directory: #{tmpdir}"}
153
+ tmpdir.rmtree rescue nil
154
+ end
155
+ end
156
+
157
+ # Update this working copy from +from+ to +to+, which means merging local changes back in
158
+ def update(to, lock)
159
+ tmpdir = temp_dir_name
160
+ begin
161
+ to.checkout_to(tmpdir)
162
+ do_update(to, lock)
163
+ ensure
164
+ logger.debug {"Removing temporary directory: #{tmpdir}"}
165
+ tmpdir.rmtree rescue nil
166
+ end
167
+ end
168
+
169
+ def temp_dir_name
170
+ path.parent + ".#{path.basename}.tmp"
171
+ end
172
+
173
+ protected
174
+ def do_update(to, lock)
175
+ raise NotImplementedError
176
+ end
177
+
178
+ # The path to the piston YAML file.
179
+ def yaml_path
180
+ path + ".piston.yml"
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,2 @@
1
+ class SubclassResponsibilityError < RuntimeError
2
+ end
data/log/.gitignore ADDED
File without changes
data/samples/common.rb ADDED
@@ -0,0 +1,19 @@
1
+ # Common code between all sample files.
2
+ # Setup the environment.
3
+ require "pathname"
4
+ require "logger"
5
+
6
+ @root = Pathname.new(File.dirname(__FILE__)).parent
7
+ $:.unshift("#{@root}lib"
8
+
9
+ require "piston"
10
+ require "piston/svn"
11
+ require "piston/git"
12
+
13
+ PISTON_DEFAULT_LOGGER = Logger.new(STDOUT)
14
+ Piston::Repository.logger = Piston::WorkingCopy.logger = PISTON_DEFAULT_LOGGER
15
+ def logger; PISTON_DEFAULT_LOGGER; end
16
+
17
+ include Piston::Svn::Client
18
+ include Piston::Git::Client
19
+
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Import an SVN repository into an SVN working copy.
4
+ require "#{File.dirname(__FILE__)}/common"
5
+
6
+ @root = @root + "tmp/git_git"
7
+ @root.rmtree rescue nil
8
+ @root.mkpath
9
+
10
+ @tmp = @root + "plugin.tmp"
11
+
12
+ @plugin = @root + "plugin"
13
+ @plugin.mkpath
14
+ File.open(@plugin + "README", "wb") {|f| f.puts "Hello World"}
15
+ File.open(@plugin + "init.rb", "wb") {|f| f.puts "# Some init code"}
16
+ Dir.chdir(@plugin) do
17
+ git :init
18
+ git :add, "."
19
+ git :commit, "-m", "initial commit"
20
+ end
21
+
22
+ @wc = @root + "wc"
23
+ @wc.mkpath
24
+ File.open(@wc + "README", "wb") {|f| f.puts "My local project"}
25
+ Dir.chdir(@wc) do
26
+ git :init
27
+ git :add, "."
28
+ git :commit, "-m", "initial commit"
29
+ end
30
+
31
+ repos = Piston::Git::Repository.new("file://" + @plugin.realpath)
32
+ commit = repos.at(:head)
33
+ commit.checkout_to(@tmp)
34
+
35
+ wc = Piston::Git::WorkingCopy.new(@wc + "vendor")
36
+ wc.create
37
+ wc.copy_from(commit)
38
+ wc.remember(commit.remember_values)
39
+ wc.finalize
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Import a Git project into a Subversion working copy.
4
+ require "#{File.dirname(__FILE__)}/common"
5
+
6
+ @root = @root + "tmp/git_svn"
7
+ @root.rmtree rescue nil
8
+ @root.mkpath
9
+
10
+ @repos = @root + "repos"
11
+ @wc = @root + "wc"
12
+
13
+ @plugin = @root + "plugin"
14
+ @tmp = @root + "plugin.tmp"
15
+
16
+ svnadmin :create, @repos
17
+ svn :checkout, "--quiet", "file://" + @repos.realpath, @wc
18
+
19
+ @plugin.mkpath
20
+ File.open(@plugin + "README", "wb") {|f| f.puts "Hello World"}
21
+ File.open(@plugin + "init.rb", "wb") {|f| f.puts "# Some initialization code here"}
22
+ Dir.chdir(@plugin) do
23
+ logger.debug {"CWD: #{Dir.getwd}"}
24
+ git :init
25
+ git :add, "."
26
+ git :commit, "-m", "initial commit"
27
+ end
28
+
29
+ repos = Piston::Git::Repository.new("file://" + @plugin.realpath)
30
+ commit = repos.at(:head)
31
+ commit.checkout_to(@tmp)
32
+ wc = Piston::Svn::WorkingCopy.new(@wc + "vendor")
33
+ wc.create
34
+ wc.copy_from(commit)
35
+ wc.remember(commit.remember_values)
36
+ wc.finalize
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Import an SVN repository into a Git working copy.
4
+ require "#{File.dirname(__FILE__)}/common"
5
+
6
+ @root = @root + "tmp/svn_git"
7
+ @root.rmtree rescue nil
8
+ @root.mkpath
9
+
10
+ @repos = @root + "repos"
11
+ @wc = @root + "wc"
12
+ @tmp = @root + "xlsuite.tmp"
13
+
14
+ @wc.mkpath
15
+ File.open(@wc + "README", "wb") {|f| f.write "Hello World"}
16
+ Dir.chdir(@wc) do
17
+ git :init
18
+ git :add, "."
19
+ git :commit, "-m", "initial"
20
+ end
21
+
22
+ repos = Piston::Svn::Repository.new("http://svn.xlsuite.org/trunk/lib")
23
+ rev = repos.at(:head)
24
+ rev.checkout_to(@tmp)
25
+ wc = Piston::Git::WorkingCopy.new(@wc + "vendor")
26
+ wc.create
27
+ wc.copy_from(rev)
28
+ wc.remember(rev.remember_values)
29
+ wc.finalize
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Import an SVN repository into an SVN working copy.
4
+ require "#{File.dirname(__FILE__)}/common"
5
+
6
+ @root = @root + "tmp/svn_svn"
7
+ @root.rmtree rescue nil
8
+ @root.mkpath
9
+
10
+ @repos = @root + "repos"
11
+ @wc = @root + "wc"
12
+ @tmp = @root + "xlsuite.tmp"
13
+
14
+ svnadmin :create, @repos
15
+ svn :checkout, "file://#{@repos.realpath}", @wc
16
+
17
+ repos = Piston::Svn::Repository.new("http://svn.xlsuite.org/trunk/lib")
18
+ rev = repos.at(:head)
19
+ rev.checkout_to(@tmp)
20
+ wc = Piston::Svn::WorkingCopy.new(@wc + "tmp")
21
+ wc.create
22
+ wc.copy_from(rev)
23
+ wc.remember(rev.remember_values)
24
+ wc.finalize
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
data/script/txt2html ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ begin
5
+ require 'newgem'
6
+ rescue LoadError
7
+ puts "\n\nGenerating the website requires the newgem RubyGem"
8
+ puts "Install: gem install newgem\n\n"
9
+ exit(1)
10
+ end
11
+ require 'redcloth'
12
+ require 'syntax/convertors/html'
13
+ require 'erb'
14
+ require File.dirname(__FILE__) + '/../lib/piston/version.rb'
15
+
16
+ version = Piston::VERSION::STRING
17
+ download = 'http://rubyforge.org/projects/piston'
18
+
19
+ class Fixnum
20
+ def ordinal
21
+ # teens
22
+ return 'th' if (10..19).include?(self % 100)
23
+ # others
24
+ case self % 10
25
+ when 1: return 'st'
26
+ when 2: return 'nd'
27
+ when 3: return 'rd'
28
+ else return 'th'
29
+ end
30
+ end
31
+ end
32
+
33
+ class Time
34
+ def pretty
35
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
36
+ end
37
+ end
38
+
39
+ def convert_syntax(syntax, source)
40
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
41
+ end
42
+
43
+ if ARGV.length >= 1
44
+ src, template = ARGV
45
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.rhtml')
46
+
47
+ else
48
+ puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
49
+ exit!
50
+ end
51
+
52
+ template = ERB.new(File.open(template).read)
53
+
54
+ title = nil
55
+ body = nil
56
+ File.open(src) do |fsrc|
57
+ title_text = fsrc.readline
58
+ body_text = fsrc.read
59
+ syntax_items = []
60
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
61
+ ident = syntax_items.length
62
+ element, syntax, source = $1, $2, $3
63
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
64
+ "syntax-temp-#{ident}"
65
+ }
66
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
67
+ body = RedCloth.new(body_text).to_html
68
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
69
+ end
70
+ stat = File.stat(src)
71
+ created = stat.ctime
72
+ modified = stat.mtime
73
+
74
+ $stdout << template.result(binding)