inferno_core 0.5.3 → 0.5.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/lib/inferno/apps/cli/evaluate.rb +37 -4
- data/lib/inferno/apps/cli/main.rb +1 -1
- data/lib/inferno/entities/ig.rb +149 -0
- data/lib/inferno/entities.rb +1 -0
- data/lib/inferno/public/bundle.js +34 -34
- data/lib/inferno/repositories/igs.rb +9 -0
- data/lib/inferno/utils/ig_downloader.rb +3 -3
- data/lib/inferno/version.rb +1 -1
- data/spec/extract_tgz_helper.rb +13 -0
- metadata +5 -4
- data/lib/inferno/public/175.bundle.js +0 -1
- data/lib/inferno/public/217.bundle.js +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e11d6b274778016418f7189d8ec9e724cf20861c6e03385dc9c302299f198d18
|
4
|
+
data.tar.gz: '09c65484d51b2f7be0a3985b374d51593d59c432ba11c21bd10d54c798ccafa4'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0daf93ce97d8a5a8e9b409200d7c001e4ac49107887db05073399a74795a94b449d3c1eb1d139214c1402e1ea10a954ee1271b80c642909c379cd7bb0ba7a1f0
|
7
|
+
data.tar.gz: 3a70bb18128af1494e0fcd1a023d8e18e8043dd535ae9c00f8471c8eb85e23678fa7c8bcb19591852c3593c6588ba92af206a90644cf6288659179fef98c1a41
|
@@ -1,14 +1,21 @@
|
|
1
1
|
require_relative '../../../inferno/dsl/fhir_evaluation/evaluator'
|
2
|
+
require_relative '../../../inferno/entities'
|
3
|
+
require_relative '../../utils/ig_downloader'
|
4
|
+
|
5
|
+
require 'tempfile'
|
2
6
|
|
3
7
|
module Inferno
|
4
8
|
module CLI
|
5
|
-
class Evaluate
|
6
|
-
|
9
|
+
class Evaluate < Thor::Group
|
10
|
+
include Thor::Actions
|
11
|
+
include Inferno::Utils::IgDownloader
|
12
|
+
|
13
|
+
def evaluate(ig_path, data_path, _log_level)
|
7
14
|
validate_args(ig_path, data_path)
|
15
|
+
_ig = get_ig(ig_path)
|
8
16
|
|
9
|
-
#
|
17
|
+
# Rule execution, and result output below will be integrated soon.
|
10
18
|
|
11
|
-
# @ig = File.join(__dir__, 'ig', ig_path)
|
12
19
|
# if data_path
|
13
20
|
# DatasetLoader.from_path(File.join(__dir__, data_path))
|
14
21
|
# else
|
@@ -30,6 +37,32 @@ module Inferno
|
|
30
37
|
raise "Provided path '#{data_path}' is not a directory"
|
31
38
|
end
|
32
39
|
|
40
|
+
def get_ig(ig_path)
|
41
|
+
if File.exist?(ig_path)
|
42
|
+
ig = Inferno::Entities::IG.from_file(ig_path)
|
43
|
+
elsif in_user_package_cache?(ig_path.sub('@', '#'))
|
44
|
+
# NPM syntax for a package identifier is id@version (eg, hl7.fhir.us.core@3.1.1)
|
45
|
+
# but in the cache the separator is # (hl7.fhir.us.core#3.1.1)
|
46
|
+
cache_directory = File.join(user_package_cache, ig_path.sub('@', '#'))
|
47
|
+
ig = Inferno::Entities::IG.from_file(cache_directory)
|
48
|
+
else
|
49
|
+
Tempfile.create('package.tgz') do |temp_file|
|
50
|
+
load_ig(ig_path, nil, { force: true }, temp_file.path)
|
51
|
+
ig = Inferno::Entities::IG.from_file(temp_file.path)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
ig.add_self_to_repository
|
55
|
+
ig
|
56
|
+
end
|
57
|
+
|
58
|
+
def user_package_cache
|
59
|
+
File.join(Dir.home, '.fhir', 'packages')
|
60
|
+
end
|
61
|
+
|
62
|
+
def in_user_package_cache?(ig_identifier)
|
63
|
+
File.directory?(File.join(user_package_cache, ig_identifier))
|
64
|
+
end
|
65
|
+
|
33
66
|
def output_results(results, output)
|
34
67
|
if output&.end_with?('json')
|
35
68
|
oo = FhirEvaluator::EvaluationResult.to_operation_outcome(results)
|
@@ -45,7 +45,7 @@ module Inferno
|
|
45
45
|
type: :string,
|
46
46
|
desc: 'Export evaluation result to outcome.json as an OperationOutcome'
|
47
47
|
def evaluate(ig_path)
|
48
|
-
Evaluate.new.
|
48
|
+
Evaluate.new.evaluate(ig_path, options[:data_path], Logger::INFO)
|
49
49
|
end
|
50
50
|
|
51
51
|
desc 'console', 'Start an interactive console session with Inferno'
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fhir_models'
|
4
|
+
require 'pathname'
|
5
|
+
require 'rubygems/package'
|
6
|
+
require 'zlib'
|
7
|
+
|
8
|
+
require_relative '../repositories/igs'
|
9
|
+
|
10
|
+
module Inferno
|
11
|
+
module Entities
|
12
|
+
# IG is a wrapper class around the relevant concepts inside an IG.
|
13
|
+
# Not everything within an IG is currently used by Inferno.
|
14
|
+
class IG < Entity
|
15
|
+
ATTRIBUTES = [
|
16
|
+
:id,
|
17
|
+
:profiles,
|
18
|
+
:extensions,
|
19
|
+
:value_sets,
|
20
|
+
:search_params,
|
21
|
+
:examples
|
22
|
+
].freeze
|
23
|
+
|
24
|
+
include Inferno::Entities::Attributes
|
25
|
+
|
26
|
+
def initialize(**params)
|
27
|
+
super(params, ATTRIBUTES)
|
28
|
+
|
29
|
+
@profiles = []
|
30
|
+
@extensions = []
|
31
|
+
@value_sets = []
|
32
|
+
@examples = []
|
33
|
+
@search_params = []
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.from_file(ig_path)
|
37
|
+
raise "#{ig_path} does not exist" unless File.exist?(ig_path)
|
38
|
+
|
39
|
+
# fhir_models by default logs the entire content of non-FHIR files
|
40
|
+
# which could be things like a package.json
|
41
|
+
original_logger = FHIR.logger
|
42
|
+
FHIR.logger = Logger.new('/dev/null')
|
43
|
+
|
44
|
+
if File.directory?(ig_path)
|
45
|
+
from_directory(ig_path)
|
46
|
+
elsif ig_path.end_with? '.tgz'
|
47
|
+
from_tgz(ig_path)
|
48
|
+
else
|
49
|
+
raise "Unable to load #{ig_path} as it does not appear to be a directory or a .tgz file"
|
50
|
+
end
|
51
|
+
ensure
|
52
|
+
FHIR.logger = original_logger if defined? original_logger
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.from_tgz(ig_path)
|
56
|
+
tar = Gem::Package::TarReader.new(
|
57
|
+
Zlib::GzipReader.open(ig_path)
|
58
|
+
)
|
59
|
+
|
60
|
+
ig = IG.new
|
61
|
+
|
62
|
+
tar.each do |entry|
|
63
|
+
next if skip_item?(entry.full_name, entry.directory?)
|
64
|
+
|
65
|
+
begin
|
66
|
+
resource = FHIR::Json.from_json(entry.read)
|
67
|
+
next if resource.nil?
|
68
|
+
|
69
|
+
ig.handle_resource(resource, entry.full_name)
|
70
|
+
rescue StandardError
|
71
|
+
next
|
72
|
+
end
|
73
|
+
end
|
74
|
+
ig
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.from_directory(ig_directory)
|
78
|
+
ig = IG.new
|
79
|
+
|
80
|
+
ig_path = Pathname.new(ig_directory)
|
81
|
+
Dir.glob("#{ig_path}/**/*") do |f|
|
82
|
+
relative_path = Pathname.new(f).relative_path_from(ig_path).to_s
|
83
|
+
next if skip_item?(relative_path, File.directory?(f))
|
84
|
+
|
85
|
+
begin
|
86
|
+
resource = FHIR::Json.from_json(File.read(f))
|
87
|
+
next if resource.nil?
|
88
|
+
|
89
|
+
ig.handle_resource(resource, relative_path)
|
90
|
+
rescue StandardError
|
91
|
+
next
|
92
|
+
end
|
93
|
+
end
|
94
|
+
ig
|
95
|
+
end
|
96
|
+
|
97
|
+
# These files aren't FHIR resources
|
98
|
+
FILES_TO_SKIP = ['package.json', 'validation-summary.json'].freeze
|
99
|
+
|
100
|
+
def self.skip_item?(relative_path, is_directory)
|
101
|
+
return true if is_directory
|
102
|
+
|
103
|
+
file_name = relative_path.split('/').last
|
104
|
+
|
105
|
+
return true unless file_name.end_with? '.json'
|
106
|
+
return true unless relative_path.start_with? 'package/'
|
107
|
+
|
108
|
+
return true if file_name.start_with? '.' # ignore hidden files
|
109
|
+
return true if file_name.end_with? '.openapi.json'
|
110
|
+
return true if FILES_TO_SKIP.include? file_name
|
111
|
+
|
112
|
+
false
|
113
|
+
end
|
114
|
+
|
115
|
+
def handle_resource(resource, relative_path)
|
116
|
+
case resource.resourceType
|
117
|
+
when 'StructureDefinition'
|
118
|
+
if resource.type == 'Extension'
|
119
|
+
extensions.push resource
|
120
|
+
else
|
121
|
+
profiles.push resource
|
122
|
+
end
|
123
|
+
when 'ValueSet'
|
124
|
+
value_sets.push resource
|
125
|
+
when 'SearchParameter'
|
126
|
+
search_params.push resource
|
127
|
+
when 'ImplementationGuide'
|
128
|
+
@id = extract_package_id(resource)
|
129
|
+
else
|
130
|
+
examples.push(resource) if relative_path.start_with? 'package/example'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def extract_package_id(ig_resource)
|
135
|
+
"#{ig_resource.id}##{ig_resource.version || 'current'}"
|
136
|
+
end
|
137
|
+
|
138
|
+
# @private
|
139
|
+
def add_self_to_repository
|
140
|
+
repository.insert(self)
|
141
|
+
end
|
142
|
+
|
143
|
+
# @private
|
144
|
+
def repository
|
145
|
+
Inferno::Repositories::IGs.new
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
data/lib/inferno/entities.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative 'entities/attributes'
|
|
2
2
|
require_relative 'entities/has_runnable'
|
3
3
|
require_relative 'entities/entity'
|
4
4
|
require_relative 'entities/header'
|
5
|
+
require_relative 'entities/ig'
|
5
6
|
require_relative 'entities/message'
|
6
7
|
require_relative 'entities/request'
|
7
8
|
require_relative 'entities/result'
|