inform-runtime 1.2.1 → 1.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f79733e3acaea7ef29ef54048e40496a2e59f4eb3e367369cfadfc7a9ac1e7a
4
- data.tar.gz: 60560e1801f0489cf40b6144adb7ec5618d0bbb265f3304ea59d1837e61bd379
3
+ metadata.gz: 8342db25700d881e383905faaf8c8d3029511a245b9cc1e4b49aec3ebf6a0149
4
+ data.tar.gz: dece3144963ca7775f4b8367047a30a883dbdaefe68df0e689a5f1f9a0482089
5
5
  SHA512:
6
- metadata.gz: 154bb199c8b4de11899a9206abe0805b71a8a678c62dac81fbb326de36d7f2092f7b70c14702403dab7ae45752ea647fb012d941498d554d7196d9f6cd651562
7
- data.tar.gz: 4000a694bde0d03cd6a88b7959f2e451fb2935cc8468330a6fbbcb8408696e30a1cde5912da28289a5a35c9027eca75c52cbb952a0d408cb64e8a30a4727573a
6
+ metadata.gz: 5142ffd42f10634c007b7aa945bd68b1d653331be622bac0b83051ed9e57d64e8bd7d190954ac42c642b7208aad9eb2fa99f20f2355c1d3c2516a493d152dca2
7
+ data.tar.gz: ebda0189c7b38d24a1d02719756c7c5e5c7ab0c1384b33c19112636c764ad15e8aab22273fd7cf38afdf28543034a1b85fdc5baf0eeb9bb6aae6c0a387c04ace
data/Rakefile CHANGED
@@ -23,24 +23,6 @@ CLOBBER.add '*.gem', 'pkg'
23
23
 
24
24
  task default: %i[package]
25
25
 
26
- desc 'Archive the current codebase snapshot'
27
- task :archive do
28
- repo_path = '.'
29
- archive = File.expand_path(File.join('..', "#{StoryTeller::PROJECT}.zip"), Dir.pwd)
30
-
31
- diff_clean = system('git', '-C', repo_path, 'diff-index', '--quiet', 'HEAD', '--')
32
- untracked = `git -C #{repo_path.shellescape} ls-files --others --exclude-standard`
33
-
34
- unless diff_clean && untracked.empty?
35
- warn 'Please resolve uncommitted or untracked changes in working tree.'
36
- exit 1
37
- end
38
-
39
- FileUtils.rm_f(archive)
40
-
41
- system('git', '-C', repo_path, 'archive', '-o', archive, '--format=zip', 'HEAD') or abort
42
- end
43
-
44
26
  desc 'Run the rubocop linter'
45
27
  task :lint do
46
28
  system('bundle', 'exec', 'rubocop') or abort
@@ -63,6 +45,7 @@ task :verify do
63
45
  system('bundle', 'exec', 'rspec', 'spec/verify_gem_spec.rb') or abort
64
46
  system('bundle', 'exec', 'rake', 'clean')
65
47
  end
48
+ task verify: :package
66
49
 
67
50
  desc 'Publish the gem'
68
51
  task :publish do
@@ -85,6 +85,8 @@ module PublicCommandMethods
85
85
 
86
86
  def cancelled?
87
87
  return true if future.nil?
88
+ return false unless future.respond_to?(:cancelled?)
89
+
88
90
  future.cancelled?
89
91
  end
90
92
 
@@ -33,6 +33,7 @@ require_relative 'helpers'
33
33
  require_relative 'io'
34
34
  require_relative 'publication'
35
35
  require_relative 'context'
36
+ require_relative 'privileges'
36
37
  require_relative 'world_tree'
37
38
  require_relative 'library'
38
39
  require_relative 'engine'
@@ -33,7 +33,7 @@ module StoryTeller
33
33
  module Library
34
34
  def play
35
35
  log.debug "Using engine-managed InformLibrary play method override"
36
- inform_library = StoryTeller::Engine.libraries[StoryTeller::Engine]
36
+ inform_library = StoryTeller::Engine.library
37
37
  inform_library.play
