glimmer-dsl-libui 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +230 -125
- data/VERSION +1 -1
- data/bin/girb +1 -1
- data/bin/glimmer +30 -0
- data/glimmer-dsl-libui.gemspec +0 -0
- data/lib/glimmer/Rakefile +26 -0
- data/lib/glimmer/launcher.rb +231 -0
- data/lib/glimmer/rake_task/list.rb +105 -0
- data/lib/glimmer/rake_task/scaffold.rb +839 -0
- data/lib/glimmer/rake_task.rb +192 -0
- metadata +41 -12
@@ -0,0 +1,231 @@
|
|
1
|
+
# Copyright (c) 2007-2023 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
if ARGV.include?('--bundler') && File.exist?(File.expand_path('./Gemfile'))
|
23
|
+
require 'bundler'
|
24
|
+
Bundler.setup(:default)
|
25
|
+
end
|
26
|
+
require 'fileutils'
|
27
|
+
require 'os'
|
28
|
+
|
29
|
+
module Glimmer
|
30
|
+
# Launcher of glimmer applications and main entry point for the `glimmer` command.
|
31
|
+
class Launcher
|
32
|
+
# TODO update the verbiage below for Glimmer DSL for LibUI
|
33
|
+
TEXT_USAGE = <<~MULTI_LINE_STRING
|
34
|
+
Glimmer DSL for LibUI (Prerequisite-Free Ruby Desktop Development Cross-Platform Native GUI Library) - Ruby Gem: glimmer-dsl-libui v#{File.read(File.expand_path('../../../VERSION', __FILE__))}
|
35
|
+
Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-ruby-option]...] (application.rb or task[task_args])
|
36
|
+
|
37
|
+
Runs Glimmer applications and tasks.
|
38
|
+
|
39
|
+
When applications are specified, they are run using Ruby,
|
40
|
+
automatically preloading the glimmer-dsl-libui Ruby gem.
|
41
|
+
|
42
|
+
Optionally, extra Glimmer options, Ruby options, and/or environment variables may be passed in.
|
43
|
+
|
44
|
+
Glimmer options:
|
45
|
+
- "--bundler=GROUP" : Activates gems in Bundler default group in Gemfile
|
46
|
+
- "--pd=BOOLEAN" : Requires puts_debuggerer to enable pd method
|
47
|
+
- "--quiet=BOOLEAN" : Does not announce file path of Glimmer application being launched
|
48
|
+
- "--debug" : Displays extra debugging information and enables debug logging
|
49
|
+
- "--log-level=VALUE" : Sets Glimmer's Ruby logger level ("ERROR" / "WARN" / "INFO" / "DEBUG"; default is none)
|
50
|
+
|
51
|
+
Tasks are run via rake. Some tasks take arguments in square brackets (surround with double-quotes if using Zsh).
|
52
|
+
|
53
|
+
Available tasks are below (if you do not see any, please add `require 'glimmer/rake_task'` to Rakefile and rerun or run rake -T):
|
54
|
+
|
55
|
+
MULTI_LINE_STRING
|
56
|
+
|
57
|
+
GLIMMER_LIB_GEM = 'glimmer-dsl-libui'
|
58
|
+
GLIMMER_LIB_LOCAL = File.expand_path(File.join('lib', "#{GLIMMER_LIB_GEM}.rb"))
|
59
|
+
GLIMMER_OPTIONS = %w[--log-level --quiet --bundler --pd]
|
60
|
+
GLIMMER_OPTION_ENV_VAR_MAPPING = {
|
61
|
+
'--log-level' => 'GLIMMER_LOGGER_LEVEL' ,
|
62
|
+
'--bundler' => 'GLIMMER_BUNDLER_SETUP' ,
|
63
|
+
'--pd' => 'PD' ,
|
64
|
+
}
|
65
|
+
REGEX_RAKE_TASK_WITH_ARGS = /^([^\[]+)\[?([^\]]*)\]?$/
|
66
|
+
|
67
|
+
class << self
|
68
|
+
def is_arm64?
|
69
|
+
host_cpu = OS.host_cpu.downcase
|
70
|
+
host_cpu.include?('aarch64') || host_cpu.include?('arm')
|
71
|
+
end
|
72
|
+
|
73
|
+
def glimmer_lib
|
74
|
+
unless @glimmer_lib
|
75
|
+
@glimmer_lib = GLIMMER_LIB_GEM
|
76
|
+
if File.exist?(GLIMMER_LIB_LOCAL)
|
77
|
+
@glimmer_lib = GLIMMER_LIB_LOCAL
|
78
|
+
puts "[DEVELOPMENT MODE] (detected #{@glimmer_lib})"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
@glimmer_lib
|
82
|
+
end
|
83
|
+
|
84
|
+
def dev_mode?
|
85
|
+
glimmer_lib == GLIMMER_LIB_LOCAL
|
86
|
+
end
|
87
|
+
|
88
|
+
def glimmer_option_env_vars(glimmer_options)
|
89
|
+
GLIMMER_OPTION_ENV_VAR_MAPPING.reduce({}) do |hash, pair|
|
90
|
+
glimmer_options[pair.first] ? hash.merge(GLIMMER_OPTION_ENV_VAR_MAPPING[pair.first] => glimmer_options[pair.first]) : hash
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def load_env_vars(env_vars)
|
95
|
+
env_vars.each do |key, value|
|
96
|
+
ENV[key] = value
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def launch(application, ruby_options: [], env_vars: {}, glimmer_options: {})
|
101
|
+
ruby_options_string = ruby_options.join(' ') + ' ' if ruby_options.any?
|
102
|
+
env_vars = env_vars.merge(glimmer_option_env_vars(glimmer_options))
|
103
|
+
env_vars.each do |k,v|
|
104
|
+
ENV[k] = v
|
105
|
+
end
|
106
|
+
the_glimmer_lib = glimmer_lib
|
107
|
+
require 'puts_debuggerer' if the_glimmer_lib == GLIMMER_LIB_LOCAL
|
108
|
+
is_rake_task = !application.end_with?('.rb')
|
109
|
+
rake_tasks = []
|
110
|
+
if is_rake_task
|
111
|
+
load File.expand_path('./Rakefile') if File.exist?(File.expand_path('./Rakefile')) && caller.join("\n").include?('/bin/glimmer:')
|
112
|
+
require_relative 'rake_task'
|
113
|
+
rake_tasks = Rake.application.tasks.map(&:to_s).map {|t| t.sub('glimmer:', '')}
|
114
|
+
|
115
|
+
potential_rake_task_parts = application.match(REGEX_RAKE_TASK_WITH_ARGS)
|
116
|
+
application = potential_rake_task_parts[1]
|
117
|
+
rake_task_args = potential_rake_task_parts[2].split(',')
|
118
|
+
end
|
119
|
+
if rake_tasks.include?(application)
|
120
|
+
load_env_vars(glimmer_option_env_vars(glimmer_options))
|
121
|
+
rake_task = "glimmer:#{application}"
|
122
|
+
puts "Running Glimmer rake task: #{rake_task}" if ruby_options_string.to_s.include?('--debug')
|
123
|
+
Rake::Task[rake_task].invoke(*rake_task_args)
|
124
|
+
else
|
125
|
+
puts "Launching Glimmer Application: #{application}" if ruby_options_string.to_s.include?('--debug') || glimmer_options['--quiet'].to_s.downcase != 'true'
|
126
|
+
require the_glimmer_lib
|
127
|
+
load File.expand_path(application)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
attr_reader :application_paths
|
133
|
+
attr_reader :env_vars
|
134
|
+
attr_reader :glimmer_options
|
135
|
+
attr_reader :ruby_options
|
136
|
+
|
137
|
+
def initialize(raw_options)
|
138
|
+
raw_options << '--quiet' if !caller.join("\n").include?('/bin/glimmer:') && !raw_options.join.include?('--quiet=')
|
139
|
+
raw_options << '--log-level=DEBUG' if raw_options.join.include?('--debug') && !raw_options.join.include?('--log-level=')
|
140
|
+
@application_path = extract_application_path(raw_options)
|
141
|
+
@env_vars = extract_env_vars(raw_options)
|
142
|
+
@glimmer_options = extract_glimmer_options(raw_options)
|
143
|
+
@ruby_options = raw_options
|
144
|
+
end
|
145
|
+
|
146
|
+
def launch
|
147
|
+
if @application_path.nil?
|
148
|
+
display_usage
|
149
|
+
else
|
150
|
+
launch_application
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def launch_application
|
157
|
+
self.class.launch(
|
158
|
+
@application_path,
|
159
|
+
ruby_options: @ruby_options,
|
160
|
+
env_vars: @env_vars,
|
161
|
+
glimmer_options: @glimmer_options
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
def display_usage
|
166
|
+
puts TEXT_USAGE
|
167
|
+
display_tasks
|
168
|
+
end
|
169
|
+
|
170
|
+
def display_tasks
|
171
|
+
if OS.windows? || Launcher.is_arm64?
|
172
|
+
require 'rake'
|
173
|
+
Rake::TaskManager.record_task_metadata = true
|
174
|
+
require_relative 'rake_task'
|
175
|
+
tasks = Rake.application.tasks
|
176
|
+
task_lines = tasks.reject do |task|
|
177
|
+
task.comment.nil?
|
178
|
+
end.map do |task|
|
179
|
+
max_task_size = tasks.map(&:name_with_args).map(&:size).max + 1
|
180
|
+
task_name = task.name_with_args.sub('glimmer:', '')
|
181
|
+
line = "glimmer #{task_name.ljust(max_task_size)} # #{task.comment}"
|
182
|
+
end
|
183
|
+
puts task_lines.to_a
|
184
|
+
else
|
185
|
+
require 'rake-tui'
|
186
|
+
require 'tty-screen'
|
187
|
+
require_relative 'rake_task'
|
188
|
+
Rake::TUI.run(branding_header: nil, prompt_question: 'Select a Glimmer task to run:') do |task, tasks|
|
189
|
+
max_task_size = tasks.map(&:name_with_args).map(&:size).max + 1
|
190
|
+
task_name = task.name_with_args.sub('glimmer:', '')
|
191
|
+
line = "glimmer #{task_name.ljust(max_task_size)} # #{task.comment}"
|
192
|
+
bound = TTY::Screen.width - 6
|
193
|
+
line.size <= bound ? line : "#{line[0..(bound - 3)]}..."
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Extract application path (which can also be a rake task, basically a non-arg)
|
199
|
+
def extract_application_path(options)
|
200
|
+
application_path = options.detect do |option|
|
201
|
+
!option.start_with?('-') && !option.include?('=')
|
202
|
+
end.tap do
|
203
|
+
options.delete(application_path)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def extract_env_vars(options)
|
208
|
+
options.select do |option|
|
209
|
+
!option.start_with?('-') && option.include?('=')
|
210
|
+
end.each do |env_var|
|
211
|
+
options.delete(env_var)
|
212
|
+
end.reduce({}) do |hash, env_var_string|
|
213
|
+
match = env_var_string.match(/^([^=]+)=(.+)$/)
|
214
|
+
hash.merge(match[1] => match[2])
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def extract_glimmer_options(options)
|
219
|
+
options.select do |option|
|
220
|
+
GLIMMER_OPTIONS.reduce(false) do |result, glimmer_option|
|
221
|
+
result || option.include?(glimmer_option)
|
222
|
+
end
|
223
|
+
end.each do |glimmer_option|
|
224
|
+
options.delete(glimmer_option)
|
225
|
+
end.reduce({}) do |hash, glimmer_option_string|
|
226
|
+
match = glimmer_option_string.match(/^([^=]+)=?(.+)?$/)
|
227
|
+
hash.merge(match[1] => (match[2] || 'true'))
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# Copyright (c) 2007-2023 Andy Maleh
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
# a copy of this software and associated documentation files (the
|
5
|
+
# "Software"), to deal in the Software without restriction, including
|
6
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
# the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be
|
12
|
+
# included in all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
22
|
+
require 'facets'
|
23
|
+
require 'text-table'
|
24
|
+
|
25
|
+
module Glimmer
|
26
|
+
module RakeTask
|
27
|
+
# Lists Glimmer related gems to use in rake_task.rb
|
28
|
+
class List
|
29
|
+
class << self
|
30
|
+
REGEX_GEM_LINE = /^([^\(]+) \(([^\)]+)\)$/
|
31
|
+
|
32
|
+
def custom_control_gems(query=nil)
|
33
|
+
list_gems('glimmer-cw-', query) do |result|
|
34
|
+
puts
|
35
|
+
puts " Glimmer Custom Control Gems#{" matching [#{query}]" if query} at rubygems.org:"
|
36
|
+
puts result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def custom_window_gems(query=nil)
|
41
|
+
list_gems('glimmer-cs-', query) do |result|
|
42
|
+
puts
|
43
|
+
puts " Glimmer Custom Window Gems#{" matching [#{query}]" if query} at rubygems.org:"
|
44
|
+
puts result
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def custom_shape_gems(query=nil)
|
49
|
+
list_gems('glimmer-cp-', query) do |result|
|
50
|
+
puts
|
51
|
+
puts " Glimmer Custom Shape Gems#{" matching [#{query}]" if query} at rubygems.org:"
|
52
|
+
puts result
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def dsl_gems(query=nil)
|
57
|
+
list_gems('glimmer-dsl-', query) do |result|
|
58
|
+
puts
|
59
|
+
puts " Glimmer DSL Gems#{" matching [#{query}]" if query} at rubygems.org:"
|
60
|
+
puts result
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def list_gems(gem_prefix, query=nil, &printer)
|
65
|
+
lines = `gem search -d #{gem_prefix}`.split("\n")
|
66
|
+
gems = lines.slice_before {|l| l.match(REGEX_GEM_LINE) }.to_a
|
67
|
+
gems = gems.map do |gem|
|
68
|
+
{
|
69
|
+
name: gem[0].match(REGEX_GEM_LINE)[1],
|
70
|
+
version: gem[0].match(REGEX_GEM_LINE)[2],
|
71
|
+
author: gem[1].strip,
|
72
|
+
description: gem[4..-1]&.map(&:strip)&.join(' ').to_s
|
73
|
+
}
|
74
|
+
end.select do |gem|
|
75
|
+
query.nil? || "#{gem[:name]} #{gem[:author]} #{gem[:description]}".downcase.include?(query.to_s.downcase)
|
76
|
+
end
|
77
|
+
printer.call(tablify(gem_prefix, gems))
|
78
|
+
end
|
79
|
+
|
80
|
+
def tablify(gem_prefix, gems)
|
81
|
+
array_of_arrays = gems.map do |gem|
|
82
|
+
name, namespace = gem[:name].sub(gem_prefix, '').underscore.titlecase.split
|
83
|
+
human_name = name
|
84
|
+
human_name += " (#{namespace})" unless namespace.nil?
|
85
|
+
[
|
86
|
+
human_name,
|
87
|
+
gem[:name],
|
88
|
+
gem[:version],
|
89
|
+
gem[:author].sub('Author: ', ''),
|
90
|
+
gem[:description],
|
91
|
+
]
|
92
|
+
end
|
93
|
+
Text::Table.new(
|
94
|
+
:head => %w[Name Gem Version Author Description],
|
95
|
+
:rows => array_of_arrays,
|
96
|
+
:horizontal_padding => 1,
|
97
|
+
:vertical_boundary => ' ',
|
98
|
+
:horizontal_boundary => ' ',
|
99
|
+
:boundary_intersection => ' '
|
100
|
+
)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|