teapot 0.7.1 → 0.7.2

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NjhkODU0M2VmNzc4OWQwMGQzNGYyZTU4MzM0NTBjMWU1MTMxYmRjNg==
4
+ ZTQyYjk5NWYwZDFhYTJiMmZjOWEzYmE3MGY2ODM2YTBhM2I5NTU2Ng==
5
5
  data.tar.gz: !binary |-
6
- MmFiZDE4M2VlNGJkNzgyYWY4MDk4ZDI1YjMzNmJlNjZhZDJjY2Q5Mg==
6
+ N2NhM2YzMWViNGNjMGVkNWZlMjZmNDMxNzM2NDNhMWU0N2Y5ZmQ4ZQ==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- Y2ExNjk4YzUwM2UyM2QxYTYyOWIzZWQ2OTVlOGQyYWU0NTk4MTU3MWNlMDQ4
10
- NTczNDgyZTA5YjdmNTljYTQ0MTM4ZTRmMzA1NjAyMzVjY2IzZWRmNGEyODVj
11
- MmE3ZjU5ZjAyZDVmNWQwMjc0MmNkNWQzMjE4NzAwODg1NGZlZWY=
9
+ OTRmYmYzN2M4YzRhYmJmMGE5MTY0ZDdlYmI1MGQyMjRhZWYxMzQ2OTg3ODQx
10
+ ODg3ZTFhYWE2NDBkNzcwYTYzNzlmODRlNGQ2ZTZkYWJiZGE5OTc0ZWQ4N2Yz
11
+ Njk0YjYzNzliMjkyZDdmNDE1NGZjZmM1MThmNWZjZmQ3OWRlMjk=
12
12
  data.tar.gz: !binary |-
13
- ZjRlOTE3MmIxOGYxY2ZiZmI0MTg1N2RjZWRjODM5MzRmMGM2MzMyN2YwZDk5
14
- MzYwM2E1YWQ2NjY0ZDg3YjY2MmYxYjEyMDNlNTFiNDkwNjVjMTY0OTQxOTcx
15
- ZTRlYmE1ZmVjYzFjNmMxZWRkMjFlMzhjNjg1ZDAyZDE3MGYwN2I=
13
+ NmNjMGYyNjlkNTY4YmI5YmI5YmI3YmIzYWJiNTRiODFlMzc2M2U0MmYwOWQ2
14
+ MmI0ZTM2N2M3NTE2ZjFiYWE1NWJmYTlkMzdlZTIyNDUxYTM2MzIwYmFlMThk
15
+ MzUwYjU0ZDBjMTdkZjMwNDhiMzdmM2E1NzAyNzA1YmJiODAxNmE=
@@ -59,7 +59,7 @@ module Teapot
59
59
  @parts.each do |path|
60
60
  full_path = @root + path
61
61
 
62
- FileUtils.cp_r(full_path.children, source_path.to_s)
62
+ FileUtils.cp_r(full_path.children, source_path.to_s, :preserve => true)
63
63
  end
64
64
 
65
65
  return source_path
@@ -58,7 +58,7 @@ module Teapot
58
58
  destination_path.dirname.mkpath
59
59
 
60
60
  # Copy the file to the destination:
61
- FileUtils.cp path, destination_path
61
+ FileUtils.cp(path, destination_path, :preserve => true)
62
62
  end
63
63
  end
64
64
  end
@@ -0,0 +1,50 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'pathname'
22
+
23
+ require 'teapot/graph'
24
+ require 'teapot/extractors/preprocessor_extractor'
25
+
26
+ module Teapot
27
+ module Build
28
+ @@graphs = {}
29
+
30
+ def self.dependency_graph(environment)
31
+ @@graphs.fetch(environment) do
32
+ graph = Graph.new
33
+
34
+ buildflags = environment[:buildflags]
35
+ roots = Extractors::PreprocessorExtractor.include_directories(buildflags)
36
+
37
+ # At some point, it would be nice if this process could be driven by environment configuration:
38
+ patterns = [
39
+ /\.c(c|pp)?$/,
40
+ /\.h(pp)?$/,
41
+ /\.mm?/
42
+ ]
43
+
44
+ graph.extractors << Extractors::PreprocessorExtractor.new(patterns, roots)
45
+
46
+ @@graphs[environment] = graph
47
+ end
48
+ end
49
+ end
50
+ end
@@ -56,21 +56,21 @@ module Teapot
56
56
 
57
57
  return instance
58
58
  end
59
-
59
+
60
60
  def execute(command, environment, *arguments)
61
61
  if @configure
62
62
  environment = environment.merge &@configure
63
63
  end
64
-
64
+
65
65
  # Flatten the environment to a hash:
66
- values = environment.flatten
67
-
66
+ flat_environment = environment.flatten
67
+
68
68
  puts "Performing #{self.class}/#{command} for #{root}...".color(:cyan)
69
-
69
+
70
70
  # Show the environment to the user:
