bake 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +7 -0
  6. data/Gemfile.lock +40 -0
  7. data/README.md +99 -0
  8. data/Rakefile +6 -0
  9. data/bake.gemspec +25 -0
  10. data/bin/bake +25 -10
  11. data/lib/bake.rb +21 -140
  12. data/lib/bake/book.rb +79 -0
  13. data/lib/bake/command.rb +29 -0
  14. data/lib/bake/command/invoke.rb +67 -0
  15. data/lib/bake/command/list.rb +76 -0
  16. data/lib/bake/command/top.rb +111 -0
  17. data/lib/bake/context.rb +103 -110
  18. data/lib/bake/loader.rb +82 -0
  19. data/lib/bake/loaders.rb +110 -0
  20. data/lib/bake/recipe.rb +109 -0
  21. data/lib/bake/version.rb +23 -0
  22. metadata +73 -85
  23. data/CHANGELOG +0 -38
  24. data/CONCEPTS +0 -54
  25. data/MIT-LICENSE +0 -21
  26. data/README +0 -38
  27. data/REFERENCE +0 -2
  28. data/TUTORIAL +0 -128
  29. data/lib/bake/addon.rb +0 -20
  30. data/lib/bake/configuration.rb +0 -126
  31. data/lib/bake/extensions.rb +0 -3
  32. data/lib/bake/extensions/class.rb +0 -11
  33. data/lib/bake/extensions/object.rb +0 -22
  34. data/lib/bake/extensions/string.rb +0 -22
  35. data/lib/bake/file_target.rb +0 -19
  36. data/lib/bake/plugin.rb +0 -49
  37. data/lib/bake/plugins/cpp.rb +0 -188
  38. data/lib/bake/plugins/cpp/darwin.rb +0 -26
  39. data/lib/bake/plugins/cpp/gcc.rb +0 -14
  40. data/lib/bake/plugins/cpp/gcc_toolset_base.rb +0 -101
  41. data/lib/bake/plugins/cpp/msvc.rb +0 -118
  42. data/lib/bake/plugins/cpp/qt.rb +0 -53
  43. data/lib/bake/plugins/cpp/toolset_base.rb +0 -56
  44. data/lib/bake/plugins/macro.rb +0 -18
  45. data/lib/bake/plugins/runner.rb +0 -40
  46. data/lib/bake/plugins/system.rb +0 -30
  47. data/lib/bake/project.rb +0 -91
  48. data/lib/bake/project_loader.rb +0 -116
  49. data/lib/bake/system_utils.rb +0 -42
  50. data/lib/bake/target.rb +0 -155
  51. data/lib/bake/toolset.rb +0 -25
  52. data/lib/bake_version.rb +0 -5
  53. data/test/test_bake.rb +0 -2
  54. data/test/test_configuration.rb +0 -58
