u3d 0.9.3 → 0.9.4
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/.circleci/config.yml +54 -0
- data/.github_changelog_generator +4 -0
- data/.rubocop.yml +14 -0
- data/CHANGELOG.md +80 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +42 -5
- data/README.md +68 -6
- data/Rakefile +25 -1
- data/docs/assets/u3d_list.png +0 -0
- data/docs/assets/u3d_run_current.png +0 -0
- data/docs/assets/u3d_sanitize.png +0 -0
- data/examples/Example1/Gemfile +2 -0
- data/examples/Example2/Gemfile +2 -0
- data/lib/u3d/commands.rb +87 -104
- data/lib/u3d/commands_generator.rb +23 -23
- data/lib/u3d/download_validator.rb +74 -0
- data/lib/u3d/downloader.rb +113 -265
- data/lib/u3d/iniparser.rb +24 -5
- data/lib/u3d/installation.rb +167 -0
- data/lib/u3d/installer.rb +62 -196
- data/lib/u3d/log_analyzer.rb +2 -0
- data/lib/u3d/unity_project.rb +45 -0
- data/lib/u3d/unity_runner.rb +30 -21
- data/lib/u3d/unity_version_definition.rb +60 -0
- data/lib/u3d/unity_versions.rb +54 -32
- data/lib/u3d/utils.rb +10 -0
- data/lib/u3d/version.rb +1 -1
- data/lib/u3d_core/command_executor.rb +23 -12
- data/lib/u3d_core/command_runner.rb +7 -1
- data/lib/u3d_core/credentials.rb +2 -2
- data/lib/u3d_core/globals.rb +4 -2
- data/lib/u3d_core/helper.rb +8 -6
- data/lib/u3d_core/ui/implementations/shell.rb +1 -1
- data/u3d.gemspec +3 -1
- metadata +28 -5
data/lib/u3d/log_analyzer.rb
CHANGED
@@ -24,6 +24,7 @@ require 'json'
|
|
24
24
|
|
25
25
|
module U3d
|
26
26
|
# Analyzes log by filtering output along a set of rules
|
27
|
+
# rubocop:disable ClassLength, PerceivedComplexity, BlockNesting
|
27
28
|
class LogAnalyzer
|
28
29
|
RULES_PATH = File.expand_path('../../../config/log_rules.json', __FILE__)
|
29
30
|
MEMORY_SIZE = 10
|
@@ -227,4 +228,5 @@ module U3d
|
|
227
228
|
true
|
228
229
|
end
|
229
230
|
end
|
231
|
+
# rubocop:enable ClassLength, PerceivedComplexity, BlockNesting
|
230
232
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
## --- BEGIN LICENSE BLOCK ---
|
2
|
+
# Copyright (c) 2016-present WeWantToKnow AS
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in all
|
12
|
+
# copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
## --- END LICENSE BLOCK ---
|
22
|
+
|
23
|
+
require 'u3d_core/helper'
|
24
|
+
|
25
|
+
module U3d
|
26
|
+
class UnityProject
|
27
|
+
attr_reader :path
|
28
|
+
|
29
|
+
def initialize(path)
|
30
|
+
@path = path
|
31
|
+
end
|
32
|
+
|
33
|
+
def exist?
|
34
|
+
Dir.exist?("#{@path}/Assets") && Dir.exist?("#{@path}/ProjectSettings")
|
35
|
+
end
|
36
|
+
|
37
|
+
def editor_version
|
38
|
+
require 'yaml'
|
39
|
+
yaml = YAML.safe_load(File.read("#{@path}/ProjectSettings/ProjectVersion.txt"))
|
40
|
+
version = yaml['m_EditorVersion']
|
41
|
+
version.gsub!(/(\d+\.\d+\.\d+)(?:x)?(\w\d+)(?:Linux)?/, '\1\2') if Helper.linux?
|
42
|
+
version
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/u3d/unity_runner.rb
CHANGED
@@ -28,16 +28,7 @@ module U3d
|
|
28
28
|
# Launches Unity with given arguments
|
29
29
|
class Runner
|
30
30
|
def run(installation, args, raw_logs: false)
|
31
|
-
log_file =
|
32
|
-
|
33
|
-
if log_file # we wouldn't want to do that for the default log file.
|
34
|
-
File.delete(log_file) if File.file?(log_file) # We only delete real files
|
35
|
-
else
|
36
|
-
log_file = installation.default_log_file
|
37
|
-
end
|
38
|
-
|
39
|
-
Utils.ensure_dir File.dirname(log_file)
|
40
|
-
FileUtils.touch(log_file) unless File.exist? log_file
|
31
|
+
log_file = find_and_prepare_logfile(installation, args)
|
41
32
|
|
42
33
|
tail_thread = Thread.new do
|
43
34
|
begin
|
@@ -64,7 +55,7 @@ module U3d
|
|
64
55
|
else
|
65
56
|
args.map!(&:shellescape)
|
66
57
|
end
|
67
|
-
|
58
|
+
|
68
59
|
U3dCore::CommandExecutor.execute(command: args, print_all: true)
|
69
60
|
ensure
|
70
61
|
sleep 1
|
@@ -72,20 +63,38 @@ module U3d
|
|
72
63
|
end
|
73
64
|
end
|
74
65
|
|
75
|
-
def
|
76
|
-
|
77
|
-
|
66
|
+
def find_and_prepare_logfile(installation, args)
|
67
|
+
log_file = Runner.find_logFile_in_args(args)
|
68
|
+
|
69
|
+
if log_file # we wouldn't want to do that for the default log file.
|
70
|
+
File.delete(log_file) if File.file?(log_file) # We only delete real files
|
71
|
+
else
|
72
|
+
log_file = installation.default_log_file
|
73
|
+
end
|
78
74
|
|
79
|
-
|
80
|
-
|
75
|
+
Utils.ensure_dir File.dirname(log_file)
|
76
|
+
FileUtils.touch(log_file) unless File.exist? log_file
|
77
|
+
log_file
|
81
78
|
end
|
82
79
|
|
83
|
-
|
84
|
-
|
85
|
-
args
|
86
|
-
|
80
|
+
class << self
|
81
|
+
# rubocop:disable MethodName
|
82
|
+
def find_logFile_in_args(args)
|
83
|
+
# rubocop:enable MethodName
|
84
|
+
find_arg_in_args('-logFile', args)
|
85
|
+
end
|
86
|
+
|
87
|
+
def find_projectpath_in_args(args)
|
88
|
+
find_arg_in_args('-projectpath', args)
|
89
|
+
end
|
90
|
+
|
91
|
+
def find_arg_in_args(arg_to_find, args)
|
92
|
+
raise 'Only arguments of type array supported right now' unless args.is_a?(Array)
|
93
|
+
args.each_with_index do |arg, index|
|
94
|
+
return args[index + 1] if arg == arg_to_find && index < args.count - 1
|
95
|
+
end
|
96
|
+
nil
|
87
97
|
end
|
88
|
-
nil
|
89
98
|
end
|
90
99
|
|
91
100
|
private
|
@@ -0,0 +1,60 @@
|
|
1
|
+
## --- BEGIN LICENSE BLOCK ---
|
2
|
+
# Copyright (c) 2016-present WeWantToKnow AS
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in all
|
12
|
+
# copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
20
|
+
# SOFTWARE.
|
21
|
+
## --- END LICENSE BLOCK ---
|
22
|
+
|
23
|
+
require 'u3d/iniparser'
|
24
|
+
|
25
|
+
module U3d
|
26
|
+
class UnityVersionDefinition
|
27
|
+
attr_accessor :version, :os, :url, :ini
|
28
|
+
|
29
|
+
def initialize(version, os, cached_versions)
|
30
|
+
@version = version
|
31
|
+
@os = os
|
32
|
+
# Cache is assumed to be correct
|
33
|
+
@url = cached_versions ? cached_versions[version] : nil
|
34
|
+
begin
|
35
|
+
@ini = INIparser.load_ini(version, cached_versions, os: os)
|
36
|
+
rescue => e
|
37
|
+
UI.error "Could not load INI file for version #{@version} on #{@os}: #{e}"
|
38
|
+
@ini = nil
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def available_packages
|
43
|
+
@ini.keys
|
44
|
+
end
|
45
|
+
|
46
|
+
def [](key)
|
47
|
+
return nil unless @ini
|
48
|
+
@ini[key]
|
49
|
+
end
|
50
|
+
|
51
|
+
def size_in_kb(package)
|
52
|
+
return -1 unless @ini[package] && @ini[package]['size']
|
53
|
+
@os == :win ? @ini[package]['size'] * 1024 : @ini[package]['size']
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.create_fake(version, size, url)
|
57
|
+
INIparser.create_linux_ini(version, size, url)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/u3d/unity_versions.rb
CHANGED
@@ -20,7 +20,7 @@
|
|
20
20
|
# SOFTWARE.
|
21
21
|
## --- END LICENSE BLOCK ---
|
22
22
|
|
23
|
-
require 'u3d/
|
23
|
+
require 'u3d/unity_version_definition'
|
24
24
|
require 'u3d_core/helper'
|
25
25
|
require 'net/http'
|
26
26
|
|
@@ -91,7 +91,52 @@ module U3d
|
|
91
91
|
class << self
|
92
92
|
def list_available
|
93
93
|
UI.message 'Loading Unity releases'
|
94
|
-
|
94
|
+
|
95
|
+
data = linux_forum_page_content
|
96
|
+
|
97
|
+
versions = {}
|
98
|
+
results = data.scan(LINUX_DOWNLOAD_DATED)
|
99
|
+
results.each do |capt|
|
100
|
+
save_package_size(capt[1], capt[0])
|
101
|
+
versions[capt[1]] = capt[0]
|
102
|
+
end
|
103
|
+
|
104
|
+
response = nil
|
105
|
+
results = data.scan(LINUX_DOWNLOAD_RECENT_PAGE)
|
106
|
+
results.each do |page|
|
107
|
+
response = linux_forum_version_page_content(page[0])
|
108
|
+
if response.is_a? Net::HTTPSuccess
|
109
|
+
capt = response.body.match(LINUX_DOWNLOAD_RECENT_FILE)
|
110
|
+
if capt && capt[1] && capt[2]
|
111
|
+
ver = capt[2].delete('x')
|
112
|
+
UI.important "Version #{ver} does not match standard Unity versions" unless ver =~ Utils::UNITY_VERSION_REGEX
|
113
|
+
save_package_size(ver, capt[1])
|
114
|
+
versions[ver] = capt[1]
|
115
|
+
else
|
116
|
+
UI.error("Could not retrieve a fitting file from #{url}")
|
117
|
+
end
|
118
|
+
else
|
119
|
+
UI.error("Could not access #{url}")
|
120
|
+
end
|
121
|
+
end
|
122
|
+
if versions.count.zero?
|
123
|
+
UI.important 'Found no releases'
|
124
|
+
else
|
125
|
+
UI.success "Found #{versions.count} releases."
|
126
|
+
end
|
127
|
+
versions
|
128
|
+
end
|
129
|
+
|
130
|
+
def save_package_size(version, url)
|
131
|
+
size = Utils.get_url_content_length(url)
|
132
|
+
if size
|
133
|
+
UnityVersionDefinition.create_fake(version, size, url)
|
134
|
+
else
|
135
|
+
UI.important "u3d tried to get the size of the installer for version #{version}, but wasn't able to"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def linux_forum_page_content
|
95
140
|
response = nil
|
96
141
|
data = ''
|
97
142
|
uri = URI(UNITY_LINUX_DOWNLOADS)
|
@@ -148,38 +193,15 @@ module U3d
|
|
148
193
|
else raise "Request failed with status #{response.code}"
|
149
194
|
end
|
150
195
|
end
|
151
|
-
data
|
152
|
-
|
153
|
-
results = data.scan(LINUX_DOWNLOAD_DATED)
|
154
|
-
results.each do |capt|
|
155
|
-
versions[capt[1]] = capt[0]
|
156
|
-
end
|
196
|
+
data
|
197
|
+
end
|
157
198
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
request = Net::HTTP::Get.new uri
|
164
|
-
response = http.request request
|
165
|
-
end
|
166
|
-
if response.kind_of? Net::HTTPSuccess
|
167
|
-
capt = response.body.match(LINUX_DOWNLOAD_RECENT_FILE)
|
168
|
-
if capt && capt[1] && capt[2]
|
169
|
-
versions[capt[2].delete('x')] = capt[1]
|
170
|
-
else
|
171
|
-
UI.error("Could not retrieve a fitting file from #{url}")
|
172
|
-
end
|
173
|
-
else
|
174
|
-
UI.error("Could not access #{url}")
|
175
|
-
end
|
176
|
-
end
|
177
|
-
if versions.count.zero?
|
178
|
-
UI.important 'Found no releases'
|
179
|
-
else
|
180
|
-
UI.success "Found #{versions.count} releases."
|
199
|
+
def linux_forum_version_page_content(url)
|
200
|
+
uri = URI(url)
|
201
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
202
|
+
request = Net::HTTP::Get.new uri
|
203
|
+
return http.request request
|
181
204
|
end
|
182
|
-
versions
|
183
205
|
end
|
184
206
|
end
|
185
207
|
end
|
data/lib/u3d/utils.rb
CHANGED
@@ -58,6 +58,16 @@ module U3d
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
def get_url_content_length(url)
|
62
|
+
uri = URI(url)
|
63
|
+
size = nil
|
64
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
65
|
+
response = http.request_head url
|
66
|
+
size = Integer(response['Content-Length'])
|
67
|
+
end
|
68
|
+
size
|
69
|
+
end
|
70
|
+
|
61
71
|
def hashfile(file_path, blocksize: 65_536)
|
62
72
|
require 'digest'
|
63
73
|
raise ArgumentError, 'Not a file' unless File.file?(file_path)
|
data/lib/u3d/version.rb
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
## --- END LICENSE BLOCK ---
|
22
22
|
|
23
23
|
module U3d
|
24
|
-
VERSION = '0.9.
|
24
|
+
VERSION = '0.9.4'.freeze
|
25
25
|
DESCRIPTION = 'Provides numerous tools for installing, managing and running the Unity3D game engine from command line.'.freeze
|
26
26
|
UNITY_VERSIONS_NOTE = "Unity3d uses the following version formatting: 0.0.0x0. The \'x\' can takes different values:\n"\
|
27
27
|
"\t. 'f' are the main release candidates for Unity3d\n"\
|
@@ -61,23 +61,19 @@ module U3dCore
|
|
61
61
|
print_all = true if U3dCore::Globals.verbose?
|
62
62
|
prefix ||= {}
|
63
63
|
|
64
|
-
output = []
|
65
64
|
command = command.join(' ') if command.is_a?(Array)
|
66
65
|
UI.command(command) if print_command
|
67
66
|
|
68
67
|
# this is only used to show the "Loading text"...
|
69
68
|
UI.command_output(loading) if print_all && loading
|
70
69
|
|
71
|
-
if admin
|
72
|
-
cred = U3dCore::Credentials.new(user: ENV['USER'])
|
73
|
-
if Helper.windows?
|
74
|
-
raise CredentialsError, "The command \'#{command}\' must be run in administrative shell" unless has_admin_privileges?
|
75
|
-
else
|
76
|
-
command = "sudo -k && echo #{cred.password.shellescape} | sudo -S bash -c \"#{command}\""
|
77
|
-
end
|
78
|
-
UI.verbose 'Admin privileges granted for command execution'
|
79
|
-
end
|
70
|
+
command = grant_admin_privileges(command) if admin
|
80
71
|
|
72
|
+
execute_command(command: command, print_all: print_all, error: error, prefix: prefix)
|
73
|
+
end
|
74
|
+
|
75
|
+
def execute_command(command: nil, print_all: nil, error: nil, prefix: nil)
|
76
|
+
output = []
|
81
77
|
begin
|
82
78
|
status = U3dCore::Runner.run(command) do |stdin, _stdout, _pid|
|
83
79
|
stdin.each do |l|
|
@@ -109,7 +105,9 @@ module U3dCore
|
|
109
105
|
return output.join("\n")
|
110
106
|
end
|
111
107
|
|
108
|
+
# rubocop:disable PredicateName
|
112
109
|
def has_admin_privileges?
|
110
|
+
# rubocop:enable PredicateName
|
113
111
|
if Helper.windows?
|
114
112
|
begin
|
115
113
|
result = system('reg query HKU\\S-1-5-19', out: File::NULL, err: File::NULL)
|
@@ -120,8 +118,8 @@ module U3dCore
|
|
120
118
|
credentials = U3dCore::Credentials.new(user: ENV['USER'])
|
121
119
|
begin
|
122
120
|
result = system("sudo -k && echo #{credentials.password.shellescape} | sudo -S /usr/bin/whoami",
|
123
|
-
|
124
|
-
|
121
|
+
out: File::NULL,
|
122
|
+
err: File::NULL)
|
125
123
|
rescue
|
126
124
|
result = false
|
127
125
|
end
|
@@ -130,6 +128,19 @@ module U3dCore
|
|
130
128
|
# returns false if result is nil (command execution fail)
|
131
129
|
return (result ? true : false)
|
132
130
|
end
|
131
|
+
|
132
|
+
def grant_admin_privileges(command)
|
133
|
+
cred = U3dCore::Credentials.new(user: ENV['USER'])
|
134
|
+
if Helper.windows?
|
135
|
+
raise CredentialsError, "The command \'#{command}\' must be run in administrative shell" unless has_admin_privileges?
|
136
|
+
else
|
137
|
+
command = "sudo -k && echo #{cred.password.shellescape} | sudo -S bash -c \"#{command}\""
|
138
|
+
end
|
139
|
+
UI.verbose 'Admin privileges granted for command execution'
|
140
|
+
command
|
141
|
+
end
|
133
142
|
end
|
143
|
+
|
144
|
+
private_class_method :execute_command
|
134
145
|
end
|
135
146
|
end
|
@@ -21,6 +21,8 @@
|
|
21
21
|
# SOFTWARE.
|
22
22
|
## --- END LICENSE BLOCK ---
|
23
23
|
|
24
|
+
require 'English'
|
25
|
+
|
24
26
|
module U3dCore
|
25
27
|
# this module is meant to be private to this lib
|
26
28
|
module Runner
|
@@ -60,17 +62,21 @@ module U3dCore
|
|
60
62
|
yield r, w, p
|
61
63
|
# if the process has closed, ruby might raise an exception if we try
|
62
64
|
# to do I/O on a closed stream. This behavior is platform specific
|
65
|
+
# rubocop:disable HandleExceptions
|
63
66
|
rescue Errno::EIO
|
67
|
+
# rubocop:enable HandleExceptions
|
64
68
|
ensure
|
65
69
|
begin
|
66
70
|
Process.wait p
|
67
71
|
# The process might have exited.
|
68
72
|
# This behavior is also ruby version dependent.
|
73
|
+
# rubocop:disable HandleExceptions
|
69
74
|
rescue Errno::ECHILD, PTY::ChildExited
|
70
75
|
end
|
76
|
+
# rubocop:enable HandleExceptions
|
71
77
|
end
|
72
78
|
end
|
73
|
-
|
79
|
+
$CHILD_STATUS.exitstatus
|
74
80
|
end
|
75
81
|
end
|
76
82
|
|
data/lib/u3d_core/credentials.rb
CHANGED
@@ -105,8 +105,8 @@ module U3dCore
|
|
105
105
|
UI.message 'Deleting credentials from the keychain'
|
106
106
|
Security::InternetPassword.delete(server: MAC_U3D_SERVER)
|
107
107
|
end
|
108
|
-
|
109
|
-
UI.verbose 'Keychain may store invalid credentials for u3d'
|
108
|
+
elsif Helper.mac?
|
109
|
+
UI.verbose 'Keychain may store invalid credentials for u3d'
|
110
110
|
end
|
111
111
|
end
|
112
112
|
end
|
data/lib/u3d_core/globals.rb
CHANGED
@@ -33,7 +33,7 @@ module U3dCore
|
|
33
33
|
attr_writer :verbose, :log_timestamps, :use_keychain, :do_not_login
|
34
34
|
|
35
35
|
def attributes
|
36
|
-
@attributes ||= ((methods - public_instance_methods).grep(/=$/) - [
|
36
|
+
@attributes ||= ((methods - public_instance_methods).grep(/=$/) - %i[<= >=]).map do |s|
|
37
37
|
a = s.to_s
|
38
38
|
a[0..(a.length - 2)] # remove the '='
|
39
39
|
end
|
@@ -69,7 +69,8 @@ module U3dCore
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
def
|
72
|
+
def respond_to_missing?(method_sym, include_private = false)
|
73
|
+
# rubocop:disable GuardClause
|
73
74
|
if method_sym.to_s =~ /^with_(.*)$/
|
74
75
|
return attributes.include? Regexp.last_match(1)
|
75
76
|
elsif method_sym.to_s =~ /^(.*)\?$/
|
@@ -77,6 +78,7 @@ module U3dCore
|
|
77
78
|
else
|
78
79
|
super
|
79
80
|
end
|
81
|
+
# rubocop:enable GuardClause
|
80
82
|
end
|
81
83
|
end
|
82
84
|
private_class_method :is?, :with, :attributes
|