Class: MrMurano::ProjectFile

Inherits:
Object
  • Object
show all
Includes:
Verbose
Defined in:
lib/MrMurano/ProjectFile.rb

Overview

A Project File that describes details about a project that is synced into Murano.

Defined Under Namespace

Modules: PrjStructCommonMethods Classes: PrfFile, PrjEndpoints, PrjEventHandlers, PrjFiles, PrjMeta, PrjModules, PrjResources

Constant Summary

Constants included from Verbose

Verbose::TABULARIZE_DATA_FORMAT_ERROR

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Verbose

ask_yes_no, #ask_yes_no, #assert, assert, cmd_confirm_delete!, #cmd_confirm_delete!, debug, #debug, dump_file_json, dump_file_plain, dump_file_yaml, #dump_output_file, #error, error, #error_file_format!, fancy_ticks, #fancy_ticks, #load_file_json, #load_file_plain, #load_file_yaml, #load_input_file, outf, #outf, #outformat_engine, #pluralize?, pluralize?, #prepare_hash_csv, #read_hashf!, #tabularize, tabularize, verbose, #verbose, warning, #warning, #whirly_interject, whirly_interject, #whirly_linger, whirly_linger, #whirly_msg, whirly_msg, #whirly_pause, whirly_pause, #whirly_start, whirly_start, #whirly_stop, whirly_stop, #whirly_unpause, whirly_unpause

Constructor Details

#initializeProjectFile

Returns a new instance of ProjectFile.



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/MrMurano/ProjectFile.rb', line 108

def initialize
  @using_projectfile = false
  @using_solutionfile = false
  @prj_file = nil
  @data = PrfFile.new(
    new_meta,
    PrjFiles.new,
    PrjModules.new,
    PrjEndpoints.new,
    PrjEventHandlers.new,
    PrjResources.new,
  )
end

Instance Attribute Details

#using_projectfileObject (readonly)

Returns the value of attribute using_projectfile.



32
33
34
# File 'lib/MrMurano/ProjectFile.rb', line 32

def using_projectfile
  @using_projectfile
end

#using_solutionfileObject (readonly)

Returns the value of attribute using_solutionfile.



32
33
34
# File 'lib/MrMurano/ProjectFile.rb', line 32

def using_solutionfile
  @using_solutionfile
end

Instance Method Details

#data_bindingObject

Get a binding to the data for building the example ProjectFile



146
147
148
# File 'lib/MrMurano/ProjectFile.rb', line 146

def data_binding
  @data.get_binding
end

#default_value_for(key) ⇒ Object

Get the default value for a key.

Keys are ‘section.key’

All of these are currently stored in $cfg, but under different names.



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/MrMurano/ProjectFile.rb', line 168

def default_value_for(key)
  keymap = {
    # The left-side is the SolutionFile key;
    # the right-side is the $cfg key.

    'assets.location' => 'location.files',
    'assets.include' => 'files.searchFor',
    'assets.exclude' => 'files.ignoring',

    # (lb): As far as I can tell, code uses $cfg['files.default_page'],
    #       and never accesses the $project['assets.default_page'].
    #       Is this a bug?
    'assets.default_page' => 'files.default_page',

    'modules.location' => 'location.modules',
    'modules.include' => 'modules.searchFor',
    'modules.exclude' => 'modules.ignoring',

    'routes.location' => 'location.endpoints',
    'routes.include' => 'endpoints.searchFor',
    'routes.exclude' => 'endpoints.ignoring',

    'routes.cors' => 'location.cors',

    'services.location' => 'location.eventhandlers',
    'services.include' => 'eventhandler.searchFor',
    'services.exclude' => 'eventhandler.ignoring',

    'resources.location' => 'location.resources',
    'resources.include' => 'product.spec',
    'resources.exclude' => 'product.ignoring',
  }.freeze
  need_split = /.*\.(searchFor|ignoring)$/
  return nil unless keymap.key? key
  # *.{include,exclude} want arrays returned.
  # But what they map to is strings.
  cfg_key = keymap[key]
  ret = ($cfg[cfg_key] || '')
  # split uses $; when no delimiter is specified.
  #   In Ruby, $; is $FS or $FIELD_SEPARATOR.
  #   It defaults to nil, which splits on whitespace.
  #   https://ruby-doc.org/stdlib-2.3.3/libdoc/English/rdoc/English.html
  ret = ret.split if cfg_key =~ need_split
  ret