@@ -0,0 +1,29 @@
1
+ # Copyright, 2020, 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_relative 'command/top'
22
+
23
+ module Bake
24
+ module Command
25
+ def self.call(*arguments)
26
+ Top.call(*arguments)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,67 @@
1
+ # Copyright, 2020, 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 'samovar'
22
+
23
+ require_relative '../loaders'
24
+ require_relative '../loader'
25
+ require_relative '../context'
26
+
27
+ module Bake
28
+ module Command
29
+ class Invoke < Samovar::Command
30
+ self.description = "Invoke one or more commands."
31
+
32
+ options do
33
+ option "-d/--describe", "Describe what will be done, but don't do it.", default: false
34
+ end
35
+
36
+ def bakefile
37
+ @parent.bakefile
38
+ end
39
+
40
+ def update_working_directory
41
+ if bakefile = self.bakefile
42
+ current_directory = Dir.pwd
43
+ working_directory = File.dirname(bakefile)
44
+
45
+ if working_directory != current_directory
46
+ Console.logger.debug(self) {"Changing working directory to #{working_directory.inspect}."}
47
+ Dir.chdir(working_directory)
48
+
49
+ return current_directory
50
+ end
51
+ end
52
+
53
+ return nil
54
+ end
55
+
56
+ many :commands, "The commands & arguments to invoke."
57
+
58
+ def call
59
+ context = @parent.context
60
+
61
+ self.update_working_directory
62
+
63
+ context.call(*@commands, **@options)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,76 @@
1
+ # Copyright, 2020, 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 'samovar'
22
+
23
+ module Bake
24
+ module Command
25
+ class List < Samovar::Command
26
+ def format_parameters(parameters, terminal)
27
+ parameters.each do |type, name|
28
+ case type
29
+ when :keyreq
30
+ name = "#{name}="
31
+ when :keyrest
32
+ name = "**options"
33
+ else
34
+ name = name.to_s
35
+ end
36
+
37
+ terminal.print(type, name, " ")
38
+ end
39
+ end
40
+
41
+ def format_recipe(recipe, terminal)
42
+ terminal.print(:command, recipe.command)
43
+
44
+ if parameters = recipe.parameters
45
+ terminal.write(" ")
46
+ format_parameters(parameters, terminal)
47
+ end
48
+ end
49
+
50
+ def call
51
+ terminal = @parent.terminal
52
+ context = @parent.context
53
+ format_recipe = self.method(:format_recipe).curry
54
+
55
+ unless context.empty?
56
+ terminal.print_line(:loader, context)
57
+
58
+ context.each do |recipe|
59
+ terminal.print_line("\t", format_recipe[recipe])
60
+ end
61
+ end
62
+
63
+ context.loaders.each do |loader|
64
+ terminal.print_line(:loader, loader)
65
+ loader.each do |path|
66
+ if book = loader.lookup(path)
67
+ book.each do |recipe|
68
+ terminal.print_line("\t", format_recipe[recipe])
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,111 @@
1
+ # Copyright, 2020, 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 'samovar'
22
+ require 'console/terminal'
23
+
24
+ require_relative 'invoke'
25
+ require_relative 'list'
26
+
27
+ module Bake
28
+ module Command
29
+ class Top < Samovar::Command
30
+ self.description = "Execute tasks using Ruby."
31
+
32
+ def self.bakefile_path(current = Dir.pwd)
33
+ while current
34
+ bakefile_path = File.join(current, "bake.rb")
35
+
36
+ if File.exist?(bakefile_path)
37
+ return bakefile_path
38
+ end
39
+
40
+ parent = File.dirname(current)
41
+
42
+ if current == parent
43
+ break
44
+ else
45
+ current = parent
46
+ end
47
+ end
48
+ end
49
+
50
+ options do
51
+ option '-h/--help', 'Show help.'
52
+ option '-b/--bakefile <path>', 'Path to the bakefile to use.', default: Top.bakefile_path
53
+ end
54
+
55
+ nested :command, {
56
+ 'invoke' => Invoke,
57
+ 'list' => List,
58
+ }, default: 'invoke'
59
+
60
+ def terminal(out = $stdout)
61
+ terminal = Console::Terminal.for(out)
62
+
63
+ terminal[:loader] = terminal.style(nil, nil, :bold)
64
+ terminal[:command] = terminal.style(:blue)
65
+
66
+ terminal[:opt] = terminal.style(:green)
67
+ terminal[:req] = terminal.style(:red)
68
+ terminal[:keyreq] = terminal.style(:red, nil, :bold)
69
+ terminal[:keyrest] = terminal.style(:green)
70
+
71
+ return terminal
72
+ end
73
+
74
+ def bakefile
75
+ @options[:bakefile]
76
+ end
77
+
78
+ def working_directory
79
+ if bakefile = self.bakefile
80
+ File.dirname(self.bakefile)
81
+ else
82
+ Dir.pwd
83
+ end
84
+ end
85
+
86
+ def context
87
+ loaders = Loaders.new
88
+
89
+ if bakefile = self.bakefile
90
+ context = Context.load(self.bakefile, loaders)
91
+ else
92
+ context = Context.new(loaders)
93
+ end
94
+
95
+ if loaders.empty?
96
+ loaders.append_defaults(working_directory)
97
+ end
98
+
99
+ return context
100
+ end
101
+
102
+ def call
103
+ if @options[:help]
104
+ self.print_usage
105
+ else
106
+ @command.call
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -1,113 +1,106 @@
1
- require 'bake/addon'
2
- require 'bake/plugin'
1
+ # Copyright, 2020, 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.
3
20
 
4
21
  module Bake
