ruflet 0.0.9 → 0.0.11

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.
@@ -6,6 +6,7 @@ module Ruflet
6
6
  module CLI
7
7
  module ExtraCommand
8
8
  include FlutterSdk
9
+ include NewCommand
9
10
 
10
11
  def command_create(args)
11
12
  command_new(args)
@@ -15,9 +16,24 @@ module Ruflet
15
16
  verbose = args.delete("--verbose") || args.delete("-v")
16
17
  fix = args.delete("--fix")
17
18
  client_dir = detect_client_dir
19
+ template_root = resolve_ruflet_client_template_root
18
20
  puts "Ruflet doctor"
19
21
  puts " Ruby: #{RUBY_VERSION}"
20
22
  puts " Flutter host target: #{flutter_host || 'unsupported'}"
23
+ if template_root
24
+ puts " Template: #{template_root}"
25
+ elsif fix
26
+ template_root = ensure_cached_ruflet_client_template!(verbose: !!verbose)
27
+ unless template_root
28
+ warn " Template: missing"
29
+ warn "Failed to fetch the Ruflet Flutter template from GitHub."
30
+ return 1
31
+ end
32
+ puts " Template: #{template_root}"
33
+ else
34
+ warn " Template: missing"
35
+ warn "Run `ruflet doctor --fix` to fetch the Flutter template from GitHub."
36
+ end
21
37
  if fix
22
38
  tools = ensure_flutter!("doctor", client_dir: client_dir, auto_install: true)
23
39
  else
@@ -97,7 +113,7 @@ module Ruflet
97
113
  client_dir = detect_client_dir
98
114
  unless client_dir
99
115
  warn "Could not find Flutter client directory."
100
- warn "Set RUFLET_CLIENT_DIR or place client at ./ruflet_client"
116
+ warn "Set RUFLET_CLIENT_DIR or let Ruflet manage the client under ./build/client"
101
117
  warn "`ruflet debug` requires Flutter client source code."
102
118
  warn "For prebuilt clients, use: `ruflet run --web` or `ruflet run --desktop`."
103
119
  return 1
@@ -132,6 +148,9 @@ module Ruflet
132
148
  env_dir = ENV["RUFLET_CLIENT_DIR"]
133
149
  return env_dir if env_dir && Dir.exist?(env_dir)
134
150
 
151
+ hidden = File.expand_path(File.join("build", "client"), Dir.pwd)
152
+ return hidden if Dir.exist?(hidden)
153
+
135
154
  local = File.expand_path("ruflet_client", Dir.pwd)
136
155
  return local if Dir.exist?(local)
137
156
 
@@ -75,7 +75,7 @@ module Ruflet
75
75
  system(fvm_env, fvm, "install", version.to_s, chdir: project_dir, out: File::NULL, err: File::NULL)
76
76
  system(fvm_env, fvm, "use", "--force", version.to_s, chdir: project_dir, out: File::NULL, err: File::NULL)
77
77
 
78
- flutter = File.join(project_dir, ".fvm", "flutter_sdk", "bin", windows_host? ? "flutter.bat" : "flutter")
78
+ flutter = flutter_bin_path(project_dir)
79
79
  return nil unless File.executable?(flutter)
80
80
 
81
81
  tools_from_flutter_bin(flutter)
@@ -91,28 +91,35 @@ module Ruflet
91
91
  dart = which_command("dart")
92
92
  unless dart
93
93
  sdk_root = ensure_flutter_sdk_downloaded(client_dir: client_dir)
94
- dart = sdk_root ? File.join(sdk_root, "bin", windows_host? ? "dart.bat" : "dart") : nil
94
+ dart = sdk_root ? File.join(sdk_root, "bin", dart_executable_name) : nil
95
95
  end
96
96
  return nil unless dart && File.executable?(dart)
97
97
 
98
98
  system(dart, "pub", "global", "activate", "fvm", out: File::NULL, err: File::NULL)
99
+ installed_fvm = File.join(pub_cache_bin_dir, fvm_executable_name)
100
+ return installed_fvm if File.executable?(installed_fvm)
101
+
99
102
  which_command("fvm")
100
103
  end
101
104
 
