sitefuel 0.0.0b → 0.1.0a

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. data/README.rdoc +81 -0
  2. data/{RELEASE_NOTES → RELEASE_NOTES.rdoc} +0 -0
  3. data/bin/sitefuel +64 -111
  4. data/lib/sitefuel/CommandLine.rb +142 -0
  5. data/lib/sitefuel/Configuration.rb +49 -13
  6. data/lib/sitefuel/License.rb +292 -0
  7. data/lib/sitefuel/SiteFuelLogger.rb +34 -5
  8. data/lib/sitefuel/SiteFuelRuntime.rb +217 -44
  9. data/lib/sitefuel/extensions/ArrayComparisons.rb +2 -2
  10. data/lib/sitefuel/extensions/ColumnPrinter.rb +276 -0
  11. data/lib/sitefuel/extensions/DynamicClassMethods.rb +2 -2
  12. data/lib/sitefuel/extensions/FileComparison.rb +2 -2
  13. data/lib/sitefuel/extensions/FileTree.rb +94 -0
  14. data/lib/sitefuel/extensions/Silently.rb +2 -2
  15. data/lib/sitefuel/extensions/StringFormatting.rb +52 -8
  16. data/lib/sitefuel/extensions/SymbolComparison.rb +4 -2
  17. data/lib/sitefuel/extensions/TerminalInfo.rb +53 -0
  18. data/lib/sitefuel/external/AbstractExternalProgram.rb +65 -11
  19. data/lib/sitefuel/external/ExternalProgramTestCase.rb +2 -2
  20. data/lib/sitefuel/external/GIT.rb +50 -3
  21. data/lib/sitefuel/external/JPEGTran.rb +2 -2
  22. data/lib/sitefuel/external/PNGCrush.rb +2 -2
  23. data/lib/sitefuel/external/SVN.rb +57 -0
  24. data/lib/sitefuel/processors/AbstractExternalProgramProcessor.rb +17 -4
  25. data/lib/sitefuel/processors/AbstractProcessor.rb +64 -47
  26. data/lib/sitefuel/processors/AbstractStringBasedProcessor.rb +20 -3
  27. data/lib/sitefuel/processors/CSSProcessor.rb +2 -2
  28. data/lib/sitefuel/processors/Configurable.rb +94 -0
  29. data/lib/sitefuel/processors/HAMLProcessor.rb +4 -4
  30. data/lib/sitefuel/processors/HTMLProcessor.rb +2 -2
  31. data/lib/sitefuel/processors/JavaScriptProcessor.rb +2 -2
  32. data/lib/sitefuel/processors/PHPProcessor.rb +2 -2
  33. data/lib/sitefuel/processors/PNGProcessor.rb +2 -2
  34. data/lib/sitefuel/processors/RHTMLProcessor.rb +2 -2
  35. data/lib/sitefuel/processors/SASSProcessor.rb +4 -4
  36. data/test/{test_images → images}/sample_jpg01.jpg +0 -0
  37. data/test/{test_images → images}/sample_png01.png +0 -0
  38. data/test/processor_listing.rb +2 -2
  39. data/test/{test_programs → programs}/versioning.rb +2 -2
  40. data/test/repositories/git/few_files/deployment.yml +0 -0
  41. data/test/repositories/git/few_files/index.html +10 -0
  42. data/test/repositories/git/few_files/style.css +2 -0
  43. data/test/repositories/svn/testrepo1/README.txt +5 -0
  44. data/test/repositories/svn/testrepo1/conf/authz +32 -0
  45. data/test/repositories/svn/testrepo1/conf/passwd +8 -0
  46. data/test/repositories/svn/testrepo1/conf/svnserve.conf +47 -0
  47. data/test/repositories/svn/testrepo1/db/current +1 -0
  48. data/test/repositories/svn/testrepo1/db/format +2 -0
  49. data/test/repositories/svn/testrepo1/db/fs-type +1 -0
  50. data/test/repositories/svn/testrepo1/db/fsfs.conf +37 -0
  51. data/test/repositories/svn/testrepo1/db/min-unpacked-rev +1 -0
  52. data/test/repositories/svn/testrepo1/db/rep-cache.db +0 -0
  53. data/test/repositories/svn/testrepo1/db/revprops/0/0 +5 -0
  54. data/test/repositories/svn/testrepo1/db/revprops/0/1 +13 -0
  55. data/test/repositories/svn/testrepo1/db/revs/0/0 +11 -0
  56. data/test/repositories/svn/testrepo1/db/revs/0/1 +0 -0
  57. data/test/repositories/svn/testrepo1/db/txn-current +1 -0
  58. data/test/repositories/svn/testrepo1/db/txn-current-lock +0 -0
  59. data/test/repositories/svn/testrepo1/db/uuid +1 -0
  60. data/test/repositories/svn/testrepo1/db/write-lock +0 -0
  61. data/test/repositories/svn/testrepo1/format +1 -0
  62. data/test/repositories/svn/testrepo1/hooks/post-commit.tmpl +50 -0
  63. data/test/repositories/svn/testrepo1/hooks/post-lock.tmpl +45 -0
  64. data/test/repositories/svn/testrepo1/hooks/post-revprop-change.tmpl +57 -0
  65. data/test/repositories/svn/testrepo1/hooks/post-unlock.tmpl +43 -0
  66. data/test/repositories/svn/testrepo1/hooks/pre-commit.tmpl +85 -0
  67. data/test/repositories/svn/testrepo1/hooks/pre-lock.tmpl +71 -0
  68. data/test/repositories/svn/testrepo1/hooks/pre-revprop-change.tmpl +66 -0
  69. data/test/repositories/svn/testrepo1/hooks/pre-unlock.tmpl +63 -0
  70. data/test/repositories/svn/testrepo1/hooks/start-commit.tmpl +68 -0
  71. data/test/repositories/svn/testrepo1/locks/db-logs.lock +3 -0
  72. data/test/repositories/svn/testrepo1/locks/db.lock +3 -0
  73. data/test/sites/simplehtml/deployment.yml +19 -0
  74. data/test/{test_sites → sites}/simplehtml/index.html +0 -0
  75. data/test/{test_sites → sites}/simplehtml/style.css +0 -0
  76. data/test/sites/sitefuelteaser/deployment.yml +13 -0
  77. data/test/sites/sitefuelteaser/img/hd.png +0 -0
  78. data/test/sites/sitefuelteaser/img/logo.png +0 -0
  79. data/test/sites/sitefuelteaser/img/uses-sitefuel.png +0 -0
  80. data/test/sites/sitefuelteaser/index.html +1 -1
  81. data/test/sites/sitefuelteaser/master.css +18 -0
  82. data/test/test_AbstractExternalProgram.rb +5 -5
  83. data/test/test_AbstractProcessor.rb +4 -4
  84. data/test/test_AbstractStringBasedProcessor.rb +2 -2
  85. data/test/test_AllProcessors.rb +4 -4
  86. data/test/test_ArrayComparisons.rb +4 -4
  87. data/test/test_CSSProcessor.rb +4 -4
  88. data/test/test_ColumnPrinter.rb +40 -0
  89. data/test/test_Configurable.rb +106 -0
  90. data/test/test_FileComparisons.rb +4 -4
  91. data/test/test_GIT.rb +41 -0
  92. data/test/{test_HAMLProcessor.rb.rb → test_HAMLProcessor.rb} +4 -4
  93. data/test/test_HTMLProcessor.rb +4 -4
  94. data/test/test_JPEGTran.rb +4 -4
  95. data/test/test_JavaScriptProcessor.rb +3 -2
  96. data/test/test_PHPProcessor.rb +4 -4
  97. data/test/test_PNGCrush.rb +8 -8
  98. data/test/test_PNGProcessor.rb +5 -5
  99. data/test/test_RHTMLProcessor.rb +4 -4
  100. data/test/test_SASSProcessor.rb +4 -4
  101. data/test/test_SVN.rb +44 -0
  102. data/test/test_SiteFuelLogging.rb +4 -4
  103. data/test/test_SiteFuelRuntime.rb +42 -4
  104. data/test/test_StringFormatting.rb +27 -4
  105. data/test/test_SymbolComparison.rb +4 -4
  106. data/test/ts_all.rb +2 -2
  107. metadata +94 -20
  108. data/README +0 -86
  109. data/test/test_sites/simplehtml/deployment.yml +0 -22
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # File:: ArrayComparisons.rb
3
3
  # Author:: wkm
