bowline 0.6.2 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.txt +2 -8
- data/TODO +0 -2
- data/VERSION +1 -1
- data/bowline.gemspec +5 -2
- data/lib/bowline.rb +6 -9
- data/lib/bowline/app_config.rb +21 -34
- data/lib/bowline/binders.rb +69 -63
- data/lib/bowline/binders/observer.rb +1 -1
- data/lib/bowline/binders/singleton.rb +0 -5
- data/lib/bowline/commands/console.rb +2 -23
- data/lib/bowline/commands/generate.rb +2 -2
- data/lib/bowline/commands/init.rb +12 -0
- data/lib/bowline/commands/run.rb +1 -1
- data/lib/bowline/desktop.rb +1 -1
- data/lib/bowline/desktop/bridge.rb +35 -18
- data/lib/bowline/desktop/js.rb +8 -14
- data/lib/bowline/desktop/network.rb +1 -1
- data/lib/bowline/desktop/path.rb +18 -1
- data/lib/bowline/desktop/runtime.rb +20 -8
- data/lib/bowline/desktop/window_manager.rb +3 -3
- data/lib/bowline/ext/array.rb +2 -2
- data/lib/bowline/ext/object.rb +3 -3
- data/lib/bowline/generators.rb +43 -0
- data/lib/bowline/generators/application.rb +7 -3
- data/lib/bowline/initializer.rb +75 -22
- data/lib/bowline/library.rb +11 -27
- data/lib/bowline/tasks/app.rake +45 -9
- data/lib/bowline/tasks/libs.rake +0 -8
- data/lib/bowline/version.rb +1 -1
- data/templates/config/environment.rb +0 -4
- data/templates/config/environments/development.rb +0 -0
- data/templates/config/environments/production.rb +0 -0
- data/templates/main_window.rb +1 -1
- data/templates/script/init +2 -1
- data/templates/window.rb +1 -1
- metadata +6 -3
data/README.txt
CHANGED
@@ -12,7 +12,7 @@ Ruby, HTML and JS desktop application framework.
|
|
12
12
|
* Uses Webkit
|
13
13
|
* View in HTML/JavaScript
|
14
14
|
* Binding between HTML & Ruby
|
15
|
-
* Cross platform (
|
15
|
+
* Cross platform (OSX & Ubuntu) - Windows soon
|
16
16
|
|
17
17
|
= INTRODUCTION
|
18
18
|
|
@@ -114,12 +114,7 @@ Suffice to say, the HTML looks a bit like this:
|
|
114
114
|
<a href="#" class="destroy">Delete</a>
|
115
115
|
</div>
|
116
116
|
</div>
|
117
|
-
|
118
|
-
Now, were you to have a user object, you could do something like
|
119
|
-
this to update the HTML.
|
120
|
-
|
121
|
-
# TODO
|
122
|
-
|
117
|
+
|
123
118
|
= METHODS IN BINDERS
|
124
119
|
|
125
120
|
You can call both class and instance methods of the binders.
|
@@ -189,7 +184,6 @@ Usage for a collection (of users):
|
|
189
184
|
def admins
|
190
185
|
# This just replaces all the listed
|
191
186
|
# users with just admins
|
192
|
-
# TODO
|
193
187
|
self.items = User.admins.all
|
194
188
|
end
|
195
189
|
end
|
data/TODO
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.3
|
data/bowline.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bowline}
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alex MacCaw"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-04-06}
|
13
13
|
s.default_executable = %q{bowline-gen}
|
14
14
|
s.description = %q{Ruby/JS GUI framework}
|
15
15
|
s.email = %q{alex@leadthinking.com}
|
@@ -55,6 +55,7 @@ Gem::Specification.new do |s|
|
|
55
55
|
"lib/bowline/commands/build.rb",
|
56
56
|
"lib/bowline/commands/console.rb",
|
57
57
|
"lib/bowline/commands/generate.rb",
|
58
|
+
"lib/bowline/commands/init.rb",
|
58
59
|
"lib/bowline/commands/run.rb",
|
59
60
|
"lib/bowline/desktop.rb",
|
60
61
|
"lib/bowline/desktop/app.rb",
|
@@ -102,6 +103,8 @@ Gem::Specification.new do |s|
|
|
102
103
|
"templates/config/boot.rb",
|
103
104
|
"templates/config/database.yml",
|
104
105
|
"templates/config/environment.rb",
|
106
|
+
"templates/config/environments/development.rb",
|
107
|
+
"templates/config/environments/production.rb",
|
105
108
|
"templates/gitignore",
|
106
109
|
"templates/helper.rb",
|
107
110
|
"templates/main_window.rb",
|
data/lib/bowline.rb
CHANGED
@@ -7,24 +7,19 @@ require 'active_support/core_ext/hash/indifferent_access'
|
|
7
7
|
Thread.abort_on_exception = true
|
8
8
|
|
9
9
|
module Bowline
|
10
|
-
def
|
10
|
+
def library_path
|
11
11
|
File.expand_path(
|
12
|
-
File.join(File.dirname(__FILE__),
|
12
|
+
File.join(File.dirname(__FILE__), "..")
|
13
13
|
)
|
14
14
|
end
|
15
|
-
module_function :
|
16
|
-
|
17
|
-
def assets_path
|
18
|
-
File.join(lib_path, "assets")
|
19
|
-
end
|
20
|
-
module_function :assets_path
|
15
|
+
module_function :library_path
|
21
16
|
|
22
17
|
module Base
|
23
18
|
end
|
24
19
|
end
|
25
20
|
|
26
21
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
27
|
-
$LOAD_PATH << File.join(Bowline.
|
22
|
+
$LOAD_PATH << File.join(Bowline.library_path, 'vendor')
|
28
23
|
|
29
24
|
require 'bowline/version'
|
30
25
|
|
@@ -46,9 +41,11 @@ require 'bowline/desktop/dock'
|
|
46
41
|
require 'bowline/desktop/host'
|
47
42
|
require 'bowline/desktop/misc'
|
48
43
|
require 'bowline/desktop/network'
|
44
|
+
require 'bowline/desktop/path'
|
49
45
|
require 'bowline/desktop/sound'
|
50
46
|
require 'bowline/desktop/window_methods'
|
51
47
|
require 'bowline/desktop/window'
|
48
|
+
require 'bowline/desktop/runtime'
|
52
49
|
require 'bowline/desktop/js'
|
53
50
|
require 'bowline/desktop/proxy'
|
54
51
|
require 'bowline/desktop/bridge'
|
data/lib/bowline/app_config.rb
CHANGED
@@ -1,41 +1,28 @@
|
|
1
|
+
require 'supermodel'
|
2
|
+
|
1
3
|
module Bowline
|
2
|
-
class AppConfig
|
3
|
-
|
4
|
-
def initialize(path)
|
5
|
-
@path = path
|
6
|
-
@keys = {}
|
7
|
-
load!
|
8
|
-
end
|
9
|
-
|
10
|
-
def load!
|
11
|
-
return unless File.exist?(path)
|
12
|
-
@keys = YAML::load(File.read(path))
|
13
|
-
end
|
14
|
-
|
15
|
-
def dump!
|
16
|
-
File.open(path, "w+") {|f| f.write(YAML::dump(keys)) }
|
17
|
-
end
|
18
|
-
|
19
|
-
def delete(key)
|
20
|
-
@keys.delete(key)
|
21
|
-
dump!
|
22
|
-
end
|
4
|
+
class AppConfig < SuperModel::Base
|
5
|
+
include SuperModel::Marshal::Model
|
23
6
|
|
24
|
-
|
25
|
-
|
7
|
+
class << self
|
8
|
+
def instance
|
9
|
+
@instance ||= create
|
10
|
+
end
|
11
|
+
|
12
|
+
def marshal_records(record = nil)
|
13
|
+
self.instance.load(record.attributes) if record
|
14
|
+
self.instance
|
15
|
+
end
|
26
16
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
keys[$`] = args.first
|
31
|
-
dump!
|
32
|
-
when "?"
|
33
|
-
keys[$`]
|
34
|
-
end
|
35
|
-
else
|
36
|
-
return keys[method_name] if keys.include?(method_name)
|
37
|
-
super
|
17
|
+
def load!(path)
|
18
|
+
self.instance.load_path(path)
|
19
|
+
self.instance
|
38
20
|
end
|
39
21
|
end
|
22
|
+
|
23
|
+
def load_path(path)
|
24
|
+
return unless path && File.exist?(path)
|
25
|
+
load(YAML::load(File.read(path)))
|
26
|
+
end
|
40
27
|
end
|
41
28
|
end
|
data/lib/bowline/binders.rb
CHANGED
@@ -60,7 +60,60 @@ module Bowline
|
|
60
60
|
extend Bowline::Desktop::Bridge::ClassMethods
|
61
61
|
js_expose
|
62
62
|
|
63
|
-
|
63
|
+
module Async
|
64
|
+
protected
|
65
|
+
def async(*methods)
|
66
|
+
if block_given?
|
67
|
+
Thread.new(callback_proc) do |proc|
|
68
|
+
begin
|
69
|
+
self.callback_proc = proc
|
70
|
+
yield
|
71
|
+
rescue => e
|
72
|
+
Bowline::Logging.log_error(e)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
else
|
76
|
+
methods.each do |method|
|
77
|
+
class_eval(<<-EOS, __FILE__, __LINE__)
|
78
|
+
def #{method}_with_async(*args, &block)
|
79
|
+
async { #{method}_without_async(*args, &block) }
|
80
|
+
end
|
81
|
+
EOS
|
82
|
+
alias_method_chain method, :async
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
extend Async
|
89
|
+
include Async
|
90
|
+
class << self; extend Async; end
|
91
|
+
|
92
|
+
class << self
|
93
|
+
def callback_proc(proc = nil) #:nodoc:
|
94
|
+
Thread.current[:callback] = proc if proc
|
95
|
+
Thread.current[:callback]
|
96
|
+
end
|
97
|
+
alias_method :callback_proc=, :callback_proc
|
98
|
+
|
99
|
+
def callback(result = nil)
|
100
|
+
result = yield if block_given?
|
101
|
+
callback_proc.call(result)
|
102
|
+
end
|
103
|
+
|
104
|
+
def js_invoke(window, callback, method, *args) #:nodoc:
|
105
|
+
self.callback_proc = callback
|
106
|
+
if method == :setup
|
107
|
+
setup(window)
|
108
|
+
else
|
109
|
+
send(method, *args)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def instance_invoke(id, method, *args) #:nodoc:
|
114
|
+
self.new(id).send(method, *args)
|
115
|
+
end
|
116
|
+
|
64
117
|
# An array of window currently bound.
|
65
118
|
def windows
|
66
119
|
@windows ||= []
|
@@ -68,10 +121,11 @@ module Bowline
|
|
68
121
|
|
69
122
|
def setup(window) #:nodoc:
|
70
123
|
self.windows << window
|
124
|
+
self.windows.uniq!
|
71
125
|
if initial_items = initial
|
72
126
|
self.items = initial_items
|
73
127
|
end
|
74
|
-
|
128
|
+
callback(true)
|
75
129
|
end
|
76
130
|
|
77
131
|
# Called by a window's JavaScript whenever that window is bound to this Binder.
|
@@ -84,18 +138,6 @@ module Bowline
|
|
84
138
|
def initial
|
85
139
|
end
|
86
140
|
|
87
|
-
def js_invoke(window, method, *args) #:nodoc:
|
88
|
-
if method == :setup
|
89
|
-
setup(window)
|
90
|
-
else
|
91
|
-
send(method, *args)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def instance_invoke(id, meth, *args) #:nodoc:
|
96
|
-
self.new(id).send(meth, *args)
|
97
|
-
end
|
98
|
-
|
99
141
|
# Calls .find on the klass sent to the bind method.
|
100
142
|
# This is used internally, to find records when the page
|
101
143
|
# invoke instance methods.
|
@@ -133,8 +175,8 @@ module Bowline
|
|
133
175
|
# Remove an item from the binder, updating the HTML.
|
134
176
|
# This method is normally only called internally by
|
135
177
|
# the bound class's after_destroy callback.
|
136
|
-
def
|
137
|
-
bowline.
|
178
|
+
def destroyed(item)
|
179
|
+
bowline.destroyed(
|
138
180
|
name,
|
139
181
|
item.id
|
140
182
|
).call
|
@@ -174,62 +216,26 @@ module Bowline
|
|
174
216
|
# See Bowline::logger
|
175
217
|
def logger
|
176
218
|
Bowline::logger
|
177
|
-
end
|
178
|
-
|
179
|
-
# Trigger events on all elements
|
180
|
-
# bound to this binder.
|
181
|
-
# Example:
|
182
|
-
# trigger(:reload, {:key => :value})
|
183
|
-
def trigger(event, data = nil)
|
184
|
-
bowline.trigger(
|
185
|
-
name,
|
186
|
-
format_event(event),
|
187
|
-
data
|
188
|
-
).call
|
189
|
-
end
|
190
|
-
|
191
|
-
# Helper method to trigger a loading
|
192
|
-
# event either side of a block:
|
193
|
-
# loading {
|
194
|
-
# # Slow code, e.g. http call
|
195
|
-
# }
|
196
|
-
def loading(&block)
|
197
|
-
trigger(:loading, true)
|
198
|
-
yield
|
199
|
-
trigger(:loading, false)
|
200
|
-
end
|
201
|
-
|
202
|
-
def format_event(name) #:nodoc:
|
203
|
-
name.is_a?(Array) ?
|
204
|
-
name.join('.') :
|
205
|
-
name.to_s
|
206
|
-
end
|
219
|
+
end
|
207
220
|
end
|
208
|
-
|
209
|
-
# jQuery element object
|
210
|
-
attr_reader :element
|
211
|
-
|
221
|
+
|
212
222
|
# Instance of the bound class' record
|
213
223
|
attr_reader :item
|
214
224
|
|
215
225
|
def initialize(id, *args) #:nodoc:
|
216
|
-
@
|
217
|
-
self.class.name, id
|
218
|
-
)
|
219
|
-
@item = self.class.find(id)
|
226
|
+
@item = self.class.find(id)
|
220
227
|
end
|
221
228
|
|
222
229
|
protected
|
223
|
-
|
224
|
-
|
225
|
-
# trigger(:highlight)
|
226
|
-
def trigger(event, data = nil)
|
227
|
-
element.trigger(
|
228
|
-
self.class.format_event(event),
|
229
|
-
data
|
230
|
-
).call
|
230
|
+
def callback_proc(*args) #:nodoc
|
231
|
+
self.class.callback_proc(*args)
|
231
232
|
end
|
232
|
-
|
233
|
+
alias_method :callback_proc=, :callback_proc
|
234
|
+
|
235
|
+
def callback(*args, &block)
|
236
|
+
self.class.callback(*args, &block)
|
237
|
+
end
|
238
|
+
|
233
239
|
# Remove element from the view
|
234
240
|
def remove!
|
235
241
|
self.class.removed(item)
|
@@ -1,23 +1,2 @@
|
|
1
|
-
|
2
|
-
require "
|
3
|
-
require "irb/completion"
|
4
|
-
|
5
|
-
options = {}
|
6
|
-
OptionParser.new do |opt|
|
7
|
-
opt.banner = "Usage: console [environment] [options]"
|
8
|
-
opt.on("--debugger", "Enable ruby-debugging for the console.") { |v| options[:debugger] = v }
|
9
|
-
opt.parse!(ARGV)
|
10
|
-
end
|
11
|
-
|
12
|
-
if options[:debugger]
|
13
|
-
begin
|
14
|
-
require "ruby-debug"
|
15
|
-
puts "=> Debugger enabled"
|
16
|
-
rescue Exception
|
17
|
-
puts "You need to install ruby-debug to run the console in debugging mode. With gems, use 'gem install ruby-debug'"
|
18
|
-
exit
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
require "#{APP_ROOT}/config/environment"
|
23
|
-
IRB.start
|
1
|
+
ENV["APP_IRB"] = "1"
|
2
|
+
require "bowline/commands/run"
|
@@ -1,3 +1,3 @@
|
|
1
|
-
require
|
1
|
+
require "bowline/generators"
|
2
2
|
|
3
|
-
Bowline::Generators.run_cli(APP_ROOT,
|
3
|
+
Bowline::Generators.run_cli(APP_ROOT, "bowline", Bowline::Version::STRING, ARGV)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
unless Bowline::Desktop.enabled?
|
2
|
+
raise "Script not executed by bowline-desktop"
|
3
|
+
end
|
4
|
+
|
5
|
+
require Bowline.root.join(*%w{config environment})
|
6
|
+
|
7
|
+
if ENV["APP_IRB"]
|
8
|
+
require "irb"
|
9
|
+
require "irb/completion"
|
10
|
+
IRB.start
|
11
|
+
Bowline::Desktop::App.exit
|
12
|
+
end
|
data/lib/bowline/commands/run.rb
CHANGED
data/lib/bowline/desktop.rb
CHANGED
@@ -30,8 +30,8 @@ module Bowline
|
|
30
30
|
true
|
31
31
|
end
|
32
32
|
|
33
|
-
def js_invoke(window, method, *args)
|
34
|
-
send(method, *args)
|
33
|
+
def js_invoke(window, callback, method, *args)
|
34
|
+
callback.call(send(method, *args))
|
35
35
|
end
|
36
36
|
RUBY
|
37
37
|
end
|
@@ -40,20 +40,31 @@ module Bowline
|
|
40
40
|
class Message #:nodoc:
|
41
41
|
include Bowline::Logging
|
42
42
|
|
43
|
-
attr_reader :window, :id, :klass, :
|
43
|
+
attr_reader :window, :id, :klass, :method_name, :args
|
44
44
|
|
45
45
|
def initialize(window, atts)
|
46
|
-
@window
|
47
|
-
atts
|
48
|
-
@id
|
49
|
-
@klass
|
50
|
-
@
|
51
|
-
@args
|
46
|
+
@window = window
|
47
|
+
atts = atts.with_indifferent_access
|
48
|
+
@id = atts[:id]
|
49
|
+
@klass = atts[:klass]
|
50
|
+
@method_name = atts[:method].to_sym
|
51
|
+
@args = atts[:args] || []
|
52
52
|
end
|
53
53
|
|
54
54
|
def callback?
|
55
55
|
@id != -1
|
56
56
|
end
|
57
|
+
|
58
|
+
def callback(result)
|
59
|
+
return unless callback?
|
60
|
+
proxy = Proxy.new(window)
|
61
|
+
proxy = proxy.Bowline.invokeCallback(
|
62
|
+
id, result.to_js.to_json
|
63
|
+
)
|
64
|
+
Runtime.main {
|
65
|
+
window.run_script(proxy.to_s)
|
66
|
+
}
|
67
|
+
end
|
57
68
|
|
58
69
|
def invoke
|
59
70
|
if klass == "_window"
|
@@ -62,14 +73,19 @@ module Bowline
|
|
62
73
|
# TODO - security concerns with constantize
|
63
74
|
object = klass.constantize
|
64
75
|
end
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
76
|
+
|
77
|
+
trace "JS invoking: #{klass}.#{method_name}(#{args.join(',')})"
|
78
|
+
|
79
|
+
if object.respond_to?(:js_exposed?) &&
|
80
|
+
object.js_exposed?(method_name)
|
81
|
+
|
82
|
+
object.js_invoke(
|
83
|
+
window,
|
84
|
+
method(:callback),
|
85
|
+
method_name,
|
86
|
+
*args
|
87
|
+
)
|
88
|
+
|
73
89
|
else
|
74
90
|
raise "Method not allowed"
|
75
91
|
end
|
@@ -82,7 +98,8 @@ module Bowline
|
|
82
98
|
result = JSON.parse(str)
|
83
99
|
Message.new(window, result).invoke
|
84
100
|
rescue => e
|
85
|
-
Bowline::Logging.
|
101
|
+
Bowline::Logging.trace(str)
|
102
|
+
Bowline::Logging.log_error(e)
|
86
103
|
end
|
87
104
|
module_function :call
|
88
105
|
end
|
data/lib/bowline/desktop/js.rb
CHANGED
@@ -55,20 +55,15 @@ module Bowline
|
|
55
55
|
raise e
|
56
56
|
end
|
57
57
|
end
|
58
|
-
|
59
|
-
def poll
|
60
|
-
run_scripts
|
61
|
-
end
|
62
|
-
module_function :poll
|
63
58
|
|
64
|
-
def setup
|
59
|
+
def setup! #:nodoc:
|
65
60
|
Desktop.on_idle(method(:poll))
|
66
61
|
end
|
67
|
-
module_function :setup
|
62
|
+
module_function :setup!
|
68
63
|
|
69
|
-
def eval(
|
70
|
-
script = Script.new(
|
71
|
-
if
|
64
|
+
def eval(window, string, method = nil, &block)
|
65
|
+
script = Script.new(window, string, method||block)
|
66
|
+
if Runtime.main_thread? && script.ready?
|
72
67
|
script.call
|
73
68
|
else
|
74
69
|
scripts << script
|
@@ -77,18 +72,17 @@ module Bowline
|
|
77
72
|
module_function :eval
|
78
73
|
|
79
74
|
private
|
80
|
-
def
|
75
|
+
def poll
|
81
76
|
ready_scripts = scripts.select(&:ready?)
|
82
77
|
ready_scripts.each do |script|
|
83
78
|
script.call
|
84
79
|
scripts.delete(script)
|
85
80
|
end
|
86
81
|
end
|
87
|
-
module_function :
|
82
|
+
module_function :poll
|
88
83
|
|
89
|
-
# TODO - thread safety, needs mutex
|
90
84
|
def scripts
|
91
|
-
|
85
|
+
@scripts ||= []
|
92
86
|
end
|
93
87
|
module_function :scripts
|
94
88
|
end
|
data/lib/bowline/desktop/path.rb
CHANGED
@@ -8,6 +8,12 @@ module Bowline
|
|
8
8
|
# * Windows: "C:\Documents and Settings\username\My Documents"
|
9
9
|
# * Mac: ~/Documents
|
10
10
|
|
11
|
+
# Get the users home dir
|
12
|
+
def home
|
13
|
+
Gem.user_home
|
14
|
+
end
|
15
|
+
module_function :home
|
16
|
+
|
11
17
|
##
|
12
18
|
# :singleton-method: data
|
13
19
|
# Get the app's data dir.
|
@@ -16,11 +22,22 @@ module Bowline
|
|
16
22
|
# * Mac: appinfo.app/Contents/SharedSupport bundle subdirectory
|
17
23
|
|
18
24
|
##
|
19
|
-
# :singleton-method: user_data
|
20
25
|
# Get the app's user data dir.
|
21
26
|
# * Unix: ~/.appinfo
|
22
27
|
# * Windows: "C:\Documents and Settings\username\Application Data\appinfo"
|
23
28
|
# * Mac: "~/Library/Application Support/appinfo".
|
29
|
+
def user_data
|
30
|
+
conf = Bowline.configuration
|
31
|
+
case Bowline::Platform.type
|
32
|
+
when :linux
|
33
|
+
File.join(home, "." + conf.name)
|
34
|
+
when :win32
|
35
|
+
File.join(home, "Application Data", conf.name)
|
36
|
+
when :osx
|
37
|
+
File.join(home, "Library", "Application Support", conf.name)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
module_function :user_data
|
24
41
|
|
25
42
|
##
|
26
43
|
# :singleton-method: temp
|
@@ -1,17 +1,30 @@
|
|
1
|
+
require "thread"
|
2
|
+
|
1
3
|
module Bowline
|
2
4
|
module Desktop
|
3
5
|
module Runtime
|
4
|
-
def setup
|
6
|
+
def setup! #:nodoc:
|
5
7
|
Desktop.on_tick(method(:poll))
|
6
8
|
end
|
7
|
-
module_function :setup
|
9
|
+
module_function :setup!
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
+
# Run block/method in main thread
|
12
|
+
def main(method = nil, &block)
|
13
|
+
proc = method||block
|
14
|
+
if main_thread?
|
15
|
+
proc.call
|
16
|
+
else
|
17
|
+
procs << proc
|
18
|
+
end
|
19
|
+
end
|
20
|
+
module_function :main
|
21
|
+
|
22
|
+
def main_thread?
|
23
|
+
Thread.current == Thread.main
|
11
24
|
end
|
12
|
-
module_function :
|
25
|
+
module_function :main_thread?
|
13
26
|
|
14
|
-
private
|
27
|
+
private
|
15
28
|
def poll
|
16
29
|
while proc = procs.shift
|
17
30
|
proc.call
|
@@ -19,9 +32,8 @@ module Bowline
|
|
19
32
|
end
|
20
33
|
module_function :poll
|
21
34
|
|
22
|
-
# TODO - thread safety, needs mutex
|
23
35
|
def procs
|
24
|
-
|
36
|
+
@procs ||= []
|
25
37
|
end
|
26
38
|
module_function :procs
|
27
39
|
end
|
@@ -4,7 +4,7 @@ module Bowline
|
|
4
4
|
# It's the usual way of interfacing with your application's windows,
|
5
5
|
# and all of Bowline's windows normally inherit from it.
|
6
6
|
#
|
7
|
-
# You'll need to call the setup method, before calling using this class.
|
7
|
+
# You'll need to call the setup! method, before calling using this class.
|
8
8
|
# If the window is deallocated (i.e. closed), you'll need to call it again.
|
9
9
|
# It's worth not calling the setup method before you need it, since it'll
|
10
10
|
# increase the amount of CPU your application uses.
|
@@ -55,7 +55,7 @@ module Bowline
|
|
55
55
|
# Call this method to allocate a new window.
|
56
56
|
# You'll need to do this before using it,
|
57
57
|
# or after it has been closed.
|
58
|
-
def setup
|
58
|
+
def setup!
|
59
59
|
return unless Desktop.enabled?
|
60
60
|
return if @window && !@window.dealocated?
|
61
61
|
if self.name == "MainWindow"
|
@@ -68,7 +68,7 @@ module Bowline
|
|
68
68
|
@script_callback = Proc.new {|str|
|
69
69
|
Bowline::Desktop::Bridge.call(self, str)
|
70
70
|
}
|
71
|
-
@window.script_callback = @script_callback
|
71
|
+
@window.script_callback = @script_callback
|
72
72
|
end
|
73
73
|
|
74
74
|
# Evaluate JavaScript in this window. Pass
|
data/lib/bowline/ext/array.rb
CHANGED
data/lib/bowline/ext/object.rb
CHANGED
@@ -2,9 +2,9 @@ class Object
|
|
2
2
|
# Aim is to convert the object into:
|
3
3
|
# * A hash or
|
4
4
|
# * An array of hashes
|
5
|
-
def to_js
|
6
|
-
if respond_to?(:
|
7
|
-
|
5
|
+
def to_js(*args)
|
6
|
+
if respond_to?(:serializable_hash)
|
7
|
+
serializable_hash(*args)
|
8
8
|
elsif respond_to?(:attributes)
|
9
9
|
attributes
|
10
10
|
else
|
data/lib/bowline/generators.rb
CHANGED
@@ -2,6 +2,43 @@ gem "templater", ">= 0.3.2"
|
|
2
2
|
require "templater"
|
3
3
|
require "rbconfig"
|
4
4
|
|
5
|
+
module Templater
|
6
|
+
module Actions
|
7
|
+
class Touch < Action
|
8
|
+
|
9
|
+
def initialize(generator, name, destination, options={})
|
10
|
+
self.generator = generator
|
11
|
+
self.name = name
|
12
|
+
self.destination = destination
|
13
|
+
self.options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
def render
|
17
|
+
''
|
18
|
+
end
|
19
|
+
|
20
|
+
def exists?
|
21
|
+
::File.exists?(destination)
|
22
|
+
end
|
23
|
+
|
24
|
+
def identical?
|
25
|
+
exists?
|
26
|
+
end
|
27
|
+
|
28
|
+
def invoke!
|
29
|
+
callback(:before)
|
30
|
+
::FileUtils.touch(destination)
|
31
|
+
callback(:after)
|
32
|
+
end
|
33
|
+
|
34
|
+
def revoke!
|
35
|
+
::FileUtils.rm_rf(::File.expand_path(destination))
|
36
|
+
end
|
37
|
+
|
38
|
+
end # Touch
|
39
|
+
end # Actions
|
40
|
+
end # Templater
|
41
|
+
|
5
42
|
module Bowline
|
6
43
|
module Generators #:nodoc: all
|
7
44
|
extend Templater::Manifold
|
@@ -27,6 +64,12 @@ module Bowline
|
|
27
64
|
"#!/usr/bin/env #{RbConfig::CONFIG["RUBY_INSTALL_NAME"]}"
|
28
65
|
end
|
29
66
|
|
67
|
+
def self.touch(name, destination)
|
68
|
+
empty_directories << Templater::ActionDescription.new(name) do |generator|
|
69
|
+
Templater::Actions::Touch.new(generator, name, destination)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
30
73
|
def self.source_root
|
31
74
|
File.join(File.dirname(__FILE__), *%w[.. .. templates])
|
32
75
|
end
|
@@ -5,11 +5,11 @@ module Bowline::Generators
|
|
5
5
|
DESC
|
6
6
|
|
7
7
|
def app_id
|
8
|
-
[
|
8
|
+
["bowline", name].join(".")
|
9
9
|
end
|
10
10
|
|
11
11
|
def destination_root
|
12
|
-
#
|
12
|
+
# TODO - only works relative
|
13
13
|
File.join(@destination_root, base_name)
|
14
14
|
end
|
15
15
|
|
@@ -19,7 +19,6 @@ module Bowline::Generators
|
|
19
19
|
|
20
20
|
first_argument :name, :required => true, :desc => "application name"
|
21
21
|
|
22
|
-
empty_directory :tmp, "tmp"
|
23
22
|
empty_directory :vendor, "vendor"
|
24
23
|
empty_directory :lib, "lib"
|
25
24
|
empty_directory :db, "db"
|
@@ -60,7 +59,12 @@ module Bowline::Generators
|
|
60
59
|
file(action.downcase.gsub(/[^a-z0-9]+/, '_').to_sym, action, action)
|
61
60
|
}
|
62
61
|
|
62
|
+
glob! "config/environments"
|
63
|
+
|
63
64
|
empty_directory :initializers, "config/initializers"
|
65
|
+
empty_directory :first_run, "config/first_run"
|
66
|
+
|
67
|
+
touch "app_first_run"
|
64
68
|
|
65
69
|
file :readme, "../README.txt", "README"
|
66
70
|
end
|
data/lib/bowline/initializer.rb
CHANGED
@@ -34,6 +34,22 @@ module Bowline
|
|
34
34
|
def root
|
35
35
|
Pathname.new(APP_ROOT) if defined?(APP_ROOT)
|
36
36
|
end
|
37
|
+
|
38
|
+
def public_path
|
39
|
+
root && root.join("public")
|
40
|
+
end
|
41
|
+
|
42
|
+
def assets_path
|
43
|
+
File.join(library_path, "assets")
|
44
|
+
end
|
45
|
+
|
46
|
+
def env
|
47
|
+
@env ||= ActiveSupport::StringInquirer.new(ENV["APP_ENV"] || "development")
|
48
|
+
end
|
49
|
+
|
50
|
+
def irb?
|
51
|
+
!!ENV["APP_IRB"]
|
52
|
+
end
|
37
53
|
end
|
38
54
|
|
39
55
|
class Initializer #:nodoc:
|
@@ -61,7 +77,14 @@ module Bowline
|
|
61
77
|
@configuration = configuration
|
62
78
|
@loaded_plugins = []
|
63
79
|
end
|
64
|
-
|
80
|
+
|
81
|
+
def set_environment
|
82
|
+
production_path = Bowline.root.join("app_production")
|
83
|
+
ENV["APP_ENV"] ||= begin
|
84
|
+
production_path.exist? ? "production" : "development"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
65
88
|
def require_frameworks
|
66
89
|
configuration.frameworks.each { |framework| require(framework.to_s) }
|
67
90
|
end
|
@@ -158,7 +181,7 @@ module Bowline
|
|
158
181
|
# Loads support for "whiny nil" (noisy warnings when methods are invoked
|
159
182
|
# on +nil+ values) if Configuration#whiny_nils is true.
|
160
183
|
def initialize_whiny_nils
|
161
|
-
require(
|
184
|
+
require("active_support/whiny_nil") if configuration.whiny_nils
|
162
185
|
end
|
163
186
|
|
164
187
|
# Sets the default value for Time.zone, and turns on ActiveRecord::Base#time_zone_aware_attributes.
|
@@ -197,18 +220,32 @@ module Bowline
|
|
197
220
|
end
|
198
221
|
|
199
222
|
def load_plugins
|
200
|
-
Dir.glob(File.join(configuration.plugin_glob,
|
223
|
+
Dir.glob(File.join(configuration.plugin_glob, "init.rb")).sort.each do |path|
|
201
224
|
config = configuration # Need local config variable
|
202
225
|
eval(IO.read(path), binding, path)
|
203
226
|
end
|
204
227
|
end
|
205
228
|
|
229
|
+
def load_application_environment
|
230
|
+
require(Bowline.root.join(*%w{config environments}, Bowline.env))
|
231
|
+
end
|
232
|
+
|
206
233
|
def load_application_initializers
|
207
234
|
Dir.glob(configuration.initializer_glob).sort.each do |initializer|
|
208
235
|
load(initializer)
|
209
236
|
end
|
210
237
|
end
|
211
238
|
|
239
|
+
def load_application_first_run
|
240
|
+
first_run = Bowline.root.join("app_first_run")
|
241
|
+
if first_run.exist?
|
242
|
+
first_run.unlink
|
243
|
+
Dir.glob(configuration.first_run_glob).sort.each do |initializer|
|
244
|
+
load(initializer)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
212
249
|
def after_initialize
|
213
250
|
configuration.after_initialize_blocks.each do |block|
|
214
251
|
block.call
|
@@ -253,31 +290,39 @@ module Bowline
|
|
253
290
|
# Creates a class called AppConfig from configuration
|
254
291
|
# variables found in config/application.yml
|
255
292
|
def load_app_config
|
256
|
-
Object.const_set("AppConfig", AppConfig.
|
293
|
+
Object.const_set("AppConfig", AppConfig.load!(configuration.app_config_file))
|
257
294
|
end
|
258
295
|
|
259
|
-
def
|
260
|
-
return unless
|
261
|
-
|
296
|
+
def initialize_desktop
|
297
|
+
return unless Desktop.enabled?
|
298
|
+
Desktop::Runtime.setup!
|
299
|
+
Desktop::JS.setup!
|
262
300
|
end
|
263
301
|
|
264
302
|
def initialize_windows
|
265
|
-
return unless
|
266
|
-
MainWindow.setup
|
303
|
+
return unless Desktop.enabled?
|
304
|
+
MainWindow.setup!
|
267
305
|
MainWindow.title = configuration.name
|
268
306
|
end
|
269
307
|
|
270
308
|
def initialize_trap
|
271
|
-
return unless
|
309
|
+
return unless Desktop.enabled?
|
272
310
|
trap("INT") {
|
273
|
-
|
311
|
+
Desktop::App.exit
|
274
312
|
}
|
275
313
|
end
|
276
314
|
|
315
|
+
def initialize_path
|
316
|
+
# Dir::tmpdir/Tempfile uses this
|
317
|
+
ENV["TMPDIR"] = Desktop::Path.temp if Desktop.enabled?
|
318
|
+
FileUtils.mkdir_p(Desktop::Path.user_data)
|
319
|
+
end
|
320
|
+
|
277
321
|
def initialize_marshal
|
278
322
|
return unless defined?(SuperModel)
|
279
|
-
|
280
|
-
|
323
|
+
path = configuration.marshal_path
|
324
|
+
path = path.call if path.is_a?(Proc)
|
325
|
+
SuperModel::Marshal.path = path
|
281
326
|
SuperModel::Marshal.load
|
282
327
|
at_exit {
|
283
328
|
SuperModel::Marshal.dump
|
@@ -287,6 +332,8 @@ module Bowline
|
|
287
332
|
def process
|
288
333
|
Bowline.configuration = configuration
|
289
334
|
|
335
|
+
set_environment
|
336
|
+
|
290
337
|
set_load_path
|
291
338
|
load_gems
|
292
339
|
|
@@ -314,16 +361,18 @@ module Bowline
|
|
314
361
|
load_plugins
|
315
362
|
load_application_classes
|
316
363
|
load_application_helpers
|
317
|
-
|
318
|
-
load_application_initializers
|
319
364
|
|
320
|
-
|
321
|
-
|
322
|
-
initialize_js
|
365
|
+
initialize_desktop
|
323
366
|
initialize_windows
|
324
367
|
initialize_trap
|
325
|
-
|
368
|
+
initialize_path
|
326
369
|
initialize_marshal
|
370
|
+
|
371
|
+
load_application_environment
|
372
|
+
load_application_initializers
|
373
|
+
load_application_first_run
|
374
|
+
|
375
|
+
after_initialize
|
327
376
|
|
328
377
|
Bowline.initialized = true
|
329
378
|
end
|
@@ -419,9 +468,8 @@ module Bowline
|
|
419
468
|
attr_accessor :time_zone
|
420
469
|
|
421
470
|
attr_accessor :plugin_glob
|
422
|
-
|
423
471
|
attr_accessor :helper_glob
|
424
|
-
|
472
|
+
attr_accessor :first_run_glob
|
425
473
|
attr_accessor :initializer_glob
|
426
474
|
|
427
475
|
# Set the application's name.
|
@@ -473,6 +521,7 @@ module Bowline
|
|
473
521
|
self.plugin_glob = default_plugin_glob
|
474
522
|
self.helper_glob = default_helper_glob
|
475
523
|
self.initializer_glob = default_initalizer_glob
|
524
|
+
self.first_run_glob = default_first_run_glob
|
476
525
|
self.publisher = default_publisher
|
477
526
|
self.copyright = default_copyright
|
478
527
|
|
@@ -589,7 +638,7 @@ module Bowline
|
|
589
638
|
end
|
590
639
|
|
591
640
|
def default_marshal_path
|
592
|
-
File.join(
|
641
|
+
Proc.new { File.join(Desktop::Path.user_data, 'marshal.db') }
|
593
642
|
end
|
594
643
|
|
595
644
|
def default_cache_classes
|
@@ -611,6 +660,10 @@ module Bowline
|
|
611
660
|
def default_initalizer_glob
|
612
661
|
File.join(root_path, *%w{ config initializers **/*.rb })
|
613
662
|
end
|
663
|
+
|
664
|
+
def default_first_run_glob
|
665
|
+
File.join(root_path, *%w{ config first_run **/*.rb })
|
666
|
+
end
|
614
667
|
|
615
668
|
def default_publisher
|
616
669
|
"Bowline"
|
data/lib/bowline/library.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
1
3
|
module Bowline
|
2
4
|
# Provides paths to Bowline's required libraries.
|
3
5
|
module Library
|
@@ -8,50 +10,32 @@ module Bowline
|
|
8
10
|
# Path to a folder stored under the users
|
9
11
|
# home directory containing the downloaded libraries.
|
10
12
|
def path
|
11
|
-
|
12
|
-
File.
|
13
|
+
Pathname.new(
|
14
|
+
File.expand_path(
|
15
|
+
File.join(Gem.user_home, ".bowline")
|
16
|
+
)
|
13
17
|
)
|
14
18
|
end
|
15
|
-
module_function :path
|
16
19
|
|
17
20
|
# Path to the bowline-desktop binary
|
18
21
|
def desktop_path
|
19
|
-
|
22
|
+
path.join("bowline-desktop")
|
20
23
|
end
|
21
|
-
module_function :desktop_path
|
22
24
|
|
23
25
|
def libs_path
|
24
|
-
|
26
|
+
path.join("libs")
|
25
27
|
end
|
26
|
-
module_function :libs_path
|
27
28
|
|
28
29
|
def local_build_path
|
29
|
-
|
30
|
+
Bowline.root.join("build")
|
30
31
|
end
|
31
|
-
module_function :local_build_path
|
32
32
|
|
33
33
|
# Returns true if all required libraries exist.
|
34
34
|
def ready?
|
35
35
|
File.exist?(desktop_path) &&
|
36
36
|
File.directory?(libs_path)
|
37
37
|
end
|
38
|
-
|
39
|
-
|
40
|
-
private
|
41
|
-
# Borrowed from Rubygems
|
42
|
-
def home_path
|
43
|
-
['HOME', 'USERPROFILE'].each do |homekey|
|
44
|
-
return ENV[homekey] if ENV[homekey]
|
45
|
-
end
|
46
|
-
if ENV['HOMEDRIVE'] && ENV['HOMEPATH'] then
|
47
|
-
return "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}"
|
48
|
-
end
|
49
|
-
begin
|
50
|
-
File.expand_path("~")
|
51
|
-
rescue
|
52
|
-
File::ALT_SEPARATOR ? "C:/" : "/"
|
53
|
-
end
|
54
|
-
end
|
55
|
-
module_function :home_path
|
38
|
+
|
39
|
+
extend self
|
56
40
|
end
|
57
41
|
end
|
data/lib/bowline/tasks/app.rake
CHANGED
@@ -1,9 +1,43 @@
|
|
1
1
|
require 'fileutils'
|
2
2
|
require 'erb'
|
3
3
|
require 'rbconfig'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'zip/zip'
|
4
6
|
|
5
7
|
namespace :app do
|
6
|
-
namespace :build do
|
8
|
+
namespace :build do
|
9
|
+
task :zip => :environment do
|
10
|
+
unless Bowline::Library.ready?
|
11
|
+
Rake::Task["libs:setup"].invoke
|
12
|
+
end
|
13
|
+
|
14
|
+
config = Bowline.configuration
|
15
|
+
|
16
|
+
build_path = Bowline::Library.local_build_path
|
17
|
+
FileUtils.mkdir_p(build_path)
|
18
|
+
|
19
|
+
app_path = File.join(build_path, "#{config.name}.zip")
|
20
|
+
FileUtils.rm_rf(app_path)
|
21
|
+
|
22
|
+
dirs = Dir[Bowline.root.join("**/**").to_s]
|
23
|
+
dirs.delete(build_path)
|
24
|
+
dirs.delete(Bowline.root.join("log").to_s)
|
25
|
+
dirs.delete(Bowline.root.join(*%w{db migrate}).to_s)
|
26
|
+
dirs.delete_if {|i| i =~ /\.svn|\.DS_Store|\.git/ }
|
27
|
+
|
28
|
+
Zip::ZipFile.open(app_path, Zip::ZipFile::CREATE) do |zf|
|
29
|
+
# This is horrible - but RubyZIP's API sucks
|
30
|
+
blank = Tempfile.new("blank")
|
31
|
+
zf.add("app_first_run", blank.path)
|
32
|
+
zf.add("app_production", blank.path)
|
33
|
+
|
34
|
+
dirs.each do |dir|
|
35
|
+
name = dir.sub(Bowline.root.to_s + "/", "")
|
36
|
+
zf.add(name, dir)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
7
41
|
task :osx => :environment do
|
8
42
|
unless Bowline::Library.ready?
|
9
43
|
Rake::Task["libs:setup"].invoke
|
@@ -11,7 +45,7 @@ namespace :app do
|
|
11
45
|
|
12
46
|
config = Bowline.configuration
|
13
47
|
assets_path = File.join(Bowline.assets_path, "osx")
|
14
|
-
build_path = Bowline::Library.local_build_path
|
48
|
+
build_path = Bowline::Library.local_build_path.to_s
|
15
49
|
app_path = File.join(build_path, "#{config.name}.app")
|
16
50
|
FileUtils.rm_rf(app_path)
|
17
51
|
contents_path = File.join(app_path, "Contents")
|
@@ -32,7 +66,7 @@ namespace :app do
|
|
32
66
|
# Make icon
|
33
67
|
makeicns = File.join(assets_path, "makeicns")
|
34
68
|
if config.icon
|
35
|
-
makeicns_in = File.expand_path(config.icon,
|
69
|
+
makeicns_in = File.expand_path(config.icon, Bowline.root)
|
36
70
|
else
|
37
71
|
makeicns_in = File.join(assets_path, "bowline.png")
|
38
72
|
end
|
@@ -41,13 +75,15 @@ namespace :app do
|
|
41
75
|
`#{makeicns} -in #{makeicns_in} -out #{makeicns_out}`
|
42
76
|
|
43
77
|
# Copy App
|
44
|
-
dirs = Dir[File.join(APP_ROOT,
|
78
|
+
dirs = Dir[File.join(APP_ROOT, "**")]
|
45
79
|
dirs.delete(build_path)
|
46
|
-
dirs.delete(File.join(APP_ROOT,
|
47
|
-
dirs.delete(File.join(APP_ROOT,
|
48
|
-
dirs.
|
49
|
-
dirs.
|
50
|
-
|
80
|
+
dirs.delete(File.join(APP_ROOT, "log"))
|
81
|
+
dirs.delete(File.join(APP_ROOT, *%w{db migrate}))
|
82
|
+
dirs.delete_if {|i| i =~ /\.svn|\.DS_Store|\.git/ }
|
83
|
+
FileUtils.cp_r(dirs, ".")
|
84
|
+
|
85
|
+
FileUtils.touch("app_production")
|
86
|
+
FileUtils.touch("app_first_run")
|
51
87
|
end
|
52
88
|
|
53
89
|
# Copy Bowline binary & libs
|
data/lib/bowline/tasks/libs.rake
CHANGED
@@ -34,14 +34,6 @@ def unzip(fpath, tpath)
|
|
34
34
|
}
|
35
35
|
end
|
36
36
|
|
37
|
-
def sym_or_copy(from, to)
|
38
|
-
begin
|
39
|
-
FileUtils.ln_s(from, to)
|
40
|
-
rescue NotImplementedError
|
41
|
-
FileUtils.cp_r(from, to)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
37
|
namespace :libs do
|
46
38
|
desc "Download Bowline's binary and pre-compiled libs"
|
47
39
|
task :download => :environment do
|
data/lib/bowline/version.rb
CHANGED
@@ -7,8 +7,4 @@ Bowline::Initializer.run do |config|
|
|
7
7
|
config.version = "0.0.1"
|
8
8
|
config.publisher = "Example"
|
9
9
|
config.url = "http://example.com"
|
10
|
-
|
11
|
-
# config.gem "activerecord"
|
12
|
-
# config.gem "net-mdns", :lib => 'net/dns/mdns'
|
13
|
-
# config.gem "rubyzip", :lib => 'zip/zip'
|
14
10
|
end
|
File without changes
|
File without changes
|
data/templates/main_window.rb
CHANGED
data/templates/script/init
CHANGED
data/templates/window.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 6
|
8
|
-
-
|
9
|
-
version: 0.6.
|
8
|
+
- 3
|
9
|
+
version: 0.6.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Alex MacCaw
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-04-06 00:00:00 +01:00
|
18
18
|
default_executable: bowline-gen
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- lib/bowline/commands/build.rb
|
119
119
|
- lib/bowline/commands/console.rb
|
120
120
|
- lib/bowline/commands/generate.rb
|
121
|
+
- lib/bowline/commands/init.rb
|
121
122
|
- lib/bowline/commands/run.rb
|
122
123
|
- lib/bowline/desktop.rb
|
123
124
|
- lib/bowline/desktop/app.rb
|
@@ -165,6 +166,8 @@ files:
|
|
165
166
|
- templates/config/boot.rb
|
166
167
|
- templates/config/database.yml
|
167
168
|
- templates/config/environment.rb
|
169
|
+
- templates/config/environments/development.rb
|
170
|
+
- templates/config/environments/production.rb
|
168
171
|
- templates/gitignore
|
169
172
|
- templates/helper.rb
|
170
173
|
- templates/main_window.rb
|