102
105
  def fvm_env
103
- pub_bin = File.join(Dir.home, ".pub-cache", "bin")
104
- { "PATH" => "#{pub_bin}#{File::PATH_SEPARATOR}#{ENV.fetch('PATH', '')}" }
106
+ { "PATH" => "#{pub_cache_bin_dir}#{File::PATH_SEPARATOR}#{ENV.fetch('PATH', '')}" }
105
107
  end
106
108
 
107
109
  def tools_from_flutter_bin(flutter_bin)
108
110
  return nil unless File.executable?(flutter_bin)
109
111
 
110
112
  bin_dir = File.dirname(flutter_bin)
111
- dart = File.join(bin_dir, windows_host? ? "dart.bat" : "dart")
113
+ sdk_root = File.expand_path("..", bin_dir)
114
+ dart = File.join(bin_dir, dart_executable_name)
112
115
  {
113
116
  flutter: flutter_bin,
114
117
  dart: (File.executable?(dart) ? dart : "dart"),
115
- env: { "PATH" => "#{bin_dir}#{File::PATH_SEPARATOR}#{ENV.fetch('PATH', '')}" }
118
+ env: {
119
+ "PATH" => "#{bin_dir}#{File::PATH_SEPARATOR}#{pub_cache_bin_dir}#{File::PATH_SEPARATOR}#{ENV.fetch('PATH', '')}",
120
+ "FLUTTER_ROOT" => sdk_root,
121
+ "FVM_FLUTTER_SDK" => sdk_root
122
+ }
116
123
  }
117
124
  end
118
125
 
@@ -125,7 +132,7 @@ module Ruflet
125
132
  archive = release.fetch("archive")
126
133
  install_root = File.join(Dir.home, ".ruflet", "flutter", release.fetch("version"), host)
127
134
  sdk_root = File.join(install_root, "flutter")
128
- flutter_bin = File.join(sdk_root, "bin", windows_host? ? "flutter.bat" : "flutter")
135
+ flutter_bin = File.join(sdk_root, "bin", flutter_executable_name)
129
136
  return sdk_root if File.executable?(flutter_bin)
130
137
 
131
138
  FileUtils.mkdir_p(install_root)
@@ -138,9 +145,9 @@ module Ruflet
138
145
  return sdk_root if File.executable?(flutter_bin)
139
146
 
140
147
  # Some archives may unpack into a different folder name.
141
- guessed = Dir.glob(File.join(install_root, "**", windows_host? ? "flutter.bat" : "flutter"))
148
+ guessed = Dir.glob(File.join(install_root, "**", flutter_executable_name))
142
149
  .map { |p| File.expand_path("../..", p) }
143
- .find { |root| File.executable?(File.join(root, "bin", windows_host? ? "flutter.bat" : "flutter")) }
150
+ .find { |root| File.executable?(File.join(root, "bin", flutter_executable_name)) }
144
151
  return guessed if guessed
145
152
 
146
153
  nil
@@ -195,12 +202,16 @@ module Ruflet
195
202
  end
196
203
 
197
204
  def existing_fvm_flutter_bin(project_dir)
198
- flutter = File.join(project_dir, ".fvm", "flutter_sdk", "bin", windows_host? ? "flutter.bat" : "flutter")
205
+ flutter = flutter_bin_path(project_dir)
199
206
  return flutter if File.executable?(flutter)
200
207
 
201
208
  nil
202
209
  end
203
210
 
211
+ def flutter_bin_path(project_dir)
212
+ File.join(project_dir, ".fvm", "flutter_sdk", "bin", flutter_executable_name)
213
+ end
214
+
204
215
  def find_fvmrc(client_dir)
205
216
  candidates = []
206
217
  candidates << File.join(client_dir, ".fvmrc") if client_dir
@@ -308,6 +319,22 @@ module Ruflet
308
319
  RbConfig::CONFIG["host_os"].match?(/mswin|mingw|cygwin/i)
309
320
  end
310
321
 