4
- # Copyright:: 2009
5
- # License:: GPL
4
+ # Copyright:: 2009, Zanoccio LLC.
5
+ # License:: GPL version 2.0 (see LICENSE.rb)
6
6
  #
7
7
  # Adds methods to Array for comparing with other arrays
8
8
  #
@@ -0,0 +1,276 @@
1
+ #
2
+ # File:: ColumnPrinter.rb
3
+ # Author:: wkm
4
+ # Copyright:: 2009, Zanoccio LLC.
5
+ # License:: GPL version 2.0 (see LICENSE.rb)
6
+ #
7
+ # Little utility for printing terminal output in columns.
8
+ #
9
+ # Note that this utility buffers per-row, and so it has to decide column widths
10
+ # as soon as the first row is printed.
11
+ #
12
+ # TODO: there are a lot of off-by-one errors here. They don't matter for
13
+ # SiteFuel purposes so we haven't fixed them... but we should. ;-)
14
+ #
15
+ # == Examples
16
+ #
17
+ # printer = ColumnPrinter.new([15, :span, 20])
18
+ # printer.row 'some number', 'this gets expanded out', 'cell 3'
19
+ #
20
+
21
+ require 'sitefuel/extensions/StringFormatting'
22
+
23
+ class ColumnPrinter
24
+ # specify the width for the entire grid
25
+ attr_accessor :column_widths
26
+
27
+ # what character should be used
28
+ attr_accessor :corner_piece
29
+
30
+ # what character should be used to horizontally separate cells
31
+ attr_accessor :horizontal_divider_piece
32
+
33
+ # what character should be used to vertically separate rows. If =nil= or
34
+ # '' rows will not be separated.
35
+ attr_accessor :vertical_divider_piece
36
+
37
+ attr_accessor :allow_resizing
38
+
39
+ # specifies the minimum width for a column
40
+ attr_accessor :minimum_column_width
41
+
42
+
43
+ def initialize(column_widths, output_width = :automatic)
44
+ mode :aligned
45
+
46
+ self.column_widths = column_widths
47
+
48
+ @output_width = output_width
49
+
50
+ # we disallow resizing since the constant checking *really* slows
51
+ # printing down
52
+ @allow_resizing = false
53
+
54
+ @minimum_column_width = 5
55
+
56
+ compute_absolute_column_widths
57
+ alignment(:left)
58
+ end
59
+
60
+
61
+ # sets the alignment for the columns
62
+ def alignment(columns)
63
+ case columns
64
+ when Symbol
65
+ @column_alignment = Array.new(column_count, columns)
66
+
67
+ when Array
68
+ @column_alignment = columns
69
+ end
70
+ end
71
+
72
+
73
+ # gives the number of columns in this printer
74
+ def column_count
75
+ self.column_widths.length
76
+ end
77
+
78
+
79
+ # set the mode of the columns
80
+ # :aligned:: columns are aligned, but there are no explicit dividers
81
+ # :divided:: columns are aligned and separated by vertical dividers
82
+ # :cells:: columns are aligned and cells are separated by horizontal and
83
+ # vertical dividers.
84
+ def mode(kind)
85
+ case kind
86
+ when :aligned
87
+ @horizontal_divider_piece = ' '
88
+ @vertical_divider_piece = ''
89
+ @corner_piece = ''
90
+
91
+ when :divided
92
+ @horizontal_divider_piece = '|'
93
+ @vertical_divider_piece = ''
94
+ @corner_piece = ''
95
+
96
+ when :cells
97
+ @horizontal_divider_piece = '|'
98
+ @vertical_divider_piece = '-'
99
+ @corner_piece = '+'
100
+
101
+ else
102
+ raise StandardError.new("Unknown kind of mode for ColumnPrinter: #{kind}")
103
+ end
104
+ end
105
+
106
+
107
+ def output_width=(new_width)
108
+ if allow_resizing
109
+ @output_width = new_width
110
+ compute_absolute_column_widths
111
+ else
112
+ # don't do anything for now; TODO should raise a message
113
+ end
114
+ end
115
+
116
+
117
+ def output_width
118
+ if @output_width == :automatic
119
+ TerminalInfo.width
120
+ else
121
+ @output_width
122
+ end
123
+ end
124
+
125
+
126
+ # given the mixture of absolute, relative, and spanning widths computes the
127
+ # actual width of each column
128
+ #
129
+ # == Method
130
+ # * start with the output width and allocate space for each absolute
131
+ # sized column
132
+ # * of the space remaining, allocate that to relative sized columns
133
+ # * divy up any remaining space evenly between :span columns
134
+ def compute_absolute_column_widths
135
+ # we remove one to make room for the leading space
136
+ unallocated_width = output_width - 1
137
+
138
+ relative_columns = []
139
+ span_columns = []
140
+
141
+ @absolute_column_widths = Array.new(column_widths.length)
142
+
143
+ # group relative sizes and span sizes, allocate out space to absolute sizes
144
+ column_widths.each_with_index do |width, index|
145
+ case width
146
+ when :span
147
+ # store for later computation
148
+ span_columns << [index, :span]
149
+
150
+ when Float
151
+ relative_columns << [index, width]
152
+
153
+ when Fixnum
154
+ @absolute_column_widths[index] = actual_width(width)
155
+ unallocated_width -= actual_width(width) + 1
156
+ end
157
+ end
158
+
159
+ # allocate out space to relative sizes
160
+ relative_columns.each do |entry|
161
+ real_size = actual_width(unallocated_width * entry.last)
162
+ unallocated_width -= real_size + 1
163
+
164
+ @absolute_column_widths[entry.first] = real_size
165
+ end
166
+
167
+ # allocate out space to span sizes
168
+ num_spans = span_columns.length.prec_f
169
+
170
+ # if there are no spans we're done
171
+ if num_spans < 1
172
+ return @absolute_column_widths
173
+ end
174
+
175
+ real_size = actual_width((unallocated_width - num_spans) / num_spans)
176
+ span_columns.each do |entry|
177
+ @absolute_column_widths[entry.first] = real_size
178
+ end
179
+
180
+ @absolute_column_widths
181
+ end
182
+
183
+
184
+ # if the given width is less than #minimum_column_width, gives
185
+ # #minimum_column_width. Otherwise gives floor() of the given width
186
+ def actual_width(width)
187
+ if width < minimum_column_width
188
+ minimum_column_width
189
+ else
190
+ width.floor
191
+ end
192
+ end
193
+
194
+
195
+ def row(*values)
196
+ write format_row(*values)
197
+ end
198
+
199
+
200
+ # aligns a cell based on the specification
201
+ def align_cell(column_index, value, width)
202
+ case @column_alignment[column_index]
203
+ when :left
204
+ value.visual_ljust(width)
205
+
206
+ when :right
207
+ value.visual_rjust(width)
208
+
209
+ when :center
210
+ value.visual_center(width)
211
+ end
212
+ end
213
+
214
+
215
+ # formats a new row
216
+ def format_row(*values)
217
+
218
+ # check if the output width has changed
219
+ if allow_resizing and output_width == :automatic
220
+ current_width = TerminalInfo.width
221
+ if current_width != output_width
222
+ output_width = current_width
223
+ end
224
+ end
225
+
226
+ line = ""
227
+
228
+ # dump out the row
229
+ values.each_with_index do |cell,index|
230
+ cell_width = @absolute_column_widths[index]
231
+ line << horizontal_divider_piece
232
+ line << align_cell(index, cell.to_s.cabbrev(cell_width), cell_width)
233
+ end
234
+ line << horizontal_divider_piece
235
+ line << row_divider
236
+
237
+ line
238
+ end
239
+
240
+
241
+ def row_divider
242
+ if vertical_divider_piece == nil
243
+ return ''
244
+ end
245
+
246
+ line = ""
247
+ line << corner_piece
248
+ @absolute_column_widths.each do |width|
249
+ line << vertical_divider_piece * width
250
+ line << corner_piece
251
+ end
252
+
253
+ line
254
+ end
255
+
256
+
257
+ # outputs an already formatted line. Eventually this will allow writing to
258
+ # strings and such; but for now just an alias for #puts
259
+ def write(line)
260
+ puts line
261
+ end
262
+
263
+
264
+ # print a divider for the entire length of the grid
265
+ # optionally a function or Proc may be specified for processing the divider
266
+ # (to change it's color or weight, for example)
267
+ def divider(character = '=', processor = nil)
268
+ div = character * output_width
269
+
270
+ if processor
271
+ write processor.call(div)
272
+ else
273
+ write div
274
+ end
275
+ end
276
+ end
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # File:: DynamicClassMethods.rb
3
3
  # Author:: wkm