5
- class Context
6
- include PluginManager
7
-
8
- DEFAULT_SEARCH_DIR = File.join(File.dirname(__FILE__), '..')
9
-
10
- attr_reader :current, :default_toolset
11
-
12
- def initialize(sys)
13
- @sys = sys
14
- @current = nil
15
- @commands = {}
16
- @default_toolset = Toolset.new(@sys)
17
- end
18
-
19
- def import(*addon_classes)
20
- addon_classes.each do |addon_class|
21
- if addon_class.inherits?(Toolset)
22
- addon = addon_class.new(@sys)
23
- else
24
- addon = addon_class.new
25
- end
26
- addon.commands.each_pair do |name, block|
27
- register(name, &block)
28
- end
29
- end
30
- end
31
-
32
- def using(*addon_classes)
33
- addon_classes.each do |addon_class|
34
- if addon_class.inherits?(Toolset)
35
- addon = addon_class.new(@sys)
36
- else
37
- addon = addon_class.new
38
- end
39
- @current.opt(:addons => addon)
40
- end
41
- end
42
-
43
- def register(name, &block)
44
- @commands[name] = block
45
- end
46
-
47
- def context_eval(target, str = nil, file = nil, &block)
48
- context = Thread.current[:bake_context]
49
- if !context.nil? && !context.equal?(self)
50
- raise 'multiple overlapping contexts detected'
51
- end
52
- Thread.current[:bake_context] = self
53
- old = @current
54
- begin
55
- @current = target
56
- if str
57
- instance_eval(str, file ? file : '')
58
- else
59
- instance_eval(&block)
60
- end
61
- ensure
62
- @current = old
63
- Thread.current[:bake_context] = nil
64
- end
65
- end
66
-
67
- def search_dirs
68
- search_dirs = [ DEFAULT_SEARCH_DIR ]
69
- return search_dirs if !@current
70
- return search_dirs + @current[:plugin_paths]
71
- end
72
-
73
- def method_missing(name, *args, &block)
74
- command = @commands[name]
75
- return call(command, *args, &block) if command
76
- if @current
77
- if @current.respond_to?(name)
78
- return @current.send(name, *args, &block)
79
- end
80
- @current[:addons].each do |addon|
81
- command = addon.commands[name]
82
- return call(command, *args, &block) if command
83
- end
84
- end
85
- raise "unknown command '#{name}'"
86
- end
87
-
88
- def self.const_missing(name)
89
- context = Thread.current[:bake_context]
90
- return super if !context
91
- context.load_plugin("Bake::Plugins::#{name}")
92
- end
93
-
94
- private
95
- def call(command, *args, &block)
96
- args << block if block
97
- return instance_exec(*args, &command)
98
- end
99
-
100
- # took this implementation from http://tinyurl.com/gzrtn
101
- def instance_exec(*args, &block)
102
- mname = "__instance_exec_#{Thread.current.object_id.abs}"
103
- class << self; self end.class_eval { define_method(mname, &block) }
104
- begin
105
- ret = send(mname, *args)
106
- ensure
107
- class << self; self end.class_eval { undef_method(mname) } rescue nil
108
- end
109
- ret
110
- end
111
- end
22
+ class Context < Book
23
+ def initialize(loaders, **options)
24
+ @loaders = loaders
25
+
26
+ @scope = []
27
+
28
+ super(**options)
29
+ end
30
+
31
+ def to_s
32
+ self.class.name
33
+ end
34
+
35
+ attr :loaders
36
+
37
+ def call(*commands, describe: false)
38
+ while command = commands.shift
39
+ if recipes = recipes_for(command)
40
+ arguments, options = recipes.first.prepare(commands)
41
+
42
+ recipes.each do |recipe|
43
+ if describe
44
+ recipe.explain(self, *arguments, **options)
45
+ else
46
+ with(recipe) do
47
+ recipe.call(self, *arguments, **options)
48
+ end
49
+ end
50
+ end
51
+ else
52
+ raise ArgumentError, "Could not find recipe for #{command}!"
53
+ end
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def with(recipe)
60
+ @scope << recipe.book
61
+
62
+ yield
63
+ ensure
64
+ @scope.pop
65
+ end
66
+
67
+ def recipes_for(command)
68
+ if command.is_a?(Symbol)
69
+ recipes_for_relative_reference(command)
70
+ else
71
+ recipes_for_absolute_reference(command)
72
+ end
73
+ end
74
+
75
+ def recipes_for_relative_reference(command)
76
+ if scope = @scope.last
77
+ if recipe = scope.lookup(command)
78
+ return [recipe]
79
+ end
80
+ end
81
+ end
82
+
83
+ def recipes_for_absolute_reference(command)
84
+ path = command.split(":")
85
+
86
+ recipes = []
87
+
88
+ # Get the root level recipes:
89
+ if recipe = self.recipe_for(path)
90
+ recipes << recipe
91
+ end
92
+
93
+ @loaders.each do |loader|
94
+ if recipe = loader.recipe_for(path)
95
+ recipes << recipe
96
+ end
97
+ end
98
+
99
+ if recipes.empty?
100
+ return nil
101
+ else
102
+ return recipes
103
+ end
104
+ end
105
+ end
112
106
  end
113
-