322
+ def flutter_executable_name
323
+ windows_host? ? "flutter.bat" : "flutter"
324
+ end
325
+
326
+ def dart_executable_name
327
+ windows_host? ? "dart.bat" : "dart"
328
+ end
329
+
330
+ def fvm_executable_name
331
+ windows_host? ? "fvm.bat" : "fvm"
332
+ end
333
+
334
+ def pub_cache_bin_dir
335
+ File.join(Dir.home, ".pub-cache", "bin")
336
+ end
337
+
311
338
  def which_command(name)
312
339
  exts = windows_host? ? ENV.fetch("PATHEXT", ".EXE;.BAT;.CMD").split(";") : [""]
313
340
  ENV.fetch("PATH", "").split(File::PATH_SEPARATOR).each do |dir|
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "fileutils"
4
+ require "tmpdir"
4
5
  require "yaml"
5
6
 
6
7
  module Ruflet
@@ -43,33 +44,91 @@ module Ruflet
43
44
  File.write(File.join(root, "Gemfile"), Ruflet::CLI::GEMFILE_TEMPLATE)
44
45
  File.write(File.join(root, "README.md"), format(Ruflet::CLI::README_TEMPLATE, app_name: File.basename(root)))
45
46
  write_default_ruflet_config(root, File.basename(root))
46
- copy_ruflet_client_template(root)
47
- configure_ruflet_client(root)
48
-
47
+ copy_default_project_assets(root)
49
48
  project_name = File.basename(root)
50
49
  puts "Run:"
51
50
  puts " cd #{project_name}"
52
51
  puts " bundle install"
53
52
  puts " bundle exec ruflet run main.rb"
54
53
  puts
55
- puts "Client template:"
56
- puts " cd ruflet_client"
57
- puts " flutter pub get"
58
- puts " flutter run"
54
+ puts "Build:"
55
+ puts " bundle exec ruflet build android --self"
56
+ puts " bundle exec ruflet build ios --self"
59
57
  0
60
58
  end
61
59
 
62
60
  private
63
61
 
64
62
  def copy_ruflet_client_template(root)
65
- template_root = File.expand_path("../../../../../ruflet_client", __dir__)
66
- return unless Dir.exist?(template_root)
63
+ template_root = resolve_ruflet_client_template_root || ensure_cached_ruflet_client_template!
64
+ return unless template_root && Dir.exist?(template_root)
67
65
 
68
- target = File.join(root, "ruflet_client")
66
+ target = hidden_flutter_client_dir(root)
67
+ FileUtils.mkdir_p(File.dirname(target))
69
68
  FileUtils.cp_r(template_root, target)
70
69
  prune_client_template(target)
71
70
  end
72
71
 
72
+ def hidden_flutter_client_dir(root = Dir.pwd)
73
+ File.join(root, "build", "client")
74
+ end
75
+
76
+ def resolve_ruflet_client_template_root
77
+ repo_template = File.expand_path("../../../../../templates/ruflet_flutter_template", __dir__)
78
+ return repo_template if Dir.exist?(repo_template)
79
+
80
+ cached_template = cached_ruflet_client_template_root
81
+ return cached_template if Dir.exist?(cached_template)
82
+
83
+ fallback = File.expand_path("../../../../../ruflet_client", __dir__)
84
+ return fallback if Dir.exist?(fallback)
85
+
86
+ nil
87
+ end
88
+
89
+ def ensure_cached_ruflet_client_template!(verbose: false)
90
+ cached_template = cached_ruflet_client_template_root
91
+ return cached_template if Dir.exist?(cached_template)
92
+
93
+ download_ruflet_client_template(verbose: verbose)
94
+ end
95
+
96
+ def cached_ruflet_client_template_root
97
+ File.join(template_cache_root, "ruflet_flutter_template")
98
+ end
99
+
100
+ def template_cache_root
101
+ File.join(Dir.home, ".ruflet", "templates")
102
+ end
103
+
104
+ def download_ruflet_client_template(verbose: false)
105
+ target = cached_ruflet_client_template_root
106
+ FileUtils.mkdir_p(template_cache_root)
107
+
108
+ Dir.mktmpdir("ruflet-template") do |tmp|
109
+ repo_dir = File.join(tmp, "Ruflet")
110
+ clone_cmd = ["git", "clone", "--depth", "1", "--filter=blob:none", "--sparse", "https://github.com/AdamMusa/Ruflet.git", repo_dir]
111
+ return nil unless run_template_command(clone_cmd, verbose: verbose)
112
+ return nil unless run_template_command(["git", "-C", repo_dir, "sparse-checkout", "set", "templates/ruflet_flutter_template"], verbose: verbose)
113
+
114
+ source = File.join(repo_dir, "templates", "ruflet_flutter_template")
115
+ return nil unless Dir.exist?(source)
116
+
117
+ FileUtils.rm_rf(target)
118
+ FileUtils.cp_r(source, target)
119
+ end
120
+
121
+ target
122
+ rescue StandardError => e
123
+ warn "Failed to fetch Ruflet template: #{e.class}: #{e.message}"
124
+ nil
125
+ end
126
+
127
+ def run_template_command(cmd, verbose: false)
128
+ output = verbose ? $stdout : File::NULL
129
+ system(*cmd, out: output, err: verbose ? $stderr : File::NULL)
130
+ end
131
+
73
132
  def prune_client_template(target)
