alki 0.9.0 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30b3e6d184beebdc00446b13b4930d47d32151df
4
- data.tar.gz: 98249b15e58962ab44737b9e54199f8690938407
3
+ metadata.gz: bc1b79ca08e965916ecbd78625d9635f9b11868c
4
+ data.tar.gz: 7d847de049a43edefa043d07ef4d64160c625407
5
5
  SHA512:
6
- metadata.gz: df40acd78708b8a0371f5191f1b5160c4d09e9348e92c237791761528a22552f3212c7dd14759c555b20d5364def4cd1976eaa12ad90690d3d9b81a7c5e27670
7
- data.tar.gz: 24bc23ef4c32c0b16a6e63a0386c3a767bcc9fc0a2393b8197c9d942e4f9ebad6bc97b394d1d142c060cc39371e42d6fc2edeb6d72a51035fd12dad836babc8c
6
+ metadata.gz: 05ffaa08ff5d51121f127ee2db0cc01238031b1b0ff6f7e0c1a95eedab5cd551e6733c991ea54a7058cc308468843b97591e40fdbac5c19b005317fbaddd5614
7
+ data.tar.gz: a1db4bc72926268f1d1ccb789215c903bfd83a0e165816a98777fa15bf5ab70f230a2a35854f94ebf62df8cb0810f9f7b3a2c1fc09bc1cd3cac0d468964b148b
data/exe/alki CHANGED
@@ -2,8 +2,9 @@
2
2
  require 'fileutils'
3
3
  require 'optparse'
4
4
  require 'alki/support'
5
+ require 'alki/generator'
5
6
 
6
- valid_addons = ["console"]
7
+ valid_addons = ["console","reload"]
7
8
 