38
38
  inform_library
39
39
  end
@@ -61,6 +61,46 @@ module StoryTeller
61
61
  @libraries ||= {}
62
62
  end
63
63
 
64
+ def library
65
+ selfobj = parser_selfobj
66
+ return libraries[selfobj] if !selfobj.nil? && libraries.key?(selfobj)
67
+
68
+ bind_managed_library(InformLibrary.new)
69
+ end
70
+
71
+ def bind_managed_library(inform_library)
72
+ raise ManagedLibraryError, "InformLibrary is nil" if inform_library.nil?
73
+
74
+ selfobj = inform_library.selfobj
75
+ raise ManagedLibraryError, "InformLibrary selfobj is nil" if selfobj.nil?
76
+
77
+ libraries[selfobj] = inform_library
78
+ selfobj.inflib = inform_library if selfobj.respond_to?(:inflib=)
79
+
80
+ ensure_location(inform_library)
81
+
82
+ inform_library
83
+ end
84
+
85
+ def ensure_location(inflib)
86
+ return if inflib.nil?
87
+
88
+ existing_location = inflib.instance_variable_get(:@location)
89
+ return unless existing_location.nil?
90
+
91
+ player = inflib.selfobj
92
+ location = player.location if player.respond_to?(:location)
93
+ location ||= player.spawn_point if player.respond_to?(:spawn_point)
94
+
95
+ inflib.instance_variable_set(:@location, location) unless location.nil?
96
+ end
97
+
98
+ def parser_selfobj
99
+ return nil unless defined?(Inform::Parser::SelfObj)
100
+
101
+ Inform::Parser::SelfObj
102
+ end
103
+
64
104
  def main_object=(obj)
65
105
  @main_object = obj
66
106
  end
@@ -130,17 +170,6 @@ module StoryTeller
130
170
  end
131
171
  end
132
172
  # module Engine
133
-
134
- # The StoryTeller::Privileges module to implement privilege
135
- module Privileges
136
- def admin?
137
- self.has?(:admin)
138
- end
139
-
140
- def builder?
141
- admin? || self.has?(:builder)
142
- end
143
- end
144
173
  end
145
174
  # module StoryTeller
146
175
 
@@ -113,7 +113,11 @@ module PublicEventMethods
113
113
  end
114
114
 
115
115
  def <<(event)
116
- @successors.add event
116
+ if @successors.respond_to?(:add)
117
+ @successors.add(event)
118
+ else
119
+ @successors << event
120
+ end
117
121
  event.antecedent = self
118
122
  end
119
123
 
@@ -141,6 +145,8 @@ module PublicEventMethods
141
145
 
142
146
  def cancelled?
143
147
  return true if future.nil?
148
+ return false unless future.respond_to?(:cancelled?)
149
+
144
150
  future.cancelled?
145
151
  end
146
152
 
@@ -752,6 +758,7 @@ module Inform
752
758
  Inform::Events.each(event_class) do |event|
753
759
  # Do not artificially terminate the source of an interruption.
754
760
  next if event == interruption
761
+ next unless event.future.respond_to?(:cancel)
755
762
 
756
763
  # Parameterizing Future#cancel with false is supposed to
757
764
  # abort the future without interrupting the executing thread.
@@ -148,20 +148,6 @@ module Inform
148
148
  end
149
149
  end
150
150
 
151
- # # The Inform module
152
- # module Inform
153
- # # The ObjectHelpers module functionality
154
- # module ObjectHelpers
155
- # def object?(obj = self)
156
- # obj.is_a?(Inform::Object) || obj.is_a?(Inform::Ephemeral::Object)
157
- # end
158
-
159
- # def sysobj?(obj = self)
160
- # obj.is_a?(Inform::Ephemeral::Object)
161
- # end
162
- # end
163
- # end
164
-
165
151
  # The Inform module
166
152
  module Inform
167
153
  # The NilClassObjectHelpers module functionality