4
- # Copyright:: 2009
5
- # License:: GPL
4
+ # Copyright:: 2009, Zanoccio LLC.
5
+ # License:: GPL version 2.0 (see LICENSE.rb)
6
6
  #
7
7
  # Adds a #meta_def function to Object so we can programmatically define class
8
8
  # methods.
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # File:: FileComparison.rb
3
3
  # Author:: wkm
4
- # Copyright:: 2009
5
- # License:: GPL
4
+ # Copyright:: 2009, Zanoccio LLC.
5
+ # License:: GPL version 2.0 (see LICENSE.rb)
6
6
  #
7
7
  # Adds File.equivalent? that tries to guess whether two files are equivalent
8
8
  #
@@ -0,0 +1,94 @@
1
+ #
2
+ # File:: FileTree.rb
3
+ # Author:: wkm
4
+ # Copyright:: 2009, Zanoccio LLC.
5
+ # License:: GPL version 2.0 (see LICENSE.rb)
6
+ #
7
+ # A FileTree is a generator designed to very quickly create large directory
8
+ # and file structures.
9
+ #
10
+
11
+ class FileTree
12
+
13
+ def initialize(base_path = :automatic)
14
+ if base_path == :automatic
15
+ @base_path = Dir.pwd
16
+ else
17
+ @base_path = base_path
18
+ end
19
+
20
+ # create the directory if it doesn't exist
21
+ unless File.directory?(base_path)
22
+ Dir.mkdir(base_path)
23
+ end
24
+
25
+ # initialize our file tree
26
+ refresh_tree
27
+ end
28
+
29
+
30
+ def refresh_tree
31
+ @directory_hash = {}
32
+ @file_hash = {}
33
+
34
+ top_level_contents = Dir[File.join(@base_path, '*')]
35
+
36
+ top_level_contents.each do |handle|
37
+ if File.directory?(handle)
38
+ @directory_hash[handle] = FileTree.new(handle)
39
+ else
40
+ @file_hash[handle] = true
41
+ end
42
+ end
43
+ end
44
+
45
+
46
+ # gives true if the directory exists at this level of the FileTree
47
+ def has_directory?(name)
48
+ @directory_hash[name] == nil
49
+ end
50
+
51
+
52
+ # creates the given directory if it doesn't exist and returns a
53
+ # FileTree for it
54
+ def create_directory(name)
55
+ full_name = File.join(@base_path, name)
56
+ res = @directory_hash[full_name]
57
+ if res != nil
58
+ return res
59
+ else
60
+ Dir.mkdir(full_name)
61
+ @directory_hash[name] = FileTree.new(full_name)
62
+ end
63
+ end
64
+
65
+
66
+ # creates the file at this level of the file tree if it doesn't exist
67
+ def create_file(name)
68
+ full_name = File.join(@base_path, name)
69
+ if File.exists?(full_name)
70
+ return full_name
71
+ else
72
+ File.new(full_name)
73
+ end
74
+ end
75
+
76
+
77
+ # creates a path to the given file but doesn't create the actual file
78
+ def create_path(name)
79
+ components = File.dirname(name).split(File::SEPARATOR)
80
+
81
+ tld = self
82
+ components.each do |part|
83
+ tld = tld.create_directory(part)
84
+ end
85
+ end
86
+
87
+
88
+ # finds the file if it exists, otherwise creates all the necessary
89
+ # parent directories for the file and gives back the file name
90
+ def get_file(name)
91
+ create_path(name)
92
+ File.join(@base_path, name)
93
+ end
94
+ end
@@ -1,8 +1,8 @@
1
1
  #