8
9
  options = {
9
10
  config_dir: nil,
@@ -14,12 +15,14 @@ options = {
14
15
  parser = OptionParser.new do |opts|
15
16
  opts.banner = "Usage: alki init PROJECT_NAME [options]"
16
17
 
17
- opts.on("-a", "--add[=ADDON]", "Add addon to project. Valid addons: #{valid_addons.join(', ')}") do |v|
18
- unless valid_addons.include? v
19
- puts "Invalid addon: #{v}"
20
- exit 1
18
+ opts.on("-a", "--addons=ADDONS", Array, "Add addon to project. Valid addons: #{valid_addons.join(', ')}") do |vs|
19
+ vs.each do |v|
20
+ unless valid_addons.include? v
21
+ puts "Invalid addon: #{v}"
22
+ exit 1
23
+ end
24
+ options[:addons] |= [v]
21
25
  end
22
- options[:addon] |= [v]
23
26
  end
24
27
 
25
28
  opts.on('-d','--directory=DIRECTORY', 'Project root, defaults to the current working directory') do |v|
@@ -47,187 +50,9 @@ unless ARGV[1] =~ %r{^[a-z0-9_]+(/[a-z0-9_]+)*$}
47
50
  exit 1
48
51
  end
49
52
 
50
-
51
-
52
- class AlkiFileWriter
53
- def initialize(root_dir)
54
- @root_dir = root_dir
55
- @changes = []
56
- @triggers = []
57
- end
58
-
59
- def create(file,contents)
60
- @changes << [:create,file: file,contents: contents,opts: {}]
61
- end
62
-
63
- def create_exec(file,contents)
64
- @changes << [:create,file: file,contents: contents,opts: {exec: true}]
65
- end
66
-
67
- def check_create(file:, contents:, opts:)
68
- path = abs_path( file)
69
- if File.exists? path
70
- if File.read(path) == contents
71
- :skip
72
- end
73
- end
74
- end
75
-
76
- def desc_create(file:, contents:, opts: {})
77
- path = abs_path( file)
78
- if opts[:exec]
79
- adj = "executable "
80
- end
81
- if File.exists? path
82
- "Overwriting #{adj}#{file}!"
83
- else
84
- "Create #{adj}#{file}"
85
- end
86
- end
87
-
88
- def do_create(file:, contents:, opts: {})
89
- path = abs_path( file)
90
- FileUtils.mkdir_p File.dirname(path)
91
- File.write path, contents
92
- FileUtils.chmod '+x', path if opts[:exec]
93
- end
94
-
95
- def opt_create(file,contents)
96
- @changes << [:opt_create,file: file,contents: contents]
97
- end
98
-
99
- def check_opt_create(file:, contents:)
100
- if File.exists? abs_path( file)
101
- :skip
102
- end
103
- end
104
-
105
- def desc_opt_create(opts)
106
- desc_create opts
107
- end
108
-
109
- def do_opt_create(opts)
110
- do_create opts
111
- end
112
-
113
- def add_line(file,line,opts={})
114
- @changes << [:add_line,file: file,line: line,opts: opts]
115
- end
116
-
117
- def check_add_line(file:,line:,opts:)
118
- if File.exists? abs_path(file)
119
- File.open(file) do |f|
120
- if opts[:after]
121
- found = until f.eof?
122
- break true if f.readline.chomp == opts[:after]
123
- end
124
- unless found
125
- puts "File \"#{file}\" doesn't contain required line #{opts[:after]}"
126
- return :abort
127
- end
128
- end
129
- until f.eof?
130
- l = f.readline
131
- if opts[:match] ? l.chomp.match(opts[:match]) : (l.chomp == line)
132
- return :skip
133
- end
134
- end
135
- end
136
- else
137
- unless @changes.find {|c| [:create,:opt_create].include?(c[0]) && c[1][:file] == file}
138
- puts "File \"#{file}\" doesn't exist!"
139
- return :abort
140
- end
141
- end
142
- end
143
-
144
- def desc_add_line(file:,line:,opts:)
145
- "Add line \"#{line}\" to #{file}"
146
- end
147
-
148
- def do_add_line(file:,line:,opts:)
149
- if opts[:after]
150
- File.write file, File.read(file).sub(/^#{Regexp.quote(opts[:after])}\n/){|m| m + line + "\n"}
151
- else
152
- File.open(file,'a') do |f|
153
- f.puts line
154
- end
155
- end
156
- end
157
-
158
- def trigger(file,cmd)
159
- @triggers << [file, cmd]
160
- end
161
-
162
- def check_trigger(changes,file)
163
- changes.find {|c| c[1][:file] == file}
164
- end
165
-
166
- def desc_trigger(cmd:)
167
- "Run \"#{cmd}\""
168
- end
169
-
170
- def do_trigger(cmd:)
171
- system cmd
172
- end
173
-
174
- def check_changes
175
- puts "Checking preconditions..."
176
- abort = false
177
- unless Dir.exists?(@root_dir)
178
- puts "Root dir doesn't exist"
179
- exit 1
180
- end
181
- do_changes = []
182
- @changes.each do |(type,args)|
183
- res = send "check_#{type}", args
184
- abort = true if res == :abort
185
- do_changes << [type,args] unless res == :skip
186
- end
187
- @triggers.each do |(file,cmd)|
188
- if check_trigger do_changes, file
189
- do_changes << [:trigger,cmd: cmd]
190
- end
191
- end
192
- exit 1 if abort
193
- do_changes
194
- end
195
-
196
- def print_overview(changes)
197
- puts "Overview of changes to be made:"
198
-
199
- changes.each do |(type,args)|
200
- desc = send "desc_#{type}", args
201
- puts " #{desc}" if desc
202
- end
203
- print "Proceed? "
204
- resp = STDIN.gets.chomp
205
- unless resp =~ /^y(es?)?/i
206
- puts "Aborting"
207
- exit
208
- end
209
- end
210
-
211
- def write
212
- puts "Using project root: #{@root_dir}\n"
213
- do_changes = check_changes
214
- print_overview do_changes
215
-
216
- puts "Writing changes..."
217
- do_changes.each do |(type,args)|
218
- send "do_#{type}", args
219
- end
220
- puts "Done"
221
- end
222
-
223
- def abs_path(p)
224
- File.expand_path(p,@root_dir)
225
- end
226
- end
227
-
228
53
  project_name = ARGV[1]
229
54
 
230
- fw = AlkiFileWriter.new config[:project_dir]
55
+ fw = Alki::Generator.new options[:project_dir]
231
56
 
232
57
  config_dir = options[:config_dir] || 'config'
233
58
  primary_config = options[:primary_config] || 'assembly'
@@ -261,7 +86,7 @@ if options[:addons].include? "console"
261
86
  fw.add_line "Gemfile", "gem 'alki-console'", match: /^gem ['"]alki-console['"]/
262
87
 
263
88
  name = project_name.tr('/','-')
264
- fw.add_line primary_config_path, " mount :console, 'alki/console', name: '#{name}'", match: /^\s*assembly :console/, after: 'Alki do'
89
+ fw.add_line primary_config_path, " mount :console, 'alki/console', name: '#{name}'", match: /^\s*mount\( *:console/, after: 'Alki do'
265
90
 
266
91
  fw.create_exec 'bin/console', <<END
267
92
  #!/usr/bin/env ruby
@@ -272,4 +97,12 @@ require '#{project_name}'
272
97
  END
273
98
  end
274
99
 
100
+ if options[:addons].include? "reload"
101
+ fw.add_line "Gemfile", "gem 'alki-reload'", match: /^gem ['"]alki-reload['"]/
102
+
103
+ env_name = project_name.tr('a-z/','A-Z_')+"_ENV"
104
+ fw.add_line primary_config_path, " mount(:reloader, 'alki/reload'){ set(:watch) { development? } }", match: /^\s*mount\(? *:reloader/, after: 'Alki do'
105
+ fw.add_line primary_config_path, " set(:development?){ ENV['#{env_name}'] == 'development' }", match: /^\s*set :development?/, after: 'Alki do'
106
+ end
107
+
275
108
  fw.write
@@ -10,6 +10,7 @@ module Alki
10
10
  @config_dir = nil
11
11
  @assembly_name = nil
12
12
  @definition = nil
13
+ @load_mode = :direct
13
14
  end
14
15
 
15
16
  attr_reader :config_dir, :assembly_name, :definition
@@ -19,6 +20,7 @@ module Alki
19
20
  end
20
21
 
21
22
  def build(opts={},&blk)
23
+ @load_mode = opts[:load_mode] if opts[:load_mode]
22
24
  build_assembly blk if blk
23
25
  if opts[:config_dir]
24
26
  context = if opts[:project_assembly]
@@ -68,9 +70,7 @@ module Alki
68
70
  end
69
71
 
70
72
  def register_config_directory
71
- opts = {config_dir: @config_dir}
72
- opts[:prefix] = File.join(@assembly_name,'alki_config') if @assembly_name
73
- Alki::Dsl.register_dir @config_dir, 'alki/dsls/assembly', opts
73
+ Alki::Dsl.register_dir @config_dir, 'alki/dsls/assembly', dsl_opts
74
74
  end
75
75
 
76
76
  def load_assembly_file(name = nil)
@@ -78,7 +78,7 @@ module Alki
78
78
  if @config_dir
79
79
  assembly_config_path = File.join(@config_dir,"#{name}.rb")
80
80
  if File.exists? assembly_config_path
81
- @definition = Alki::Dsl.load(assembly_config_path)[:class]
81
+ @definition = assembly_config_path
82
82
  true
83
83
  end
84
84
  end
@@ -89,22 +89,47 @@ module Alki
89
89
  end
90
90
 
91
91
  def build_assembly(blk)
92
- @definition = Alki::Dsl.build('alki/dsls/assembly', config_dir: @config_dir, &blk)[:class]
92
+ @definition = Alki::Dsl.build('alki/dsls/assembly', dsl_opts, &blk)[:class]
93
+ end
94
+
95
+ def dsl_opts
96
+ opts = {config_dir: @config_dir}
97
+ if @assembly_name
98
+ opts[:prefix] = File.join(@assembly_name,'alki_config')
99
+ opts[:assembly_name] = @assembly_name
100
+ end
101
+ opts
93
102
  end
94
103
 
95
104
  def build_class
96
105
  definition = @definition
106
+ name = @assembly_name
107
+ load_class = if @load_mode == :require
108
+ ->{ name }
109
+ else
110
+ ->{ self }
111
+ end
97
112
  Alki::ClassBuilder.build(
98
113
  prefix: '',
99
114
  name: @assembly_name,
100
115
  class_modules: [Alki::Assembly],
101
116
  type: :module,
102
117
  class_methods: {
118
+ assembly_name: {
119
+ body: ->{
120
+ name
121
+ }
122
+ },
103
123
  definition: {
104
124
  body: ->{
105
- definition
125
+ definition.is_a?(String) ?
126
+ Alki::Dsl.load(definition)[:class] :
127
+ definition
106
128
  }
107
129
  },
130
+ load_class: {
131
+ body: load_class
132
+ }
108
133
  }
109
134
  )
110
135
  end
@@ -11,16 +11,18 @@ module Alki
11
11
  @overlays = overlays
12
12
  @data = {}
13
13
  @semaphore = Monitor.new
14
- clear
15
- end
16
-
17
- def clear
18
14
  @lookup_cache = {}
19
15
  @call_cache = {}
20
16
  @context_cache = {}
21
17
  @processed_overlays = false
22
18
  end
23
19
 
20
+ def synchronize
21
+ @semaphore.synchronize do
22
+ yield
23
+ end
24
+ end
25
+
24
26
  def call(path,*args,&blk)
25
27
  execute({},path,args,blk)
26
28
  end
@@ -29,7 +31,7 @@ module Alki
29
31
  cache_entry = @call_cache[path]
30
32
  if cache_entry
31
33
  if cache_entry.status == :building
32
- raise "Circular element reference found"
34
+ raise "Circular element reference found: #{path.join(".")}"
33
35
  end
34
36
  else
35
37
  @semaphore.synchronize do
@@ -49,6 +51,15 @@ module Alki
49
51
  call_value(cache_entry.type,cache_entry.value,meta,args,blk)
50
52
  end
51
53
 
54
+ def canonical_path(from,path)
55
+ from_elem = lookup(from)
56
+ scope = from_elem[:full_scope] || from_elem[:scope]
57
+ path.inject(nil) do |p,elem|
58
+ scope = lookup(p)[:scope] if p
59
+ scope[elem]
60
+ end
61
+ end
62
+
52
63
  private
53
64
 
54
65
  def process_overlays
@@ -58,8 +69,11 @@ module Alki
58
69
  @overlays.each do |(from,info)|
59
70
  target = canonical_path(from,info.target) or
60
71
  raise InvalidPathError.new("Invalid overlay target #{info.target.join('.')}")
61
- overlay = canonical_path(from,info.overlay) or
62
- raise InvalidPathError.new("Invalid overlay path #{info.overlay.join('.')}")
72
+ overlay = info.overlay
73
+ if overlay.is_a?(Array)
74
+ overlay = canonical_path(from,info.overlay) or
75
+ raise InvalidPathError.new("Invalid overlay path #{info.overlay.join('.')}")
76
+ end
63
77
  (@data[:overlays][target]||=[]) << [overlay,info.args]
64
78
  end
65
79
  end
@@ -84,15 +98,6 @@ module Alki
84
98
  elem.output data
85
99
  end
86
100
 
87
-
88
- def canonical_path(from,path)
89
- scope = lookup(from)[:full_scope]
90
- path.inject(nil) do |p,elem|
91
- scope = lookup(p)[:scope] if p
92
- scope[elem]
93
- end
94
- end
95
-
96
101
  def process_action(action)
97
102
  if action.key?(:value)
98
103
  [:value,action[:value]]
@@ -1,20 +1,37 @@
1
+ require 'delegate'
2
+ require 'alki/support'
3
+
1
4
  module Alki
2
5
  module Assembly
3
- class Instance
4
- def initialize(executor)
5
- @executor = executor
6
+ class Instance < Delegator
7
+ def initialize(assembly_module,args)
8
+ @assembly_module = assembly_module
9
+ @args = args
6
10
  end
7
11
 
8
- def root
9
- @root ||= @executor.call []
12
+ def __reload__
13
+ if @obj.respond_to? :__reload__
14
+ did_something = @obj.__reload__
15
+ end
16
+ if did_something != false && @obj
17
+ @obj = nil
18
+ did_something = true
19
+ end
20
+ if did_something
21
+ GC.start
22
+ end
23
+ !!did_something
10
24
  end
11
25
 
12
- def respond_to_missing?(name,include_all)
13
- root.respond_to? name
26
+ def __setobj__(obj)
27
+ @obj = obj
14
28
  end
15
29
 
16
- def method_missing(name,*args,&blk)
17
- root.send name, *args, &blk
30
+ def __getobj__
31
+ unless @obj
32
+ Alki::Support.load_class(@assembly_module).raw_instance self, *@args
33
+ end
34
+ @obj
18
35
  end
19
36
  end
20
37
  end
@@ -12,7 +12,7 @@ Alki do
12
12
  },
13
13
  proc: -> (elem) {
14
14
  elem[:value] = overlays.inject(__build__) do |val,(overlay,args)|
15
- overlay = root.lookup(overlay)
15
+ overlay = root.lookup(overlay) if overlay.is_a?(Array)
16
16
  if !overlay.respond_to?(:call) && overlay.respond_to?(:new)
17
17
  overlay = overlay.method(:new)
18
18
  end
data/lib/alki/assembly.rb CHANGED
@@ -3,26 +3,34 @@ require 'alki/assembly/types/assembly'
3
3
  require 'alki/assembly/types/group'
4
4
  require 'alki/assembly/instance'
5
5
  require 'alki/assembly/executor'
6
+ require 'alki/overlay_info'
6
7
 
7
8
  module Alki
8
9
  module Assembly
9
10
  def new(overrides={},&blk)
11
+ Instance.new load_class, [overrides, blk]
12
+ end
13
+
14
+ def raw_instance(instance,overrides,blk)
10
15
  overrides_info = OverrideBuilder.build(overrides,&blk)
11
16
  override_root = overrides_info[:root] || build(:group)
12
17
 
13
18
  assembly = build :assembly, root, override_root
14
- executor = Executor.new(assembly, overlays+overrides_info[:overlays])
19
+ update_instance_overlay = [[],OverlayInfo.new(
20
+ [:assembly_instance],
21
+ ->obj{instance.__setobj__ obj; instance},
22
+ []
23
+ )]
24
+ all_overlays = overlays+overrides_info[:overlays]+[update_instance_overlay]
25
+ executor = Executor.new(assembly, all_overlays)
15
26
 
16
27
  override_root.children[:assembly_instance] = build(:service,->{
17
- Instance.new(executor)
28
+ root
18
29
  })
30
+ override_root.children[:assembly_executor] = build(:value,executor)
19
31
  executor.call [:assembly_instance]
20
32
  end
21
33
 
22
- def build(type,*args)
23
- Alki::Support.load_class("alki/assembly/types/#{type}").new *args
24
- end
25
-
26
34
  def root
27
35
  self.definition.root
28
36
  end
@@ -30,5 +38,11 @@ module Alki
30
38
  def overlays
31
39
  self.definition.overlays
32
40
  end
41
+
42
+ private
43
+
44
+ def build(type,*args)
45
+ Alki::Support.load_class("alki/assembly/types/#{type}").new *args
46
+ end
33
47
  end
34
48
  end
@@ -4,6 +4,7 @@ Alki do
4
4
 
5
5
  finish do
6
6
  add :config_dir, build(:value, ctx[:config_dir])
7
+ add :assembly_name, build(:value, ctx[:assembly_name])
7
8
  prefix_overlays :original, ctx[:overlays]
8
9
 
9
10
  root = ctx[:root]
@@ -1,5 +1,6 @@
1
1
  require 'alki/execution/context'
2
2
  require 'alki/overlay_delegator'
3
+ require 'alki/reloadable_delegator'
3
4
 
4
5
  module Alki
5
6
  module Execution
@@ -9,6 +10,14 @@ module Alki
9
10
  def delegate_overlay(obj,overlay,**args)
10
11
  Alki::OverlayDelegator.new(obj,overlay,args)
11
12
  end
13
+
14
+ def entrypoint(klass,*args, reloadable: false)
15
+ klass.new *args.map {|a| reloadable ? self.reloadable(a) : lookup(a) }
16
+ end
17
+
18
+ def reloadable(path)
19
+ Alki::ReloadableDelegator.new(root.assembly_instance,meta[:building],path)
20
+ end
12
21
  end
13
22
  end
14
23
  end
@@ -0,0 +1,177 @@
1
+ module Alki
2
+ class Generator
3
+ def initialize(root_dir)
4
+ @root_dir = root_dir
5
+ @changes = []
6
+ @triggers = []
7
+ end
8
+
9
+ def create(file,contents)
10
+ @changes << [:create,file: file,contents: contents,opts: {}]
11
+ end
12
+
13
+ def create_exec(file,contents)
14
+ @changes << [:create,file: file,contents: contents,opts: {exec: true}]
15
+ end
16
+
17
+ def check_create(file:, contents:, opts:)
18
+ path = abs_path( file)
19
+ if File.exists? path
20
+ if File.read(path) == contents
21
+ :skip
22
+ end
23
+ end
24
+ end
25
+
26
+ def desc_create(file:, contents:, opts: {})
27
+ path = abs_path( file)
28
+ if opts[:exec]
29
+ adj = "executable "
30
+ end
31
+ if File.exists? path
32
+ "Overwriting #{adj}#{file}!"
33
+ else
34
+ "Create #{adj}#{file}"
35
+ end
36
+ end
37
+
38
+ def do_create(file:, contents:, opts: {})
39
+ path = abs_path( file)
40
+ FileUtils.mkdir_p File.dirname(path)
41
+ File.write path, contents
42
+ FileUtils.chmod '+x', path if opts[:exec]
43
+ end
44
+
45
+ def opt_create(file,contents)
46
+ @changes << [:opt_create,file: file,contents: contents]
47
+ end
48
+
49
+ def check_opt_create(file:, contents:)
50
+ if File.exists? abs_path( file)
51
+ :skip
52
+ end
53
+ end
54
+
55
+ def desc_opt_create(opts)
56
+ desc_create opts
57
+ end
58
+
59
+ def do_opt_create(opts)
60
+ do_create opts
61
+ end
62
+
63
+ def add_line(file,line,opts={})
64
+ @changes << [:add_line,file: file,line: line,opts: opts]
65
+ end
66
+
67
+ def check_add_line(file:,line:,opts:)
68
+ if File.exists? abs_path(file)
69
+ File.open(file) do |f|
70
+ if opts[:after]
71
+ found = until f.eof?
72
+ break true if f.readline.chomp == opts[:after]
73
+ end
74
+ unless found
75
+ puts "File \"#{file}\" doesn't contain required line #{opts[:after]}"
76
+ return :abort
77
+ end
78
+ end
79
+ until f.eof?
80
+ l = f.readline
81
+ if opts[:match] ? l.chomp.match(opts[:match]) : (l.chomp == line)
82
+ return :skip
83
+ end
84
+ end
85
+ end
86
+ else
87
+ unless @changes.find {|c| [:create,:opt_create].include?(c[0]) && c[1][:file] == file}
88
+ puts "File \"#{file}\" doesn't exist!"
89
+ return :abort
90
+ end
91
+ end
92
+ end
93
+
94
+ def desc_add_line(file:,line:,opts:)
95
+ "Add line \"#{line}\" to #{file}"
96
+ end
97
+
98
+ def do_add_line(file:,line:,opts:)
99
+ if opts[:after]
100
+ File.write file, File.read(file).sub(/^#{Regexp.quote(opts[:after])}\n/){|m| m + line + "\n"}
101
+ else
102
+ File.open(file,'a') do |f|
103
+ f.puts line
104
+ end
105
+ end
106
+ end
107
+
108
+ def trigger(file,cmd)
109
+ @triggers << [file, cmd]
110
+ end
111
+
112
+ def check_trigger(changes,file)
113
+ changes.find {|c| c[1][:file] == file}
114
+ end
115
+
116
+ def desc_trigger(cmd:)
117
+ "Run \"#{cmd}\""
118
+ end
119
+
120
+ def do_trigger(cmd:)
121
+ system cmd
122
+ end
123
+
124
+ def check_changes
125
+ puts "Checking preconditions..."
126
+ abort = false
127
+ unless Dir.exists?(@root_dir)
128
+ puts "Root dir doesn't exist"
129
+ exit 1
130
+ end
131
+ do_changes = []
132
+ @changes.each do |(type,args)|
133
+ res = send "check_#{type}", args
134
+ abort = true if res == :abort
135
+ do_changes << [type,args] unless res == :skip
136
+ end
137
+ @triggers.each do |(file,cmd)|
138
+ if check_trigger do_changes, file
139
+ do_changes << [:trigger,cmd: cmd]
140
+ end
141
+ end
142
+ exit 1 if abort
143
+ do_changes
144
+ end
145
+
146
+ def print_overview(changes)
147
+ puts "Overview of changes to be made:"
148
+
149
+ changes.each do |(type,args)|
150
+ desc = send "desc_#{type}", args
151
+ puts " #{desc}" if desc
152
+ end
153
+ print "Proceed? "
154
+ resp = STDIN.gets.chomp
155
+ unless resp =~ /^y(es?)?/i
156
+ puts "Aborting"
157
+ exit
158
+ end
159
+ end
160
+
161
+ def write
162
+ puts "Using project root: #{@root_dir}\n"
163
+ do_changes = check_changes
164
+ print_overview do_changes
165
+
166
+ puts "Writing changes..."
167
+ do_changes.each do |(type,args)|
168
+ send "do_#{type}", args
169
+ end
170
+ puts "Done"
171
+ end
172
+
173
+ def abs_path(p)
174
+ File.expand_path(p,@root_dir)
175
+ end
176
+ end
177
+ end
@@ -0,0 +1,17 @@
1
+ require 'delegate'
2
+
3
+ module Alki
4
+ class ReloadableDelegator < Delegator
5
+ def initialize(instance,from,path)
6
+ @instance = instance
7
+ @from = from.to_s.split('.').map(&:to_sym)
8
+ @path = path.to_s.split('.').map(&:to_sym)
9
+ end
10
+
11
+ def __getobj__
12
+ @instance.assembly_executor.call(
13
+ @instance.assembly_executor.canonical_path(@from,@path)
14
+ )
15
+ end
16
+ end
17
+ end
data/lib/alki/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Alki
2
- VERSION = "0.9.0"
2
+ VERSION = "0.9.1"
3
3
  end
data/lib/alki.rb CHANGED
@@ -5,6 +5,7 @@ module Alki
5
5
  class << self
6
6
  def project_assembly!(opts={},&blk)
7
7
  opts[:project_assembly] ||= caller_locations(1,1)[0].absolute_path
8
+ opts[:load_mode] = :require
8
9
  Assembly::Builder.build(opts,&blk)
9
10
  end
10
11
 
@@ -210,16 +210,18 @@ describe 'Overlays' do
210
210
 
211
211
  it 'should allow setting overlays on assembly_instance' do
212
212
  values = []
213
+ mock = Minitest::Mock.new
213
214
  assembly = Alki.create_assembly do
214
215
  overlay :assembly_instance, :test_overlay
215
-
216
+ set :val, 1
216
217
  set :test_overlay, ->(value) {
217
218
  values << value
218
- :transformed
219
+ mock
219
220
  }
220
221
  end
221
- assembly.new.must_equal :transformed
222
+ mock.expect :val, 2
223
+ assembly.new.val.must_equal 2
222
224
  values.size.must_equal 1
223
- values[0].must_be_instance_of Alki::Assembly::Instance
225
+ values[0].val.must_equal 1
224
226
  end
225
227
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alki
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Edlefsen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-17 00:00:00.000000000 Z
11
+ date: 2016-12-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -138,9 +138,11 @@ files:
138
138
  - lib/alki/execution/context_class_builder.rb
139
139
  - lib/alki/execution/value_context.rb
140
140
  - lib/alki/feature_test.rb
141
+ - lib/alki/generator.rb
141
142
  - lib/alki/overlay_delegator.rb
142
143
  - lib/alki/overlay_info.rb
143
144
  - lib/alki/override_builder.rb
145
+ - lib/alki/reloadable_delegator.rb
144
146
  - lib/alki/service_delegator.rb
145
147
  - lib/alki/test.rb
146
148
  - lib/alki/version.rb
@@ -186,7 +188,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
188
  version: '0'
187
189
  requirements: []
188
190
  rubyforge_project:
189
- rubygems_version: 2.5.1
191
+ rubygems_version: 2.5.2
190
192
  signing_key:
191
193
  specification_version: 4
192
194
  summary: Base library for building applications.