end

#get(key) ⇒ Object Also known as: []

Get a value for a key. Keys are ‘section.key’



152
153
154
155
156
157
158
159
160
# File 'lib/MrMurano/ProjectFile.rb', line 152

def get(key)
  raise 'Empty key' if key.empty?
  section, ikey = key.split('.')
  raise 'Missing dot' if ikey.nil? && section == key
  raise 'Missing key' if ikey.nil? && section != key
  ret = @data[section.to_sym][ikey.to_sym]
  return default_value_for(key) if ret.nil?
  ret
end

#ifset(src, skey, dest, dkey) ⇒ Object

Only set destination if source has key

Parameters:

  • src (Hash, Struct)

    Source of value to copy

  • skey (String, Symbol)

    Key in source to check and read

  • dest (Hash, Struct)

    Destination to save value in

  • dkey (String, Symbol)

    Key in destination to save to



299
300
301
# File 'lib/MrMurano/ProjectFile.rb', line 299

def ifset(src, skey, dest, dkey)
  dest[dkey] = src[skey] if src.key? skey
end

#loadObject

Load the project file in the project directory.



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# File 'lib/MrMurano/ProjectFile.rb', line 242

def load
  possible = Dir[
    ($cfg['location.base'] + '*.murano').to_s,
    ($cfg['location.base'] + 'Solutionfile.json').to_s,
  ]
  debug "Possible Project files: #{possible}"
  return 0 if possible.empty? # this is ok.

  warning "Multiple possible Project files! #{possible}" if possible.count > 1
  @prj_file = Pathname.new(possible.first)

  data = nil
  begin
    data = YAML.load_file(@prj_file.to_s)
  #rescue Exception => e
  rescue StandardError => e
    error "Load error; #{e}"
    pp e
    return -3
  end
  if data.nil?
    error "Failed to load #{@prj_file}"
    return -2
  end
  unless data.is_a?(Hash)
    error "Bad format in #{@prj_file}"
    return -4
  end

  data = Hash.transform_keys_to_symbols(data)

  # Get format version; little different for older format.
  if @prj_file.basename.to_s == 'Solutionfile.json'
    fmtvers = (data[:version] || '0.2.0')
  else
    fmtvers = (data[:formatversion] || '1.0.0')
  end

  methodname = "load_#{fmtvers.tr('.', '_')}".to_sym
  debug "Will try to #{methodname}"
  if respond_to? methodname
    errorlist = __send__(methodname, data)
    unless errorlist.empty?
      error %(Project file #{@prj_file} not valid.)
      errorlist.each { |er| error er }
      return -5
    end
  else
    error "Cannot load Project file of version #{fmtvers}"
  end
end

#load_0_2_0(data) ⇒ Array Also known as: load_0_2

Load data in the 0.2.0 format.

Parameters:

  • data (Hash)

    the data to load

Returns:

  • (Array)

    An array of validation errors in the data



325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/MrMurano/ProjectFile.rb', line 325

def load_0_2_0(data)
  schema_path = Pathname.new(::File.dirname(__FILE__)) + 'schema/sf-v0.2.0.yaml'
  schema = YAML.load_file(schema_path.to_s)
  v = JSON::Validator.fully_validate(schema, data)
  return v unless v.empty?
  @using_solutionfile = true

  ifset(data, :default_page, @data[:assets], :default_page)
  ifset(data, :file_dir, @data[:assets], :location)

  @data[:routes].location = '.'
  @data[:routes][:include] = [data[:custom_api]] if data.key? :custom_api
  ifset(data, :cors, @data[:routes], :cors)

  if data.key? :modules
    @data[:modules].location = '.'
    @data[:modules][:include] = data[:modules].values
  end

  if data.key? :event_handler
    @data[:services].location = '.'
    evd = data[:event_handler].values.map(&:values).flatten
    @data[:services].include = evd
    @data.services.legacy = store_legacy_service_handlers(data[:event_handler])
  end
  []
end

#load_0_3_0(data) ⇒ Array Also known as: load_0_3, load_0

Load data in the 0.3.0 format.

Parameters:

  • data (Hash)

    the data to load

Returns:

  • (Array)

    An array of validation errors in the data



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/MrMurano/ProjectFile.rb', line 367

def load_0_3_0(data)
  schema_path = Pathname.new(::File.dirname(__FILE__)) + 'schema/sf-v0.3.0.yaml'
  schema = YAML.load_file(schema_path.to_s)
  v = JSON::Validator.fully_validate(schema, data)
  return v unless v.empty?
  @using_solutionfile = true

  ifset(data, :default_page, @data[:assets], :default_page)
  ifset(data, :assets, @data[:assets], :location)

  @data[:routes].location = '.'
  @data[:routes][:include] = [data[:routes]] if data.key? :routes
  ifset(data, :cors, @data[:routes], :cors)

  if data.key? :modules
    @data[:modules].location = '.'
    @data[:modules][:include] = data[:modules].values
  end

  if data.key? :services
    @data[:services].location = '.'
    evd = data[:services].values.map(&:values).flatten
    @data[:services].include = evd
    @data.services.legacy = store_legacy_service_handlers(data[:services])
  end

  []
end

#load_1_0_0(data) ⇒ Array Also known as: load_1_0, load_1

Load data in the 1.0.0 format.

Parameters:

  • data (Hash)

    the data to load

Returns:

  • (Array)

    An array of validation errors in the data



306
307
308
309
310
311
312
313
314
315
316
317
318
# File 'lib/MrMurano/ProjectFile.rb', line 306

def load_1_0_0(data)
  schema_path = Pathname.new(::File.dirname(__FILE__)) + 'schema/pf-v1.0.0.yaml'
  schema = YAML.load_file(schema_path.to_s)
  v = JSON::Validator.fully_validate(schema, data)
  return v unless v.empty?
  @using_projectfile = true

  @data.each_pair do |key, str|
    str.load(data[key]) if data.key? key
  end

  []
end

#new_metaObject



122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/MrMurano/ProjectFile.rb', line 122

def new_meta
  tname = Pathname.new($cfg['location.base']).basename.to_s.gsub(/[^A-Za-z0-9]/, '')
  PrjMeta.new(
    tname,
    "One line summary of #{tname}",
    "In depth description of #{tname}\n\nWith lots of details.",
    [$cfg['user.name']],
    '1.0.0',
    nil,
    nil
  )
end

#project_filePathname

Get the current Project file

Returns:

  • (Pathname)

    Path to current project file.



141
142
143
# File 'lib/MrMurano/ProjectFile.rb', line 141

def project_file
  @prj_file
end

#refresh_user_nameObject



135
136
137
# File 'lib/MrMurano/ProjectFile.rb', line 135

def refresh_user_name
  @data.info = new_meta
end

#save(ios = $stdout) ⇒ Object

Save the Project File.

This ALWAYS saves in the latest format only.



230
231
232
233
234
235
236
237
238
# File 'lib/MrMurano/ProjectFile.rb', line 230

def save(ios=$stdout)
  dt = @data.save
  dt = Hash.transform_keys_to_strings(dt).to_yaml
  if ios.nil?
    dt
  else
    ios.write dt
  end
end

#set(key, value) ⇒ Object Also known as: []=

Set a value for a key. Keys are ‘section.key’



216
217
218
219
220
221
222
223
224
# File 'lib/MrMurano/ProjectFile.rb', line 216

def set(key, value)
  section, ikey = key.split('.')
  begin
    sec = @data[section.to_sym]
    sec[ikey.to_sym] = value
  rescue NameError => e
    debug ">>=>> #{e}"
  end
end

#store_legacy_service_handlers(services) ⇒ Object



354
355
356
357
358
359
360
361
362
# File 'lib/MrMurano/ProjectFile.rb', line 354

def store_legacy_service_handlers(services)
  ret = {}
  services.each do |service, events|
    events.each do |event, path|
      ret[path] = [service, event]
    end
  end
  ret
end