74
133
  paths = %w[
75
134
  .dart_tool
@@ -83,6 +142,7 @@ module Ruflet
83
142
  android/.gradle
84
143
  android/.kotlin
85
144
  android/local.properties
145
+ pubspec_overrides.yaml
86
146
  ]
87
147
  paths.each do |path|
88
148
  full = File.join(target, path)
@@ -94,9 +154,14 @@ module Ruflet
94
154
  File.write(File.join(root, "ruflet.yaml"), <<~YAML)
95
155
  app:
96
156
  name: #{app_name}
97
- # Optional production client endpoint used by `ruflet build`.
157
+ display_name: #{humanize_name(app_name)}
158
+ package_name: #{app_name.gsub(/[^a-zA-Z0-9_]+/, "_").downcase}
159
+ organization: com.example
160
+ version: 1.0.0+1
161
+ description: A new Ruflet app.
162
+ # Required for server-driven builds: `ruflet build ios`, `apk`, `web`, etc. without `--self`.
98
163
  # Example: https://api.example.com
99
- ruflet_client_url: ""
164
+ backend_url: ""
100
165
 
101
166
  # Source of truth for Flutter client extensions/plugins.
102
167
  # Examples: camera, video, audio, flashlight, webview, map
@@ -117,100 +182,27 @@ module Ruflet
117
182
  YAML
118
183
  end
119
184
 
120
- def configure_ruflet_client(root)
121
- config_path = File.join(root, "ruflet.yaml")
122
- return unless File.file?(config_path)
123
-
124
- config = YAML.safe_load(File.read(config_path), aliases: true) || {}
125
- extension_keys = extract_extension_keys(config)
126
- extension_packages = extension_keys.filter_map { |key| CLIENT_EXTENSION_MAP[key]&.fetch(:package) }.uniq
127
- extension_aliases = extension_keys.filter_map { |key| CLIENT_EXTENSION_MAP[key]&.fetch(:alias) }.uniq
128
-
129
- client_dir = File.join(root, "ruflet_client")
130
- apply_client_manifest!(client_dir, extension_packages, extension_aliases)
131
- rescue StandardError => e
132
- warn "Failed to configure ruflet_client from ruflet.yaml: #{e.class}: #{e.message}"
133
- end
134
-
135
- def extract_extension_keys(config)
136
- from_services = Array(config["services"])
137
-
138
- from_services
139
- .map { |v| normalize_extension_key(v) }
140
- .compact
141
- .uniq
142
- end
143
-
144
- def normalize_extension_key(value)
145
- key = value.to_s.strip.downcase
146
- return nil if key.empty?
147
-
148
- key.tr!("-", "_")
149
- key.gsub!(/\A(flet_)+/, "")
150
- key.gsub!(/\Aservice_/, "")
151
- key.gsub!(/\Acontrol_/, "")
152
- key = "file_picker" if key == "filepicker"
153
- key
154
- end
155
-
156
- def apply_client_manifest!(client_dir, extension_packages, extension_aliases)
157
- return unless Dir.exist?(client_dir)
158
-
159
- pubspec_path = File.join(client_dir, "pubspec.yaml")
160
- main_path = File.join(client_dir, "lib", "main.dart")
161
- prune_client_pubspec(pubspec_path, extension_packages) if File.file?(pubspec_path)
162
- prune_client_main(main_path, extension_aliases) if File.file?(main_path)
163
- end
164
-
165
- def prune_client_pubspec(path, selected_packages)
166
- data = YAML.safe_load(File.read(path), aliases: true) || {}
167
- deps = (data["dependencies"] || {}).dup
185
+ def copy_default_project_assets(root)
186
+ assets_dir = File.join(root, "assets")
187
+ FileUtils.mkdir_p(assets_dir)
168
188
 
