BuildMaster 0.7.0 → 0.8.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 (56) hide show
  1. data/README +26 -0
  2. data/lib/buildmaster.rb +2 -1
  3. data/lib/buildmaster/build_number_file.rb +27 -0
  4. data/lib/buildmaster/buildnumber +1 -0
  5. data/lib/buildmaster/file_processor.rb +114 -25
  6. data/lib/buildmaster/java_manifest.rb +4 -0
  7. data/lib/buildmaster/{site.rb → site/site.rb} +11 -46
  8. data/lib/buildmaster/site/template/buildmaster.css +340 -0
  9. data/lib/buildmaster/site/template/buildmaster_template.xml +130 -0
  10. data/lib/buildmaster/site/template_builder.rb +276 -0
  11. data/lib/buildmaster/site_server.rb +33 -0
  12. data/lib/buildmaster/site_spec.rb +74 -22
  13. data/lib/buildmaster/site_tester.rb +14 -2
  14. data/lib/buildmaster/source_content.rb +11 -0
  15. data/lib/buildmaster/source_file_handler.rb +7 -2
  16. data/lib/buildmaster/svn_driver.rb +23 -11
  17. data/lib/buildmaster/template_exception.rb +8 -0
  18. data/lib/buildmaster/template_runner.rb +19 -86
  19. data/lib/buildmaster/templatelets.rb +23 -0
  20. data/lib/buildmaster/templatelets/attribute.rb +16 -0
  21. data/lib/buildmaster/templatelets/each.rb +43 -0
  22. data/lib/buildmaster/templatelets/href.rb +39 -0
  23. data/lib/buildmaster/templatelets/include.rb +30 -0
  24. data/lib/buildmaster/templatelets/link.rb +41 -0
  25. data/lib/buildmaster/templatelets/text.rb +14 -0
  26. data/lib/buildmaster/templatelets/when.rb +24 -0
  27. data/lib/buildmaster/tree_to_object.rb +76 -0
  28. data/lib/buildmaster/xtemplate.rb +10 -11
  29. data/test/buildmaster/manifest.mf +1 -1
  30. data/test/buildmaster/{content → site/content}/index.html +0 -0
  31. data/test/buildmaster/site/content/markdown.markdown +0 -0
  32. data/test/buildmaster/site/content/textile.textile +0 -0
  33. data/test/buildmaster/{tc_site.rb → site/tc_site.rb} +1 -1
  34. data/test/buildmaster/site/tc_template_builder.rb +128 -0
  35. data/test/buildmaster/tc_build_number_file.rb +31 -0
  36. data/test/buildmaster/tc_file_processor.rb +81 -14
  37. data/test/buildmaster/tc_site_spec.rb +26 -42
  38. data/test/buildmaster/tc_source_file_handler.rb +55 -0
  39. data/test/buildmaster/tc_template_runner.rb +42 -1
  40. data/test/buildmaster/tc_tree_to_object.rb +120 -0
  41. data/test/buildmaster/tc_xtemplate.rb +13 -233
  42. data/test/buildmaster/templatelets/common_templatelet_test.rb +27 -0
  43. data/test/buildmaster/templatelets/tc_attribute.rb +57 -0
  44. data/test/buildmaster/templatelets/tc_each.rb +69 -0
  45. data/test/buildmaster/templatelets/tc_href.rb +48 -0
  46. data/test/buildmaster/templatelets/tc_include.rb +34 -0
  47. data/test/buildmaster/templatelets/tc_link.rb +70 -0
  48. data/test/buildmaster/templatelets/tc_text.rb +36 -0
  49. data/test/buildmaster/templatelets/tc_when.rb +59 -0
  50. data/test/buildmaster/ts_site.rb +4 -0
  51. data/test/buildmaster/ts_templatelets.rb +10 -0
  52. data/test/tmp/output/index.html +8 -0
  53. data/test/tmp/output/markdown.html +8 -0
  54. data/test/tmp/output/textile.html +8 -0
  55. data/test/ts_buildmaster.rb +15 -3
  56. metadata +102 -53
@@ -2,6 +2,7 @@ module BuildMaster
2
2
 
3
3
  require 'watir'
4
4
  require 'set'
5
+ require 'uri'
5
6
 
6
7
  class SiteTester
7
8
  URL_PATTERN = /^https?\:\/\/([^\/]*)/
@@ -44,10 +45,9 @@ class SiteTester
44
45
  end
45
46
 
46
47
  def check_page
47
- if (@visited_pages.include?(@ie.url))
48
+ if (url_visited?(@ie.url))
48
49
  return
49
50
  end
50
- @visited_pages.add(@ie.url)
51
51
  check_links
52
52
  errors = @errors[@ie.url]
53
53
  if (errors && errors.length > 0)
