Skip to content

Commit

Permalink
FI-3440: Add IG class to DSL
Browse files Browse the repository at this point in the history
  • Loading branch information
dehall committed Dec 12, 2024
1 parent 4034350 commit 1b1ab63
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 7 deletions.
24 changes: 20 additions & 4 deletions lib/inferno/apps/cli/evaluate.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
require_relative '../../../inferno/dsl/fhir_evaluation/evaluator'
require_relative '../../../inferno/dsl/fhir_evaluation/config'
require_relative '../../../inferno/dsl/ig'
require_relative '../../utils/ig_downloader'

require 'tempfile'

module Inferno
module CLI
class Evaluate
def run(ig_path, data_path, _log_level)
class Evaluate < Thor::Group
include Thor::Actions
include Inferno::Utils::IgDownloader

def evaluate(ig_path, data_path, _log_level)
validate_args(ig_path, data_path)

# IG Import, rule execution, and result output below will be integrated at phase 2 and 3.
if File.file?(ig_path)
ig = Inferno::DSL::IG.from_file(ig_path)
else
Tempfile.create('package.tgz') do |temp_file|
load_ig(ig_path, nil, { force: true }, temp_file.path)
ig = Inferno::DSL::IG.from_file(temp_file.path)
end
end

# Rule execution, and result output below will be integrated at phase 2 and 3.

# @ig = File.join(__dir__, 'ig', ig_path)
# if data_path
# DatasetLoader.from_path(File.join(__dir__, data_path))
# else
Expand Down
2 changes: 1 addition & 1 deletion lib/inferno/apps/cli/main.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Main < Thor
type: :string,
desc: 'Export evaluation result to outcome.json as an OperationOutcome'
def evaluate(ig_path)
Evaluate.new.run(ig_path, options[:data_path], Logger::INFO)
Evaluate.new.evaluate(ig_path, options[:data_path], Logger::INFO)
end

desc 'console', 'Start an interactive console session with Inferno'
Expand Down
90 changes: 90 additions & 0 deletions lib/inferno/dsl/ig.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# frozen_string_literal: true

require 'fhir_models'
require 'rubygems/package'
require 'zlib'

module Inferno
module DSL
# IG is a wrapper class around the relevant concepts inside an IG.
# Not everything within an IG is currently used by Inferno.
class IG
attr_accessor :profiles, :extensions, :value_sets, :search_params, :examples

def initialize
@profiles = []
@extensions = []
@value_sets = []
@examples = []
@search_params = []
end

def self.from_file(ig_path)
raise "#{ig_path} is not an IG file" unless File.file?(ig_path)

tar = Gem::Package::TarReader.new(
Zlib::GzipReader.open(ig_path)
)

# fhir_models by default logs the entire content of non-FHIR files
# which could be things like a package.json
original_logger = FHIR.logger
FHIR.logger = Logger.new('/dev/null')

ig = IG.new

tar.each do |entry|
next if skip_tar_entry? entry

begin
resource = FHIR::Json.from_json(entry.read)
next if resource.nil?

ig.add_resource(resource, entry)
rescue StandardError
next
end
end

ig
ensure
FHIR.logger = original_logger if defined? original_logger
end

# These files aren't FHIR resources
FILES_TO_SKIP = ['package.json', 'validation-summary.json'].freeze

def self.skip_tar_entry?(entry)
return true if entry.directory?

file_name = entry.full_name.split('/').last

# TODO: consider making these regexes we can iterate over in a single loop
return true unless file_name.end_with? '.json'
return true unless entry.full_name.start_with? 'package/'

return true if file_name.start_with? '.' # ignore hidden files
return true if file_name.end_with? '.openapi.json'
return true if FILES_TO_SKIP.include? file_name

false
end

def add_resource(resource, entry)
if resource.resourceType == 'StructureDefinition'
if resource.type == 'Extension'
extensions.push resource
else
profiles.push resource
end
elsif resource.resourceType == 'ValueSet'
value_sets.push resource
elsif resource.resourceType == 'SearchParameter'
search_params.push resource
elsif entry.full_name.start_with? 'package/example'
examples.push resource
end
end
end
end
end
5 changes: 3 additions & 2 deletions lib/inferno/utils/ig_downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def ig_file(suffix = nil)
File.join(ig_path, suffix ? "package_#{suffix}.tgz" : 'package.tgz')
end

def load_ig(ig_input, idx = nil, thor_config = { verbose: true })
def load_ig(ig_input, idx = nil, thor_config = { verbose: true }, output_path = nil)
case ig_input
when FHIR_PACKAGE_NAME_REG_EX
uri = ig_registry_url(ig_input)
Expand All @@ -29,8 +29,9 @@ def load_ig(ig_input, idx = nil, thor_config = { verbose: true })
FAILED_TO_LOAD
end

destination = output_path || ig_file(idx)
# use Thor's get to support CLI options config
get(uri, ig_file(idx), thor_config)
get(uri, destination, thor_config)
uri
end

Expand Down

0 comments on commit 1b1ab63

Please sign in to comment.