169
- deps.keys.each do |name|
170
- next unless name.start_with?("flet_")
171
- next if name == "flet"
172
- next if selected_packages.include?(name)
189
+ default_project_assets_root.each do |source_root|
190
+ next unless Dir.exist?(source_root)
173
191
 
174
- deps.delete(name)
175
- end
176
-
177
- data["dependencies"] = deps
178
- File.write(path, YAML.dump(data))
179
- end
180
-
181
- def prune_client_main(path, selected_aliases)
182
- lines = File.readlines(path)
183
- alias_to_package = {}
184
-
185
- lines.each do |line|
186
- match = line.match(%r{\Aimport 'package:(flet_[^/]+)/\1\.dart' as ([a-zA-Z0-9_]+);})
187
- next unless match
188
-
189
- alias_to_package[match[2]] = match[1]
190
- end
191
-
192
- kept = lines.select do |line|
193
- import_match = line.match(%r{\Aimport 'package:(flet_[^/]+)/\1\.dart' as ([a-zA-Z0-9_]+);})
194
- if import_match
195
- package_name = import_match[1]
196
- next true if package_name == "flet"
197
- next true if selected_aliases.include?(import_match[2])
198
- next false
199
- end
200
-
201
- extension_match = line.match(/\A\s*([a-zA-Z0-9_]+)\.Extension\(\),\s*\z/)
202
- if extension_match
203
- extension_alias = extension_match[1]
204
- package_name = alias_to_package[extension_alias]
205
- next true if package_name.nil? # non-Flet extension lines
206
- next true if selected_aliases.include?(extension_alias)
207
- next false
192
+ %w[icon.png splash.png].each do |filename|
193
+ source = File.join(source_root, filename)
194
+ FileUtils.cp(source, File.join(assets_dir, filename)) if File.file?(source)
208
195
  end
209
-
210
- true
196
+ return if File.file?(File.join(assets_dir, "icon.png")) && File.file?(File.join(assets_dir, "splash.png"))
211
197
  end
198
+ end
212
199
 
213
- File.write(path, kept.join)
200
+ def default_project_assets_root
201
+ [
202
+ File.expand_path("../../../assets", __dir__),
203
+ File.expand_path("../../../../../templates/ruflet_flutter_template/assets", __dir__),
204
+ File.expand_path("../../../../../ruflet_client/assets", __dir__)
205
+ ]
214
206
  end
215
207
 
216
208
  def humanize_name(name)
@@ -40,6 +40,7 @@ module Ruflet
40
40
  "RUFLET_SUPPRESS_SERVER_BANNER" => "1",
41
41
  "RUFLET_PORT" => selected_port.to_s
42
42
  }
43
+ apply_local_ruflet_dev_overrides(env)
43
44
  assets_dir = File.join(File.dirname(script_path), "assets")
44
45
  env["RUFLET_ASSETS_DIR"] = assets_dir if File.directory?(assets_dir)
45
46
 
@@ -105,6 +106,24 @@ module Ruflet
105
106
  [RbConfig.ruby, script_path]
106
107
  end
107
108
 