@@ -1,3 +1,4 @@
1
+ # lib/story_teller/history.rb
1
2
  # encoding: utf-8
2
3
  # frozen_string_literal: false
3
4
 
@@ -176,17 +176,23 @@ module Kernel
176
176
 
177
177
  raise MethodAlreadyDefined, :class_loader if respond_to?(:class_loader)
178
178
  def class_loader
179
- JRuby.runtime.jruby_class_loader
179
+ return JRuby.runtime.jruby_class_loader if defined?(JRuby)
180
+
181
+ raise NotImplementedError, "class_loader is only available on JRuby"
180
182
  end
181
183
 
182
184
  raise MethodAlreadyDefined, :load_service if respond_to?(:load_service)
183
185
  def load_service
184
- JRuby.runtime.load_service
186
+ return JRuby.runtime.load_service if defined?(JRuby)
187
+
188
+ raise NotImplementedError, "load_service is only available on JRuby"
185
189
  end
186
190
 
187
191
  raise MethodAlreadyDefined, :object_space if respond_to?(:object_space)
188
192
  def object_space
189
- JRuby.runtime.object_space
193
+ return JRuby.runtime.object_space if defined?(JRuby)
194
+
195
+ raise NotImplementedError, "object_space is only available on JRuby"
190
196
  end
191
197
 
192
198
  JavaPattern = %r{java}.freeze
@@ -205,6 +211,8 @@ module Kernel
205
211
  raise MethodAlreadyDefined, :collect_garbage if respond_to?(:collect_garbage)
206
212
  # rubocop: disable Metrics/AbcSize
207
213
  def collect_garbage
214
+ return unless java?
215
+
208
216
  java.lang.System.gc()
209
217
  sleep 0.1
210
218
  java.lang.System.runFinalization()
@@ -27,37 +27,20 @@ module StoryTeller
27
27
  module Bootstrap
28
28
  module_function
29
29
 
30
- def ensure_location(inflib)
31
- return if inflib.nil?
32
- return if inflib.location
30
+ def manage_inform_library(player: nil)
31
+ existing = StoryTeller::Engine.libraries[player] unless player.nil?
32
+ return existing unless existing.nil?
33
33
 
34
- player_obj = inflib.player
35
- location = player_obj&.location
36
- location ||= player_obj&.spawn_point if player_obj.respond_to?(:spawn_point)
37
- inflib.instance_variable_set(:@location, location)
34
+ new_inform_library(player:)
38
35
  end
39
36
 
40
- def set_selfobj(inflib, player)
41
- inflib.selfobj = player unless player.nil?
42
- end
43
-
44
- # rubocop: disable Metrics/MethodLength
45
- def manage_inform_library(player: nil, key: StoryTeller::Engine, &block)
46
- inflib = StoryTeller::Engine.libraries[key]
47
- unless inflib.nil? || player.nil?
48
- set_selfobj(inflib, player)
49
- return inflib
50
- end
51
-
52
- inflib = block_given? ? block.call : InformLibrary.new
53
- return nil if inflib.nil?
54
-
55
- set_selfobj(inflib, player)
37
+ def new_inform_library(player: nil)
38
+ inflib = InformLibrary.new
39
+ bind_inform_library(inflib, player)
56
40
  inflib.subscribe(inflib.selfobj)
57
41
  ensure_location(inflib)
58
- StoryTeller::Engine.libraries[key] = inflib
42
+ inflib
59
43
  end
60
- # rubocop: enable Metrics/MethodLength
61
44
  end
62
45
  # module Bootstrap
63
46
  end
@@ -38,13 +38,14 @@ module StoryTeller
38
38
  InformLibrary.class_eval do
39
39
  include Inform::Context unless include?(Inform::Context)
40
40
  include Inform::StdLib unless include?(Inform::StdLib)
41
+ include Inform::History unless include?(Inform::History)
41
42
  end
42
43
  InformLibrary.prepend(StoryTeller::Library::Location)
43
44
  end
44
45
 