@@ -55,6 +55,18 @@ class SiteTester
55
55
  end
56
56
  end
57
57
 
58
+ def url_visited?(url)
59
+ index = url.index('#')
60
+ if (index)
61
+ url = url[0, index]
62
+ end
63
+ if (@visited_pages.include?(url))
64
+ return true
65
+ end
66
+ @visited_pages.add(url)
67
+ return false
68
+ end
69
+
58
70
  def check_links
59
71
  current = @ie.url
60
72
  @ie.links.each do |link|
@@ -0,0 +1,11 @@
1
+ module BuildMaster
2
+ class SourceContent
3
+ attr_reader :path, :document
4
+
5
+ def initialize(path, document)
6
+ @path = path
7
+ @document = document
8
+ end
9
+
10
+ end
11
+ end
@@ -27,15 +27,20 @@ class SourceFileHandler < WEBrick::HTTPServlet::AbstractServlet
27
27
  path = "#{path}index.html"
28
28
  extension = '.html'
29
29
  end
30
- if (extension.casecmp('.html') == 0)
30
+ file_processor = FileProcessor.for_request_path(path, @spec)
31
+ if (file_processor.is_html?)
31
32
  begin
32
- serve_generated_file(path[0, path.length - 5], req, res)
33
+ content = file_processor.generate_document.to_s
33
34
  rescue Exception
34
35
  @logger.error("error serving the file #{path}")
35
36
  @logger.error($!)
36
37
  raise WEBrick::HTTPStatus::InternalServerError,
37
38
  "#{$!}", caller
38
39
  end
40
+ res['content-type'] = 'text/html'
41
+ res['content-length'] = content.length
42
+ res['last-modified'] = DateTime.new
43
+ res.body = content
39
44
  else
40
45
  @delegate.service(req, res)
41
46
  end
@@ -1,21 +1,33 @@
1
+ require 'stringio'
1
2
  require 'rexml/document'
2
3
 
3
4
  module BuildMaster
4
5
 
5
6
  class SvnInfo
6
- attr_reader :path, :repository_root
7
-
8
- def initialize(path)
9
- @path = path
10
- analyze_entry_file(File.join(path, ".svn", "entries"))
7
+ attr_reader :path, :repository_root
8
+
9
+ def initialize(path)
10
+ @path = path
11
+ analyze_entry_file(File.join(path, ".svn", "entries"))
12
+ end
13
+
14
+ def analyze_entry_file(path)
15
+ content = load_content(path)
16
+ xml = REXML::Document.new(content)
17
+ xml.root.each_element_with_attribute('name', '', 1) do |element|
18
+ @repository_root = element.attributes['repos']
11
19
  end
12
-
13
- def analyze_entry_file(file)
14
- xml = REXML::Document.new(File.open(file))
15
- xml.root.each_element_with_attribute('name', '', 1) do |element|
16
- @repository_root = element.attributes['repos']
17
- end
20
+ end
21
+
22
+ def load_content(path)
23
+ buffer = StringIO.new
24
+ File.open(path, 'r') do |file|
25
+ while (line = file.gets)
26
+ buffer.puts(line)
27
+ end
18
28
  end
29
+ return buffer.string
30
+ end
19
31
  end
20
32
 
21
33
  class SvnDriver
@@ -0,0 +1,8 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ module BuildMaster
4
+
5
+ class TemplateException < Exception
6
+ end
7
+
8
+ end
@@ -1,16 +1,24 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'template_exception'
4
+
1
5
  module BuildMaster
2
6
  class TemplateRunner
3
- BuildMaster::NAMESPACE = "http://buildmaster.rubyforge.org/xtemplate/1.0"
7
+ @@NAMESPACE = 'http://buildmaster.rubyforge.org/xtemplate/1.0'
8
+ attr_reader :templatelets
9
+ attr_writer :templatelets
4
10
 
5
- def initialize(result, template, source, &evaluator)
6
- @result = result
11
+ def initialize(target, template, source, &evaluator)
12
+ @templatelets = Hash.new
13
+ @target = target
7
14
  @template = template
8
- @source = source
15
+ @source_instance = source
16
+ @templatelets = templatelets
9
17
  @evaluator = evaluator
10
18
  end
11
19
 
12
20
  def process
13
- process_children(@result, @template)
21
+ process_children(@target, @template)
14
22
  end
15
23
 
16
24
  private
@@ -35,13 +43,16 @@ module BuildMaster
35
43
  end
36
44
 
37
45
  def template_directive?(element)
38
- element.namespace == NAMESPACE
46
+ element.namespace == @@NAMESPACE
39
47
  end
40
48
 
41
49
  def process_directive(target, template_element)
42
50
  message = "process_#{template_element.name}_directive"