109
+ def apply_local_ruflet_dev_overrides(env)
110
+ lib_paths = local_ruflet_dev_lib_paths
111
+ return if lib_paths.empty?
112
+
113
+ existing = env["RUBYLIB"].to_s
114
+ segments = lib_paths + existing.split(File::PATH_SEPARATOR).reject(&:empty?)
115
+ env["RUBYLIB"] = segments.uniq.join(File::PATH_SEPARATOR)
116
+ puts "Ruflet dev source: #{lib_paths.join(", ")}"
117
+ end
118
+
119
+ def local_ruflet_dev_lib_paths
120
+ repo_root = File.expand_path("../../../../../", __dir__)
121
+ package_roots = %w[ruflet_core ruflet_server].map { |name| File.join(repo_root, "packages", name, "lib") }
122
+ return [] unless package_roots.all? { |path| Dir.exist?(path) }
123
+
124
+ package_roots
125
+ end
126
+
108
127
  def resolve_script(token)
109
128
  path = File.expand_path(token, Dir.pwd)
110
129
  return path if File.file?(path)
@@ -7,7 +7,7 @@ module Ruflet
7
7
  Ruflet.run do |page|
8
8
  page.title = "Counter Demo"
9
9
  count = 0
10
- count_text = text(count.to_s, size: 40)
10
+ count_text = text(count.to_s, style: {size: 40})
11
11
  page.add(
12
12
  container(
13
13
  expand: true,
@@ -22,7 +22,7 @@ module Ruflet
22
22
  )
23
23
  ),
24
24
  floating_action_button: fab(
25
- icon: Ruflet::MaterialIcons::ADD,
25
+ icon: "add",
26
26
  on_click: ->(_e) do
27
27
  count += 1
28
28
  page.update(count_text, value: count.to_s)
@@ -36,8 +36,8 @@ module Ruflet
36
36
  GEMFILE_TEMPLATE = <<~GEMFILE
37
37
  source "https://rubygems.org"
38
38
 
39
- gem "ruflet_core", ">= 0.0.9"
40
- gem "ruflet_server", ">= 0.0.9"
39
+ gem "ruflet_core", ">= 0.0.10"
40
+ gem "ruflet_server", ">= 0.0.10"
41
41
  GEMFILE
42
42
 
43
43
  README_TEMPLATE = <<~MD
data/lib/ruflet/cli.rb CHANGED
@@ -39,6 +39,8 @@ module Ruflet
39
39
  command_debug(argv)
40
40
  when "build"
41
41
  command_build(argv)
42
+ when "install"
43
+ command_install(argv)
42
44
  when "devices"
43
45
  command_devices(argv)
44
46
  when "emulators"
@@ -66,7 +68,8 @@ module Ruflet
66
68
  ruflet run [scriptname|path] [--web|--desktop] [--port PORT]
67
69
  ruflet update [web|desktop|all] [--check] [--force] [--platform PLATFORM]
68
70
  ruflet debug [scriptname|path]
69
- ruflet build <apk|android|ios|aab|web|macos|windows|linux>
71
+ ruflet build <apk|android|ios|aab|web|macos|windows|linux> [--self] [--verbose]
72
+ ruflet install [--device DEVICE_ID] [--verbose]
70
73
  ruflet devices
71
74
  ruflet emulators
72
75
  ruflet doctor
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ruflet
4
- VERSION = "0.0.9" unless const_defined?(:VERSION)
4
+ VERSION = "0.0.11" unless const_defined?(:VERSION)
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruflet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - AdamMusa
@@ -23,34 +23,6 @@ dependencies:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
25
  version: '2.2'
26
- - !ruby/object:Gem::Dependency
27
- name: ruflet_core
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - '='
31
- - !ruby/object:Gem::Version
32
- version: 0.0.9
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - '='
38
- - !ruby/object:Gem::Version
39
- version: 0.0.9
40
- - !ruby/object:Gem::Dependency
41
- name: ruflet_server
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - '='
45
- - !ruby/object:Gem::Version
46
- version: 0.0.9
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - '='
52
- - !ruby/object:Gem::Version
53
- version: 0.0.9
54
26
  description: Ruflet command line interface for creating, updating, building, and running
55
27
  Ruflet apps.
56
28
  email:
@@ -61,6 +33,8 @@ extensions: []
61
33
  extra_rdoc_files: []
62
34
  files:
63
35
  - README.md
36
+ - assets/icon.png
37
+ - assets/splash.png
64
38
  - bin/ruflet
65
39
  - lib/ruflet/cli.rb
66
40
  - lib/ruflet/cli/build_command.rb