71
- Environment::System::dump(values)
72
-
73
- self.send(command, values, *arguments)
71
+ Environment::System::dump(flat_environment)
72
+
73
+ self.send(command, flat_environment, *arguments)
74
74
  end
75
75
  end
76
76
  end
@@ -20,6 +20,8 @@
20
20
 
21
21
  require 'pathname'
22
22
 
23
+ require 'teapot/build/graph'
24
+
23
25
  module Teapot
24
26
  module Build
25
27
  module Targets
@@ -40,12 +42,13 @@ module Teapot
40
42
  return prefix
41
43
  end
42
44
 
43
- def compile(environment, root, source_file, commands)
44
- object_file = (build_prefix!(environment) + source_file).sub_ext('.o')
45
-
45
+ def compile!(environment, root, source_file, object_file, commands)
46
46
  # Ensure there is a directory for the output file:
47
47
  object_file.dirname.mkpath
48
-
48
+
49
+ # Make sure there is no pre-existing object file
50
+ object_file.rmtree if object_file.exist?
51
+
49
52
  case source_file.extname
50
53
  when ".cpp", ".mm"
51
54
  commands.run(
@@ -60,8 +63,19 @@ module Teapot
60
63
  "-c", root + source_file, "-o", object_file
61
64
  )
62
65
  end
63
-
64
- return Array object_file
66
+ end
67
+
68
+ def compile(environment, root, source_file, commands)
69
+ object_file = (build_prefix!(environment) + source_file).sub_ext('.o')
70
+
71
+ # The graph is recreated once per file. This could be improved.
72
+ graph = Build::dependency_graph(environment)
73
+
74
+ if graph.regenerate?(object_file, root + source_file)
75
+ compile!(environment, root, source_file, object_file, commands)
76
+ end
77
+
78
+ return object_file
65
79
  end
66
80
  end
67
81
  end
@@ -31,13 +31,17 @@ module Teapot
31
31
  def link(environment, objects)
32
32
  executable_file = link_prefix!(environment) + @name
33
33
 
34
- Commands.run(
35
- environment[:cxx],
36
- environment[:cxxflags],
37
- "-o", executable_file, objects,
38
- environment[:ldflags]
39
- )
40
-
34
+ graph = Build::dependency_graph(environment)
35
+
36
+ if graph.regenerate?(executable_file, objects)
37
+ Commands.run(
38
+ environment[:cxx],
39
+ environment[:cxxflags],
40
+ "-o", executable_file, objects,
41
+ environment[:ldflags]
42
+ )
43
+ end
44
+
41
45
  return executable_file
42
46
  end
43
47
  end
@@ -58,7 +58,7 @@ module Teapot
58
58
  if !build_source_path.exist?
59
59
  build_source_path.mkpath
60
60
 
61
- FileUtils.cp_r(source_path.children, build_source_path.to_s)
61
+ FileUtils.cp_r(source_path.children, build_source_path.to_s, :preserve => true)
62
62
 
63
63
  # Write the environment checksum out to a file:
64
64
  File.write(build_source_checksum_path, checksum(values))
@@ -23,6 +23,8 @@ require 'teapot/build/targets/directory'
23
23
  require 'teapot/build/targets/files'
24
24
  require 'teapot/build/targets/compiler'
25
25
 
26
+ require 'teapot/build/graph'
27
+
26
28
  require 'fileutils'
27
29
 
28
30
  module Teapot
@@ -48,8 +50,12 @@ module Teapot
48
50
  def link(environment, objects)
49
51
  library_file = link_prefix!(environment) + "lib#{@name}.a"
50
52
 
51
- Linker.link_static(environment, library_file, objects)
52
-
53
+ graph = Build::dependency_graph(environment)
54
+
55
+ if graph.regenerate?(library_file, objects)
56
+ Linker.link_static(environment, library_file, objects)
57
+ end
58
+
53
59
  return library_file
54
60
  end
55
61
 
@@ -75,7 +81,7 @@ module Teapot
75
81
  destination_path = prefix + file_list.prefix + relative_path
76
82
 
77
83
  destination_path.dirname.mkpath
78
- FileUtils.cp path, destination_path
84
+ FileUtils.cp(path, destination_path, :preserve => true)
79
85
  end
80
86
  end
81
87
 
@@ -87,7 +93,7 @@ module Teapot
87
93
 
88
94
  destination_path.dirname.mkpath
89
95
 
90
- FileUtils.cp path, destination_path
96
+ FileUtils.cp(path, destination_path, :preserve => true)
91
97
  end
92
98
 
93
99
  if self.respond_to? :headers
@@ -39,7 +39,7 @@ module Teapot
39
39
  if @parent
40
40
  @parent.flatten_to_hash(hash)
41
41
  end
42
-
42
+
43
43
  @values.each do |key, value|
44
44
  previous = hash[key]
45
45
 
@@ -57,6 +57,5 @@ module Teapot
57
57
  end
58
58
  end
59
59
  end
60
-
61
60
  end
62
61
  end