43
- raise TemplateException, "unable to process element template:#{template_element.name}" unless respond_to?(message, true)
44
- send(message, target, template_element)
51
+ templatelet = @templatelets[template_element.name]
52
+ if (not templatelet)
53
+ raise TemplateException, "unable to process element template:#{template_element.name}"
54
+ end
55
+ templatelet.process(target, template_element, @source_instance)
45
56
  end
46
57
 
47
58
  def clone_element( template_element )
@@ -64,83 +75,5 @@ module BuildMaster
64
75
  end
65
76
  end
66
77
 
67
- def process_include_directive(target_element, template_element)
68
- elements_attribute = template_element.attributes["elements"]
69
- if (elements_attribute)
70
- REXML::XPath.match(@source, elements_attribute).each do |matched|
71
- target_element.add(deep_clone(matched))
72
- end
73
- return
74
- end
75
- end
76
-
77
- def process_when_directive(target_element, template_element)
78
- if evaluate(template_element, 'test')
79
- process_children(target_element, template_element)
80
- end
81
- end
82
-
83
- def process_attribute_directive(target_element, template_element)
84
- name = template_element.attributes['name']
85
- target_element.attributes[name]=evaluate(template_element, 'eval')
86
- end
87
-
88
- def process_text_directive(target_element, template_element)
89
- target_element.add(REXML::Text.new(evaluate(template_element, 'eval')))
90
- end
91
-
92
- def process_each_directive(target_element, template_element)
93
- source_xml = evaluate!(template_element, 'source')
94
- matched_element = REXML::XPath.match(REXML::Document.new(source_xml), template_element.attributes['select'])
95
- count = attribute!(template_element, 'count')
96
- count.to_i.times do |i|
97
- TemplateRunner.new(target_element, template_element, matched_element[i], &@evaluator).process
98
- end
99
- end
100
-
101
- def process_link_directive(target_element, template_element)
102
- current_path = @evaluator.call('relative_to_root')
103
- file_name = current_path.basename(current_path.extname).to_s + ".html"
104
- current_html_path = current_path.parent().join(file_name)
105
- href = Pathname.new(attribute!(template_element, 'href'))
106
- if (href.absolute?)
107
- href = href.relative_path_from(Pathname.new('/'))
108
- end
109
- anchor_or_div = nil
110
- if (current_html_path == href)
111
- anchor_or_div = REXML::Element.new('div')
112
- anchor_or_div.attributes['class']='current'
113
- else
114
- anchor_or_div = REXML::Element.new('a')
115
- anchor_or_div.attributes['href'] = href.relative_path_from(current_html_path.parent())
116
- end
117
- template_element.attributes.each do |name, value|
118
- anchor_or_div.attributes[name] = value unless name == 'href'
119
- end
120
- process_children(anchor_or_div, template_element)
121
- target_element.add(anchor_or_div)
122
- end
123
-
124
- def evaluate!(xml_element, attribute_name)
125
- value = evaluate(xml_element, attribute_name)
126
- message = xml_element.attributes[attribute_name]
127
- if (not value)
128
- raise TemplateException, "#{message} from attribute #{attribute_name} cannot be nil"
129
- end
130
- return value
131
- end
132
-
133
- def evaluate(xml_element, attribute_name)
134
- message = attribute!(xml_element, attribute_name)
135
- return @evaluator.call(message)
136
- end
137
-
138
- def attribute!(xml_element, attribute_name)
139
- value = xml_element.attributes[attribute_name]
140
- if (not value)
141
- raise TemplateException, "attribute #{attribute_name} not found in #{xml_element}"
142
- end
143
- return value
144
- end
145
78
  end
146
79
  end