45
46
  def load_library
46
47
  augment_inform_library!
47
- StoryTeller::Library::Bootstrap.manage_inform_library
48
+ StoryTeller::Engine.library
48
49
  end
49
50
 
50
51
  def inform_object_model?
@@ -26,26 +26,29 @@ if defined?(Java)
26
26
  require 'apache-log4j-2'
27
27
  end
28
28
 
29
- # The Logging module
30
- module Logging
29
+ # The LoggingConfiguration module
30
+ module LoggingConfiguration
31
+ # rubocop: disable Metrics/AbcSize
31
32
  # rubocop: disable Metrics/MethodLength
32
33
  def config
33
34
  @config ||= begin
34
- support_dir_path = File.expand_path(__dir__)
35
- lib_dir_path = File.expand_path(File.dirname(support_dir_path))
35
+ module_dir_path = File.expand_path(__dir__)
36
+ lib_dir_path = File.expand_path(File.dirname(module_dir_path))
36
37
  project_dir_path = File.expand_path(File.dirname(lib_dir_path))
37
38
  app_name = File.basename(project_dir_path)
38
39
  logs_dir_path = File.expand_path(File.join(project_dir_path, 'logs'))
39
40
  FileUtils.mkdir_p(logs_dir_path)
40
- log_file = File.expand_path(File.join(logs_dir_path, "#{app_name}.log"))
41
+ log_file_path = File.expand_path(File.join(logs_dir_path, "#{app_name}.log"))
42
+ FileUtils.touch(log_file_path)
41
43
  {
42
- level: :info,
44
+ level: ENV['INFORM_LOG_LEVEL']&.to_i || Logger::INFO,
43
45
  name: app_name,
44
46
  lib_dir_path: lib_dir_path,
45
47
  project_dir_path: project_dir_path,
46
48
  logs_dir_path: logs_dir_path,
47
- log_file: log_file,
48
- rolling_log_file_name_template: "#{app_name}-%d{yyyy-MM-dd}.log.gz",
49
+ log_file_path: log_file_path,
50
+ rolling_log_file_name_template: File.expand_path(
51
+ File.join(logs_dir_path, "#{app_name}-%d{yyyy-MM-dd}.log.gz")),
49
52
  logging_timestamp_format: '%Y-%m-%d %H:%M:%S',
50
53
  logging_pattern_template: {
51
54
  java: '%d{ABSOLUTE} %-5p [%c{1}] %m%n',
@@ -57,103 +60,182 @@ module Logging
57
60
  end
58
61
  end
59
62
  module_function :config
63
+ # rubocop: enable Metrics/AbcSize
64
+ # rubocop: enable Metrics/MethodLength
65
+ end
66
+
67
+ # The LoggingHelpers module
68
+ module LoggingHelpers
69
+ if defined?(Java)
70
+ java_import Java::org.apache.logging.log4j.core.appender::ConsoleAppender
71
+ java_import Java::org.apache.logging.log4j.core.config::Configurator
72
+ java_import Java::org.apache.logging.log4j.core.config.builder.api::ConfigurationBuilderFactory
73
+ java_import Java::org.apache.logging.log4j::Level
74
+ end
75
+
76
+ # rubocop: disable Metrics/AbcSize
77
+ # rubocop: disable Metrics/MethodLength
78
+ def init_log4j(log_level = org.apache.logging.log4j.Level::INFO)
79
+ java.lang::System.setProperty('log4j.shutdownHookEnabled', java.lang::Boolean.toString(false))
80
+ config = ConfigurationBuilderFactory.newConfigurationBuilder()
81
+
82
+ log_level = Level.to_level(log_level.to_s.upcase) if log_level.is_a? Symbol
83
+ config.setStatusLevel(log_level)
84
+ config.setConfigurationName(LoggingConfiguration.config[:name])
85
+
86
+ # create a console appender
87
+ target = ConsoleAppender::Target::SYSTEM_OUT
88
+ pattern = LoggingConfiguration.config[:logging_pattern_template][:java]
89
+ layout = config.newLayout('PatternLayout')
90
+ layout = layout.addAttribute('pattern', pattern)
91
+ appender = config.newAppender('stdout', 'CONSOLE')
92
+ appender = appender.addAttribute('target', target)
93
+ appender = appender.add(layout)
94
+ config.add(appender)
95
+
96
+ # create a root logger
97
+ root_logger = config.newRootLogger(log_level)
98
+ root_logger = root_logger.add(config.newAppenderRef('stdout'))
99
+
100
+ # create a rolling file appender
101
+ cron = config.newComponent('CronTriggeringPolicy')
102
+ cron = cron.addAttribute('schedule', '0 0 0 * * ?')
103
+
104
+ size = config.newComponent('SizeBasedTriggeringPolicy')
105
+ size = size.addAttribute('size', LoggingConfiguration.config[:size])
106
+
107
+ policies = config.newComponent('Policies')
108
+ policies = policies.addComponent(cron)
109
+ policies = policies.addComponent(size)
110
+
111
+ appender = config.newAppender('rolling_file', 'RollingFile')
112
+ appender = appender.addAttribute(
113
+ 'fileName', LoggingConfiguration.config[:log_file_path])
114
+ appender = appender.addAttribute(
115
+ 'filePattern', LoggingConfiguration.config[:rolling_log_file_name_template])
116
+ appender = appender.add(layout)
117
+ appender = appender.addComponent(policies)
118
+ config.add(appender)
119
+
120
+ root_logger = root_logger.addAttribute('additivity', false)
121
+ root_logger = root_logger.add(config.newAppenderRef('rolling_file'))
122
+ config.add(root_logger)
123
+
124
+ logging_configuration = config.build()
125
+ ctx = Configurator.initialize(logging_configuration)
126
+ ctx.updateLoggers()
127
+ end
128
+ module_function :init_log4j
129
+ # rubocop: enable Metrics/AbcSize
60
130
  # rubocop: enable Metrics/MethodLength
131
+ # def init_log4j
132
+
133
+ LoggingHelpers.init_log4j if defined?(Java)
61
134
  end
135
+ # module Logging
62
136
 
63
137
  # Namespace for methods to help with implicit backtrace printing
64
- module LoggerHelpers
138
+ module TraceHelpers
65
139
  def generate_message(error_or_message, error)
66
140
  error_message = "#{error_or_message}: #{error.class.name}"
67
141
  error_message << ": #{error.message}" if error.respond_to?(:message)
68
142
  error_message
69
143
  end
144
+ module_function :generate_message
70
145
 
71
146
  def extract_backtrace(error, default_result = nil)
72
147
  if error.respond_to?(:backtrace)
73
- error.backtrace.each { |trace| original_error(trace) unless trace.nil? }
148
+ error.backtrace || default_result
74
149
  elsif error.respond_to?(:getStackTrace)
75
- error.getStackTrace().each { |trace| original_error(trace) unless trace.nil? }
150
+ error.getStackTrace() || default_result
76
151
  else
77
152
  default_result
78
153
  end
79
154
  end
155
+ module_function :extract_backtrace
80
156
  end
81
157
 
82
- # Monkey-patch the built-in Ruby Logger class to support
83
- # implicit backtrace printing
84
- # TODO: Figure out if this is actually useful.
158
+ # class Logger
85
159
  class Logger
86
- TRACE = DEBUG - 1 unless const_defined?(:TRACE)
87
-
88
- include LoggerHelpers
160
+ # module Severity
161
+ module Severity
162
+ # Lowest-level information, for developers.
163
+ TRACE = -1
164
+ LEVELS['trace'] = Logger::Severity::TRACE
165
+ end
166
+ end
89
167
 
168
+ # Add extra severity to the standard Logger class.
169
+ # Also add support for including backtraces implicitly.
170
+ class ExtraLogger < Logger
90
171
  alias original_error error
172
+ def error(error_or_message = nil, error = nil, &block)
173
+ return log_error(error_or_message, &block) if error.nil?
91
174
 
92
- def error(error_or_message, error = nil)
93
- warn error_or_message
94
- return extract_backtrace(error_or_message) if error.nil?
95
- original_error(generate_message(error_or_message, error))
96
- extract_backtrace(original_error(error))
175
+ original_error(TraceHelpers.generate_message(error_or_message, error))
176
+ TraceHelpers.extract_backtrace(error, []).each do |trace|
177
+ original_error(trace) unless trace.nil?
178
+ end
97
179
  end
98
180
 
99
- def trace(progname = nil, &block)
100
- add(TRACE, nil, progname, &block)
181
+ def log_error(error_or_message = nil, &block)
182
+ original_error(error_or_message, &block)
183
+ TraceHelpers.extract_backtrace(error_or_message, []).each do |trace|
184
+ original_error(trace) unless trace.nil?
185
+ end
101
186
  end
102
187
 
103
- def trace?
104
- @level <= TRACE
188
+ SEV_LABEL_EXTRA = (Logger::SEV_LABEL + %w(TRACE)).freeze
189
+ def format_severity(severity)
190
+ SEV_LABEL_EXTRA[severity] || super
191
+ end
192
+
193
+ def trace(progname = nil, &block)
194
+ add(Logger::Severity::TRACE, nil, progname, &block)
105
195
  end
106
196
  end
107
197
 
108
- # The Logging module
109
- module Logging
198
+ # The LoggingHelpers module
199
+ module LoggingHelpers
110
200
  if defined?(Java)
111
201
  java_import Java::org.apache.logging.log4j.Level
112
202
  java_import Java::org.apache.logging.log4j.LogManager
113
203
  end
114
204
 
115
- RubyLogLevels = {
116
- all: -Float::INFINITY,
117
- trace: Logger::TRACE,
118
- debug: Logger::DEBUG,
119
- info: Logger::INFO,
120
- warn: Logger::WARN,
121
- error: Logger::ERROR,
122
- fatal: Logger::FATAL,
123
- unknown: Logger::UNKNOWN,
124
- off: Logger::UNKNOWN + 1
125
- }.freeze
205
+ FORWARD_SLASH_PATTERN = %r{/} unless defined?(FORWARD_SLASH_PATTERN)
126
206
 
127
- def init_logger(level = :info, logger_name = nil)
128
- return init_java_logger(level, logger_name, caller[2]) if defined?(Java)
129
- init_ruby_logger(level, logger_name, caller[2])
207
+ def init_logger(obj, level = :info, logger_name = nil)
208
+ return init_java_logger(obj, level, logger_name, caller[2]) if defined?(Java)
209
+ init_ruby_logger(obj, level, logger_name, caller[2])
130
210
  end
211
+ module_function :init_logger
131
212
 
132
- def ruby_log_formatter(severity, datetime, progname, message)
213
+ def ruby_log_formatter(severity_level, datetime, program_name, message)
133
214
  format(
134
- Logging.config[:logging_pattern_template][:ruby],
135
- timestamp: datetime.strftime(Logging.config[:logging_timestamp_format]),
136
- progname: progname, severity: severity, msg: message)
215
+ LoggingConfiguration.config[:logging_pattern_template][:ruby],
216
+ timestamp: datetime.strftime(LoggingConfiguration.config[:logging_timestamp_format]),
217
+ progname: program_name, severity: severity_level, msg: message)
137
218
  end
219
+ module_function :ruby_log_formatter
138
220
 
139
- ForwardSlashPattern = %r{/}.freeze
140
-
141
- def init_ruby_logger(level = nil, logger_name = nil, source_location = nil)
142
- logger_name = get_formatted_logger_name(logger_name)
143
- logger_name = source_location.split(ForwardSlashPattern).last if logger_name.empty?
144
- log = Logger.new($stdout, progname: logger_name)
221
+ def init_ruby_logger(obj, level = nil, logger_name = nil, source_location = nil)
222
+ logger_name = get_formatted_logger_name(obj, logger_name)
223
+ logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
224
+ log = ExtraLogger.new($stdout, progname: logger_name)
145
225
  log.level = normalize_ruby_log_level(level) unless level.nil?
146
226
  log.formatter = method(:ruby_log_formatter)
147
227
  log
148
228
  end
229
+ module_function :init_ruby_logger
149
230
 
150
- def init_java_logger(level = nil, logger_name = nil, source_location = nil)
151
- logger_name = get_formatted_logger_name(logger_name)
152
- logger_name = source_location.split(ForwardSlashPattern).last if logger_name.empty?
231
+ def init_java_logger(obj, level = nil, logger_name = nil, source_location = nil)
232
+ logger_name = get_formatted_logger_name(obj, logger_name)
233
+ logger_name = source_location.split(FORWARD_SLASH_PATTERN).last if logger_name.empty?
153
234
  log = LogManager.getLogger(logger_name)
154
235
  log.level = Level.to_level(level.to_s.upcase) unless level.nil?
155
236
  log
156
237
  end
238
+ module_function :init_java_logger
157
239
 
158
240
  def normalize_ruby_log_level(level)
159
241
  return level if level.is_a?(Integer)
@@ -162,12 +244,26 @@ module Logging
162
244
  raise ArgumentError, "Unknown Ruby log level: #{level.inspect}"
163
245
  end
164
246
  end
247
+ module_function :normalize_ruby_log_level
165
248
 
166
- def get_formatted_logger_name(logger_name = nil)
167
- return logger_name.to_s[/\w+$/] unless logger_name.nil?
168
- return name[/\w+$/] if is_a?(Class) || is_a?(Module)
169
- self.class.name[/\w+$/]
249
+ def get_formatted_logger_name(obj, logger_name = nil)
250
+ return logger_name.to_s if !logger_name.nil? && logger_name.respond_to?(:to_s)
251
+ return obj.name if obj.is_a?(Class) || obj.is_a?(Module)
252
+ obj.class.name
170
253
  end
254
+ module_function :get_formatted_logger_name
255
+
256
+ RubyLogLevels = {
257
+ all: -Float::INFINITY,
258
+ trace: Logger::TRACE,
259
+ debug: Logger::DEBUG,
260
+ info: Logger::INFO,
261
+ warn: Logger::WARN,
262
+ error: Logger::ERROR,
263
+ fatal: Logger::FATAL,
264
+ unknown: Logger::UNKNOWN,
265
+ off: Logger::UNKNOWN + 1
266
+ }.freeze
171
267
 
172
268
  # rubocop: disable Metrics/CyclomaticComplexity
173
269
  # OFF: 0
@@ -191,23 +287,25 @@ module Logging
191
287
  when -Float::INFINITY..-2 then :all
192
288
  end
193
289
  end
290
+ module_function :symbolize_numeric_log_level
194
291
  # rubocop: enable Metrics/CyclomaticComplexity
292
+ end
293
+ # module LoggingHelpers
195
294
 
295
+ # The Logging module
296
+ module Logging
196
297
  def log_level=(level)
197
- raise "Parameter level may not be nil" if level.nil?
198
- normalized_level = symbolize_numeric_log_level(level)
199
-
200
- Logging.config[:level] = normalized_level
298
+ LoggingConfiguration.config[:level] = LoggingHelpers.symbolize_numeric_log_level(level)
201
299
  end
202
300
  module_function :log_level=
203
301
 
204
302
  def log_level
205
- Logging.config[:level]
303
+ LoggingConfiguration.config[:level]
206
304
  end
207
305
  module_function :log_level
208
306
 
209
- def log(level = Logging.log_level, log_name = Logging.config[:app_name])
210
- @log ||= init_logger(level, log_name)
307
+ def log(level = Logging.log_level, log_name = LoggingConfiguration.config[:app_name])
308
+ @log ||= LoggingHelpers.init_logger(self, level, log_name)
211
309
  end
212
310
  alias logger log
213
311
  end
@@ -0,0 +1,34 @@
1
+ # lib/story_teller/privileges.rb
2
+ # encoding: utf-8
3
+ # frozen_string_literal: false
4
+
5
+ # Copyright Nels Nelson 2008-2025 but freely usable (see license)
6
+ #
7
+ # This file is part of the StoryTeller.
8
+ #
9
+ # The StoryTeller is free software: you can redistribute it and/or
10
+ # modify it under the terms of the GNU General Public License as published
11
+ # by the Free Software Foundation, either version 3 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # The StoryTeller is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with the StoryTeller. If not, see <http://www.gnu.org/licenses/>.
21
+
22
+ # The StoryTeller module
23
+ module StoryTeller
24
+ # The StoryTeller::Privileges module to implement privilege
25
+ module Privileges
26
+ def admin?
27
+ self.has?(:admin)
28
+ end
29
+
30
+ def builder?
31
+ admin? || self.has?(:builder)
32
+ end
33
+ end
34
+ end
@@ -162,6 +162,13 @@ module Inform
162
162
  (respond_to?(:_key?) && _key?(property)) ||
163
163
  !args.empty?
164
164
  self.prototype(method, *args, &block)
165
+ # TODO: Remove (2026-04-28)
166
+ # Experiment with supporting only property setting for those
167
+ # declared in StoryTeller::Library.declarations.properties.
168
+ # elsif (properties.respond_to?(:key?) && properties.key?(property)) ||
169
+ # (respond_to?(:_key?) && _key?(property)) ||
170
+ # StoryTeller::Library.declarations.properties.key?(property)
171
+ # self.prototype(method, *args, &block)
165
172
  else
166
173
  super
167
174
  end
@@ -172,6 +179,7 @@ module Inform
172
179
  # rubocop: enable Metrics/PerceivedComplexity
173
180
  # rubocop: enable Style/MissingRespondToMissing
174
181
 
182
+ # TODO: Remove (2026-04-28)
175
183
  # def respond_to_missing?(method, include_all=false)
176
184
  # m = method.to_s
177
185
  # return false if m =~ /\?$/
@@ -19,6 +19,8 @@
19
19
  # You should have received a copy of the GNU General Public License
20
20
  # along with StoryTeller. If not, see <http://www.gnu.org/licenses/>.
21
21
 
22
+ require_relative 'version'
23
+
22
24
  # The Inform module
23
25
  module Inform
24
26
  # These are built-ins primarily found used in the InformLibrary.
@@ -430,7 +432,7 @@ module StdLib
430
432
  # appropriate.
431
433
  nil # false
432
434
  rescue StandardError => e
433
- log.error "Error getting reaction from #{obj}", e
435
+ log.error "Error getting reaction from #{obj.identity}", e
434
436
  e.backtrace.each { |t| log.error t }
435
437
  ensure
436
438
  obj.inflib = si
@@ -23,7 +23,7 @@
23
23
  module StoryTeller
24
24
  # module Engine
25
25
  module Engine
26
- VERSION = '1.2.1'.freeze
26
+ VERSION = '1.2.3'.freeze
27
27
  end
28
28
  end
29
29
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inform-runtime
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nels Nelson
@@ -43,14 +43,14 @@ dependencies:
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.1.0
46
+ version: 0.1.1
47
47
  type: :runtime
48
48
  prerelease: false
49
49
  version_requirements: !ruby/object:Gem::Requirement
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 0.1.0
53
+ version: 0.1.1
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: logger
56
56
  requirement: !ruby/object:Gem::Requirement
@@ -124,6 +124,7 @@ files:
124
124
  - lib/story_teller/mixins.rb
125
125
  - lib/story_teller/model_adapter.rb
126
126
  - lib/story_teller/plurals.rb
127
+ - lib/story_teller/privileges.rb
127
128
  - lib/story_teller/prototype.rb
128
129
  - lib/story_teller/publication.rb
129
130
  - lib/story_teller/session.rb