@@ -0,0 +1,62 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'teapot/graph'
22
+
23
+ module Teapot
24
+ module Extractors
25
+ class PreprocessorExtractor < Graph::Extractor
26
+ def self.include_directories(flags)
27
+ roots = []
28
+
29
+ # Extract include directories:
30
+ flags.each do |option|
31
+ if option.to_s =~ /^-I(.+)/
32
+ roots << Pathname($1)
33
+ end
34
+ end
35
+
36
+ return roots
37
+ end
38
+
39
+ def initialize(patterns, roots = [])
40
+ super patterns
41
+
42
+ @roots = roots
43
+ end
44
+
45
+ def extract(path)
46
+ local_root = Pathname(path).dirname
47
+
48
+ File.open(path).each do |line|
49
+ if line =~ /\#(?:include|import) "(.*?)"/
50
+ path = local_root + $1
51
+
52
+ yield path if path.exist?
53
+ elsif line =~ /\#(?:include|import) \<(.*?)\>/
54
+ path = @roots.collect{|root| root+$1}.find{|path| path.exist?}
55
+
56
+ yield path if path
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,134 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'set'
22
+ require 'pathname'
23
+
24
+ module Teapot
25
+ class Graph
26
+ def initialize
27
+ @nodes = {}
28
+
29
+ @extractors = []
30
+ end
31
+
32
+ attr :root
33
+ attr :nodes
34
+ attr :extractors
35
+
36
+ def << node
37
+ @nodes[node.path] = node
38
+ end
39
+
40
+ def regenerate?(output_path, input_paths)
41
+ return true unless output_path.exist?
42
+
43
+ output_modified_time = output_path.mtime
44
+
45
+ Array(input_paths).each do |path|
46
+ node = fetch(path)
47
+
48
+ return true if node.changed_since?(output_modified_time)
49
+ end
50
+
51
+ return false
52
+ end
53
+
54
+ def extract(source_path)
55
+ dependencies = Set.new
56
+
57
+ @extractors.each do |extractor|
58
+ extractor.call(source_path) do |path|
59
+ dependencies << path
60
+ end
61
+ end
62
+
63
+ nodes = dependencies.map{|path| fetch(path)}
64
+ end
65
+
66
+ def fetch(path)
67
+ @nodes.fetch(path) do
68
+ node = @nodes[path] = Node.new(self, path)
69
+ node.extract_dependencies!
70
+
71
+ node
72
+ end
73
+ end
74
+
75
+ class Node
76
+ def initialize(graph, path)
77
+ @graph = graph
78
+
79
+ @path = Pathname(path)
80
+
81
+ @dependencies = []
82
+
83
+ @changed = nil
84
+ end
85
+
86
+ attr :path
87
+ attr :dependencies
88
+
89
+ def changed_since?(modified_time)
90
+ if @changed == nil
91
+ # If the file was modified in the future relative to old modified_time:
92
+ if @path.mtime > modified_time
93
+ puts "Changed: #{path.to_s.inspect}"
94
+ return @changed = true
95
+ else
96
+ @changed = false
97
+ end
98
+
99
+ # If any of the file's dependencies have changed relative to the old modified_time:
100
+ @dependencies.each do |dependency|
101
+ if dependency.changed_since?(modified_time)
102
+ return @changed = true
103
+ end
104
+ end
105
+ end
106
+
107
+ return @changed
108
+ end
109
+
110
+ def extract_dependencies!
111
+ @dependencies = @graph.extract(path)
112
+ end
113
+ end
114
+
115
+ class Extractor
116
+ def initialize(patterns = [])
117
+ @patterns = Array(patterns)
118
+ end
119
+
120
+ def extract(path)
121
+ end
122
+
123
+ def call(path, &block)
124
+ return unless path.exist?
125
+
126
+ basename = path.basename.to_s
127
+
128
+ if @patterns.find{|pattern| pattern.match(basename)}
129
+ extract(path, &block)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
@@ -19,5 +19,5 @@
19
19
  # THE SOFTWARE.
20
20
 
21
21
  module Teapot
22
- VERSION = "0.7.1"
22
+ VERSION = "0.7.2"
23
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teapot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-27 00:00:00.000000000 Z
11
+ date: 2013-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rainbow
@@ -86,6 +86,7 @@ files:
86
86
  - lib/teapot/build.rb
87
87
  - lib/teapot/build/component.rb
88
88
  - lib/teapot/build/file_list.rb
89
+ - lib/teapot/build/graph.rb
89
90
  - lib/teapot/build/linker.rb
90
91
  - lib/teapot/build/target.rb
91
92
  - lib/teapot/build/targets/application.rb
@@ -113,7 +114,9 @@ files:
113
114
  - lib/teapot/environment/evaluator.rb
114
115
  - lib/teapot/environment/flatten.rb
115
116
  - lib/teapot/environment/system.rb
117
+ - lib/teapot/extractors/preprocessor_extractor.rb
116
118
  - lib/teapot/generator.rb
119
+ - lib/teapot/graph.rb
117
120
  - lib/teapot/loader.rb
118
121
  - lib/teapot/name.rb
119
122
  - lib/teapot/package.rb