2
2
  # File:: Silently.rb
3
3
  # Author:: wkm
4
- # Copyright:: 2009
5
- # License:: GPL
4
+ # Copyright:: 2009, Zanoccio LLC.
5
+ # License:: GPL version 2.0 (see LICENSE.rb)
6
6
  #
7
7
  # Implements a silently method for executing code without warnings; intended for
8
8
  # wrapping around require statements
@@ -1,49 +1,93 @@
1
1
  #
2
2
  # File:: StringFormatting.rb
3
3
  # Author:: wkm
4
- # Copyright:: 2009
5
- # License:: GPL
4
+ # Copyright:: 2009, Zanoccio LLC.
5
+ # License:: GPL version 2.0 (see LICENSE.rb)
6
6
  #
7
- # Adds String#cabbrev for abbreviating strings
7
+ # Adds String#cabbrev for abbreviating strings. Note that this function
8
+ # correctly supports ANSI sequences in strings (ie. it ignores them when
9
+ # computing sizes)
8
10
  #
11
+ # Adds String#align for stripping leading whitespace from multiple lines in
12
+ # a string.
13
+ #
14
+
15
+ require 'term/ansicolor'
16
+
17
+ include Term::ANSIColor
9
18
 
10
19
  class String
11
20
 
21
+ # gives the apparent length of the string (ignoring ASCII sequences)
22
+ def visual_length
23
+ uncolored.length
24
+ end
25
+
26
+
27
+ # gives the difference between the actual and apparent length of the string
28
+ def visual_length_delta
29
+ length - visual_length
30
+ end
31
+
32
+
33
+ # like #ljust but uses #visual_length for proper ANSI sequence handling
34
+ def visual_ljust(width, padding=" ")
35
+ ljust(width + visual_length_delta, padding)
36
+ end
37
+
38
+
39
+ # like #rjust but uses #visual_length for proper ANSI sequence handling
40
+ def visual_rjust(width, padding=" ")
41
+ rjust(width + visual_length_delta, padding)
42
+ end
43
+
44
+
45
+ # like #center but uses #visual_length for proper ANSI sequence handling
46
+ def visual_center(width, padding=" ")
47
+ center(width + visual_length_delta, padding)
48
+ end
49
+
50
+
12
51
  # gives an abbreviated form of a string, showing some of the beginning
