Class: Udb::Architecture
- Inherits:
-
Object
- Object
- Udb::Architecture
- Extended by:
- T::Sig
- Defined in:
- lib/udb/architecture.rb
Direct Known Subclasses
Constant Summary collapse
- OBJS =
[ { fn_name: "extension", arch_dir: "ext", klass: Extension, kind: DatabaseObject::Kind::Extension }, { fn_name: "instruction", arch_dir: "inst", klass: Instruction, kind: DatabaseObject::Kind::Instruction }, { fn_name: "instruction_type", arch_dir: "inst_type", klass: InstructionType, kind: DatabaseObject::Kind::InstructionType }, { fn_name: "instruction_subtype", arch_dir: "inst_subtype", klass: InstructionSubtype, kind: DatabaseObject::Kind::InstructionSubtype }, { fn_name: "csr", arch_dir: "csr", klass: Csr, kind: DatabaseObject::Kind::Csr }, { fn_name: "proc_cert_class", arch_dir: "proc_cert_class", klass: ProcCertClass, kind: DatabaseObject::Kind::ProcessorCertificateClass }, { fn_name: "proc_cert_model", arch_dir: "proc_cert_model", klass: ProcCertModel, kind: DatabaseObject::Kind::ProcessorCertificateModel }, { fn_name: "manual", arch_dir: "manual", klass: Manual, kind: DatabaseObject::Kind::Manual }, { fn_name: "manual_version", arch_dir: "manual_version", klass: ManualVersion, kind: DatabaseObject::Kind::ManualVersion }, { fn_name: "profile_release", arch_dir: "profile_release", klass: ProfileRelease, kind: DatabaseObject::Kind::ProfileRelease }, { fn_name: "profile_family", arch_dir: "profile_family", klass: ProfileFamily, kind: DatabaseObject::Kind::ProfileFamily }, { fn_name: "profile", arch_dir: "profile", klass: Profile, kind: DatabaseObject::Kind::Profile } ].freeze
Instance Attribute Summary collapse
-
#path ⇒ Pathname
readonly
Path to the directory with the standard YAML files.
Class Method Summary collapse
-
.generate_obj_methods(fn_name, arch_dir, obj_class)
These instance methods are create when this Architecture class is first loaded.
Instance Method Summary collapse
-
#exception_codes ⇒ Array<ExceptionCode>
All exception codes defined by the spec.
-
#initialize(arch_dir) ⇒ Architecture
constructor
A new instance of Architecture.
-
#interrupt_codes ⇒ Array<InteruptCode>
All interrupt codes defined by extensions.
-
#objs ⇒ Array<TopLevelDatabaseObject>
All known objects.
- #param(name) ⇒ nil, Parameter
-
#param_hash ⇒ Hash<String, Parameter>
Hash of all extension parameters defined in the architecture.
-
#params ⇒ Array<Parameter>
Alphabetical list of all parameters defined in the architecture.
- #portfolio(name) ⇒ PortfolioClass?
- #portfolio_class(name) ⇒ PortfolioClass?
-
#portfolio_class_hash ⇒ Hash<String, PortfolioClass>
Hash of all portfolio classes defined in the architecture.
-
#portfolio_classes ⇒ Array<PortfolioClass>
Alphabetical list of all portfolio classes defined in the architecture.
-
#portfolio_hash ⇒ Hash<String, Portfolio>
Hash of all portfolios defined in the architecture.
-
#portfolios ⇒ Array<Portfolio>
Alphabetical list of all portfolios defined in the architecture.
-
#ref(uri) ⇒ DatabaseObject
given a ‘$ref` target, return the Ruby object.
-
#validate(resolver, show_progress: true)
validate the architecture against JSON Schema and any object-specific verification.
Constructor Details
#initialize(arch_dir) ⇒ Architecture
Returns a new instance of Architecture.
69 70 71 72 73 74 75 76 77 |
# File 'lib/udb/architecture.rb', line 69 def initialize(arch_dir) @arch_dir = Pathname.new(arch_dir) raise "Arch directory not found: #{arch_dir}" unless @arch_dir.exist? @arch_dir = @arch_dir.realpath @path = @arch_dir # alias @objects = Concurrent::Hash.new @object_hashes = Concurrent::Hash.new end |
Instance Attribute Details
#path ⇒ Pathname (readonly)
Returns Path to the directory with the standard YAML files.
66 67 68 |
# File 'lib/udb/architecture.rb', line 66 def path @path end |
Class Method Details
.generate_obj_methods(fn_name, arch_dir, obj_class)
This method returns an undefined value.
These instance methods are create when this Architecture class is first loaded. This is a Ruby “class” method and so self is the entire Architecture class, not an instance it. However, this class method creates normal instance methods and when they are called self is an instance of the Architecture class.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/udb/architecture.rb', line 110 def self.generate_obj_methods(fn_name, arch_dir, obj_class) plural_fn = ActiveSupport::Inflector.pluralize(fn_name) define_method(plural_fn) do return @objects[arch_dir] unless @objects[arch_dir].nil? @objects[arch_dir] = Concurrent::Array.new @object_hashes[arch_dir] = Concurrent::Hash.new Dir.glob(@arch_dir / arch_dir / "**" / "*.yaml") do |obj_path| f = File.open(obj_path) f.flock(File::LOCK_EX) obj_yaml = YAML.load(f.read, filename: obj_path, permitted_classes: [Date]) f.flock(File::LOCK_UN) @objects[arch_dir] << obj_class.new(obj_yaml, Pathname.new(obj_path).realpath, self) @object_hashes[arch_dir][@objects[arch_dir].last.name] = @objects[arch_dir].last end @objects[arch_dir] end define_method("#{fn_name}_hash") do return @object_hashes[arch_dir] unless @object_hashes[arch_dir].nil? send(plural_fn) # create the hash @object_hashes[arch_dir] end define_method(fn_name) do |name| return @object_hashes[arch_dir][name] unless @object_hashes[arch_dir].nil? send(plural_fn) # create the hash @object_hashes[arch_dir][name] end end |
Instance Method Details
#exception_codes ⇒ Array<ExceptionCode>
Returns All exception codes defined by the spec.
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/udb/architecture.rb', line 309 def exception_codes return @exception_codes unless @exception_codes.nil? @exception_codes = extensions.reduce([]) do |list, ext| ecodes = extension(ext.name).data["exception_codes"] next list if ecodes.nil? ecodes.each do |ecode| # double check that all the codes are unique raise "Duplicate exception code" if list.any? { |e| e.num == ecode["num"] || e.name == ecode["name"] || e.var == ecode["var"] } list << ExceptionCode.new(ecode["name"], ecode["var"], ecode["num"], ext) end list end end |
#interrupt_codes ⇒ Array<InteruptCode>
Returns All interrupt codes defined by extensions.
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 |
# File 'lib/udb/architecture.rb', line 328 def interrupt_codes return @interrupt_codes unless @interrupt_codes.nil? @interupt_codes = extensions.reduce([]) do |list, ext| icodes = extension(ext.name).data["interrupt_codes"] next list if icodes.nil? icodes.each do |icode| # double check that all the codes are unique if list.any? { |i| i.num == icode["num"] || i.name == icode["name"] || i.var == icode["var"] } raise "Duplicate interrupt code" end list << InterruptCode.new(icode["name"], icode["var"], icode["num"], ext) end list end end |
#objs ⇒ Array<TopLevelDatabaseObject>
Returns All known objects.
227 228 229 230 231 232 233 234 235 |
# File 'lib/udb/architecture.rb', line 227 def objs return @objs unless @objs.nil? @objs = [] OBJS.each do |obj_info| @objs.concat(send(ActiveSupport::Inflector.pluralize(obj_info[:fn_name]))) end @objs.freeze end |
#param(name) ⇒ nil, Parameter
258 259 260 |
# File 'lib/udb/architecture.rb', line 258 def param(name) param_hash[name] end |
#param_hash ⇒ Hash<String, Parameter>
Returns Hash of all extension parameters defined in the architecture.
245 246 247 248 249 250 251 252 253 |
# File 'lib/udb/architecture.rb', line 245 def param_hash return @param_hash unless @param_hash.nil? @param_hash = {} params.each do |param| @param_hash[param.name] = param end @param_hash end |
#params ⇒ Array<Parameter>
Returns Alphabetical list of all parameters defined in the architecture.
238 239 240 241 242 |
# File 'lib/udb/architecture.rb', line 238 def params return @params unless @params.nil? @params = extensions.map(&:params).flatten.uniq(&:name).sort_by!(&:name) end |
#portfolio(name) ⇒ PortfolioClass?
304 305 306 |
# File 'lib/udb/architecture.rb', line 304 def portfolio(name) portfolio_hash[name] end |
#portfolio_class(name) ⇒ PortfolioClass?
282 |
# File 'lib/udb/architecture.rb', line 282 def portfolio_class(name) = portfolio_class_hash[name] |
#portfolio_class_hash ⇒ Hash<String, PortfolioClass>
Returns Hash of all portfolio classes defined in the architecture.
270 271 272 273 274 275 276 277 278 |
# File 'lib/udb/architecture.rb', line 270 def portfolio_class_hash return @portfolio_class_hash unless @portfolio_class_hash.nil? @portfolio_class_hash = {} portfolio_classes.each do |portfolio_class| @portfolio_class_hash[portfolio_class.name] = portfolio_class end @portfolio_class_hash end |
#portfolio_classes ⇒ Array<PortfolioClass>
Returns Alphabetical list of all portfolio classes defined in the architecture.
263 264 265 266 267 |
# File 'lib/udb/architecture.rb', line 263 def portfolio_classes return @portfolio_classes unless @portfolio_classes.nil? @portfolio_classes = profile_families.concat(proc_cert_classes).sort_by!(&:name) end |
#portfolio_hash ⇒ Hash<String, Portfolio>
Returns Hash of all portfolios defined in the architecture.
292 293 294 295 296 297 298 299 300 |
# File 'lib/udb/architecture.rb', line 292 def portfolio_hash return @portfolio_hash unless @portfolio_hash.nil? @portfolio_hash = {} portfolios.each do |portfolio| @portfolio_hash[portfolio.name] = portfolio end @portfolio_hash end |
#portfolios ⇒ Array<Portfolio>
Returns Alphabetical list of all portfolios defined in the architecture.
285 286 287 288 289 |
# File 'lib/udb/architecture.rb', line 285 def portfolios return @portfolios unless @portfolios.nil? @portfolios = @profiles.concat(@certificates).sort_by!(&:name) end |
#ref(uri) ⇒ DatabaseObject
given a ‘$ref` target, return the Ruby object
353 354 355 356 357 358 359 360 361 362 363 364 365 366 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 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
# File 'lib/udb/architecture.rb', line 353 def ref(uri) raise ArgumentError, "JSON Reference (#{uri}) must contain one '#'" unless uri.count("#") == 1 file_path, obj_path = uri.split("#") obj = case file_path when /^proc_cert_class.*/ proc_cert_class_name = File.basename(file_path, ".yaml") proc_cert_class(proc_cert_class_name) when /^proc_cert_model.*/ proc_cert_model_name = File.basename(file_path, ".yaml") proc_cert_model(proc_cert_model_name) when /^csr.*/ csr_name = File.basename(file_path, ".yaml") csr(csr_name) when /^ext.*/ ext_name = File.basename(file_path, ".yaml") extension(ext_name) when %r{^inst/.*} inst_name = File.basename(file_path, ".yaml") instruction(inst_name) when /^manual.*/ manual_name = File.basename(file_path, ".yaml") manual(manual_name) when /^manual_version.*/ manual_name = File.basename(file_path, ".yaml") manual_version(manual_name) when /^profile_family.*/ profile_family_name = File.basename(file_path, ".yaml") profile_family(profile_family_name) when /^profile_release.*/ profile_release_name = File.basename(file_path, ".yaml") profile_release(profile_release_name) when /^profile.*/ profile_name = File.basename(file_path, ".yaml") profile(profile_name) when %r{^inst_subtype/.*/.*} inst_subtype_name = File.basename(file_path, ".yaml") instruction_subtype(inst_subtype_name) when %r{^inst_type/[^/]+} # type inst_type_name = File.basename(file_path, ".yaml") instruction_type(inst_type_name) else raise "Unhandled ref object: #{file_path}" end unless obj_path.nil? parts = obj_path.split("/") parts.each do |part| raise "Error in $ref. There is no method '#{part}' for a #{obj.class.name}" unless obj.respond_to?(part.to_sym) obj = obj.send(part) end end obj end |
#validate(resolver, show_progress: true)
This method returns an undefined value.
validate the architecture against JSON Schema and any object-specific verification
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/udb/architecture.rb', line 82 def validate(resolver, show_progress: true) = ProgressBar.create(total: objs.size) if show_progress objs.each do |obj| next unless obj.is_a?(TopLevelDatabaseObject) .increment if show_progress obj.validate(resolver) end end |