@@ -0,0 +1,23 @@
1
+ $:.unshift(File.dirname(__FILE__))
2
+
3
+ require 'templatelets/href'
4
+ require 'templatelets/attribute'
5
+ require 'templatelets/each'
6
+ require 'templatelets/include'
7
+ require 'templatelets/link'
8
+ require 'templatelets/text'
9
+ require 'templatelets/when'
10
+
11
+ module REXML
12
+ class Element
13
+ def attribute_value!(name)
14
+ value = attribute_value(name)
15
+ raise "attribute #{name} not found" unless value
16
+ return value
17
+ end
18
+
19
+ def attribute_value(name)
20
+ return attributes[name]
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ module BuildMaster
2
+ class Attribute
3
+ def initialize(expression_evaluator)
4
+ @evaluator = expression_evaluator
5
+ end
6
+
7
+ def process(target, template, source)
8
+ name = template.attribute_value!('name')
9
+ eval = template.attribute_value!('eval')
10
+ if (not @evaluator.respond_to?(eval))
11
+ raise TemplateException, '#{@evaluator.class} cannot evaluate expression #{eval}'
12
+ end
13
+ target.attributes[name] = @evaluator.send(eval, source.path)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,43 @@
1
+ require 'uri'
2
+ require 'open-uri'
3
+
4
+ module BuildMaster
5
+ class Each
6
+ def initialize(site_spec)
7
+ @site_spec = site_spec
8
+ end
9
+
10
+ def process(target, template, source)
11
+ source_xml = load_source_xml(template)
12
+ matched_element = REXML::XPath.match(source_xml, template.attribute_value!('select'))
13
+ count = template.attribute_value!('count')
14
+ count.to_i.times do |i|
15
+ element_source = SourceContent.new(source.path, matched_element[i])
16
+ template_runner = TemplateRunner.new(target, template, element_source)
17
+ template_runner.templatelets = @site_spec.load_templatelets
18
+ template_runner.process
19
+ end
20
+ end
21
+
22
+ private
23
+ def load_source_xml(template)
24
+ path = template.attribute_value!('source')
25
+ if (URI.parse(path).scheme.nil?)
26
+ return @site_spec.load_document(path)
27
+ end
28
+ return load_content_through_uri(path)
29
+ end
30
+
31
+ def load_content_through_uri(uri)
32
+ buffer = StringIO.new
33
+ begin
34
+ open(uri) do |file|
35
+ buffer.puts file.gets
36
+ end
37
+ return REXML::Document.new(buffer.string)
38
+ rescue Exception => exception
39
+ raise RuntimeError, "Error loading uri: #{uri}", caller
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,39 @@
1
+ $:.unshift(File.join('..', File.dirname(__FILE__)))
2
+
3
+ require 'uri'
4
+
5
+ require 'template_exception'
6
+ require 'template_runner'
7
+
8
+ module BuildMaster
9
+
10
+ class Href
11
+ def initialize(site_spec)
12
+ @site_spec = site_spec
13
+ end
14
+
15
+ def process(target, template, source)
16
+ url = template.attribute_value!('url')
17
+ href = construct_href(url, source.path)
18
+ target.attributes[name_based_on_target(target)] = href
19
+ end
20
+
21
+ private
22
+ def construct_href(url, current_path)
23
+ href = url
24
+ if (URI.parse(url).scheme.nil?)
25
+ href = Pathname.new(url).relative_path_from(current_path.parent)
26
+ end
27
+ return href
28
+ end
29
+
30
+ def name_based_on_target(target)
31
+ name = target.name
32
+ if (name == 'img')
33
+ return 'src'
34
+ else
35
+ return 'href'
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+
2
+ module BuildMaster
3
+ class Include
4
+ def initialize(site_spec)
5
+ @site_spec = site_spec
6
+ end
7
+
8
+ def process(target, template, source)
9
+ elements_xpath = template.attribute_value!('elements')
10
+ if (elements_xpath[elements_xpath.length - 1, 1] == '*')
11
+ elements_xpath = elements_xpath[0, elements_xpath.length - 1]
12
+ REXML::XPath.each(source.document, elements_xpath) do |matched|
13
+ matched.each_child {|child| target.add(deep_clone(child))}
14
+ end
15
+ else
16
+ REXML::XPath.each(source.document, elements_xpath) {|matched| target.add(deep_clone(matched))}
17
+ end
18
+ end
19
+
20
+ private
21
+ def deep_clone(node )
22
+ if node.kind_of? REXML::Parent
23
+ node.deep_clone
24
+ else
25
+ node.clone
26
+ end
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,41 @@
1
+ require 'rexml/element'
2
+
3
+ module BuildMaster
4
+ class Link
5
+ def initialize(site_spec)
6
+ @site_spec = site_spec
7
+ end
8
+
9
+ def process(target, template, source)
10
+ target_path = get_href_as_relative_path(template)
11
+ result = nil
12
+ if (target_path == source.path)
13
+ result = REXML::Element.new('div')
14
+ result.attributes['class'] = 'current'
15
+ else
16
+ result = REXML::Element.new('a')
17
+ href = target_path.relative_path_from(source.path.parent)
18
+ result.attributes['href'] = href.to_s
19
+ end
20
+ template.attributes.each do |name, value|
21
+ result.attributes[name] = value unless name == 'href'
22
+ end
23
+ template.each_child do |element|
24
+ runner = TemplateRunner.new(result, template, source)
25
+ runner.templatelets = @site_spec.load_templatelets
26
+ runner.process
27
+ end
28
+ target.add(result)
29
+ end
30
+
31
+ private
32
+ def get_href_as_relative_path(template)
33
+ href = Pathname.new(template.attribute_value!('href'))
34
+ if (href.absolute?)
35
+ href = href.relative_path_from(Pathname.new('/'))
36
+ end
37
+ return href
38
+ end
39
+
40
+ end
41
+ end