13
52
  # and some of the end.
14
53
  #
15
54
  # "the quick brown dog".cabbrev 12 # => "the q... dog"
16
55
  def cabbrev(len)
17
- if length <= len
56
+ real_length = uncolored.length
57
+ if real_length <= len
18
58
  self
19
59
  else
20
- self[0..(len/2-2).floor] + "..." + self[(length - len/2+2) .. (length)]
60
+ self[0..(len/2-2).floor] + "..." + self[(real_length - len/2+2) .. (real_length)]
21
61
  end
22
62
  end
23
63
 
64
+
24
65
  # gives an abbreviated form of the string, showing as much of the beginning
25
66
  # as possible
26
67
  #
27
68
  # "the quick brown dog".labbrev 12 # => "the quick ..."
28
69
  def labbrev(len)
29
- if length <= len
70
+ if uncolored.length <= len
30
71
  self
31
72
  else
32
73
  self[0..(len-4)] + '...'
33
74
  end
34
75
  end
35
76
 
77
+
36
78
  # gives an abbreviated form of the string, showing as much of the end as
37
79
  # possible
38
80
  #
39
81
  # "the quick brown dog".rabbrev 12 # => "...brown dog"
40
82
  def rabbrev(len)
41
- if length <= len
83
+ real_length = uncolored.length
84
+ if real_length <= len
42
85
  self
43
86
  else
44
- '...' + self[(length - (len-3)) .. length]
87
+ '...' + self[(real_length - (len-3)) .. real_length]
45
88
  end
46
89
  end
90
+
47
91
 
48
92
  # removes leading whitespace from a set of lines, preserving indentation
49
93
  # relative to the first non-empty line