BuildMaster 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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