suma 0.1.24 → 0.1.26
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/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +68 -62
- data/Gemfile +1 -0
- data/README.adoc +119 -0
- data/lib/suma/cli/compare.rb +210 -0
- data/lib/suma/cli/export.rb +2 -11
- data/lib/suma/cli.rb +19 -0
- data/lib/suma/eengine/errors.rb +27 -0
- data/lib/suma/eengine/wrapper.rb +150 -0
- data/lib/suma/eengine_converter.rb +32 -0
- data/lib/suma/export_standalone_schema.rb +14 -0
- data/lib/suma/schema_exporter.rb +2 -1
- data/lib/suma/version.rb +1 -1
- data/suma.gemspec +1 -1
- metadata +13 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13a0618f0faf4d08efb9d7783533cad40d31b5069b20d0107ccf6535ac5dcf7f
|
|
4
|
+
data.tar.gz: c5cf074c3c75091c41828fece24dbef27c07691f8dce321ac4d6ef7f71515640
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c9f2807fcfd075246d53741d231b241300410ad847795d0c2575cc4cfc205c22d36c2d1f7c7648432be41e63e3f00ae45472382d4c201230e8eefc5cda4506bc
|
|
7
|
+
data.tar.gz: 189245d32cd54e2fef7090a2f6ee9ab67188265b4ff5ffbb3dd71436ccf832b618f27f2005f97c8bf9ee29db43453063b9b18f4e6f6a4e983ddc5e1c99fa9b53
|
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# This configuration was generated by
|
|
2
2
|
# `rubocop --auto-gen-config`
|
|
3
|
-
# on 2025-10-
|
|
3
|
+
# on 2025-10-16 10:57:12 UTC using RuboCop version 1.81.1.
|
|
4
4
|
# The point is for the user to remove these configuration records
|
|
5
5
|
# one by one as the offenses are removed from the code base.
|
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
|
@@ -18,55 +18,20 @@ Gemspec/RequiredRubyVersion:
|
|
|
18
18
|
Exclude:
|
|
19
19
|
- 'suma.gemspec'
|
|
20
20
|
|
|
21
|
-
# Offense count:
|
|
21
|
+
# Offense count: 84
|
|
22
22
|
# This cop supports safe autocorrection (--autocorrect).
|
|
23
|
-
# Configuration parameters:
|
|
24
|
-
#
|
|
25
|
-
Layout/
|
|
26
|
-
|
|
27
|
-
- 'spec/suma/cli/export_spec.rb'
|
|
28
|
-
|
|
29
|
-
# Offense count: 1
|
|
30
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
31
|
-
# Configuration parameters: EnforcedStyleAlignWith.
|
|
32
|
-
# SupportedStylesAlignWith: either, start_of_block, start_of_line
|
|
33
|
-
Layout/BlockAlignment:
|
|
34
|
-
Exclude:
|
|
35
|
-
- 'spec/suma/cli/export_spec.rb'
|
|
23
|
+
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
|
24
|
+
# URISchemes: http, https
|
|
25
|
+
Layout/LineLength:
|
|
26
|
+
Enabled: false
|
|
36
27
|
|
|
37
28
|
# Offense count: 1
|
|
38
29
|
# This cop supports safe autocorrection (--autocorrect).
|
|
39
|
-
|
|
30
|
+
# Configuration parameters: EnforcedStyle.
|
|
31
|
+
# SupportedStyles: final_newline, final_blank_line
|
|
32
|
+
Layout/TrailingEmptyLines:
|
|
40
33
|
Exclude:
|
|
41
|
-
- '
|
|
42
|
-
|
|
43
|
-
# Offense count: 2
|
|
44
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
45
|
-
# Configuration parameters: Width, AllowedPatterns.
|
|
46
|
-
Layout/IndentationWidth:
|
|
47
|
-
Exclude:
|
|
48
|
-
- 'spec/suma/cli/export_spec.rb'
|
|
49
|
-
|
|
50
|
-
# Offense count: 74
|
|
51
|
-
# This cop supports safe autocorrection (--autocorrect).
|
|
52
|
-
# Configuration parameters: Max, AllowHeredoc, AllowURI, AllowQualifiedName, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
|
|
53
|
-
# URISchemes: http, https
|
|
54
|
-
Layout/LineLength:
|
|
55
|
-
Exclude:
|
|
56
|
-
- 'lib/suma/cli/build.rb'
|
|
57
|
-
- 'lib/suma/cli/validate.rb'
|
|
58
|
-
- 'lib/suma/collection_manifest.rb'
|
|
59
|
-
- 'lib/suma/jsdai/figure.rb'
|
|
60
|
-
- 'lib/suma/jsdai/figure_image.rb'
|
|
61
|
-
- 'lib/suma/processor.rb'
|
|
62
|
-
- 'lib/suma/schema_attachment.rb'
|
|
63
|
-
- 'lib/suma/schema_document.rb'
|
|
64
|
-
- 'lib/suma/thor_ext.rb'
|
|
65
|
-
- 'spec/suma/cli/export_spec.rb'
|
|
66
|
-
- 'spec/suma/cli/extract_terms_spec.rb'
|
|
67
|
-
- 'spec/suma/cli/validate_ascii_spec.rb'
|
|
68
|
-
- 'spec/suma/jsdai/figure_spec.rb'
|
|
69
|
-
- 'suma.gemspec'
|
|
34
|
+
- 'Gemfile'
|
|
70
35
|
|
|
71
36
|
# Offense count: 2
|
|
72
37
|
# Configuration parameters: IgnoreLiteralBranches, IgnoreConstantBranches, IgnoreDuplicateElseBranch.
|
|
@@ -84,30 +49,48 @@ Lint/IneffectiveAccessModifier:
|
|
|
84
49
|
Exclude:
|
|
85
50
|
- 'lib/suma/cli/export.rb'
|
|
86
51
|
|
|
87
|
-
# Offense count:
|
|
52
|
+
# Offense count: 11
|
|
88
53
|
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
89
54
|
Metrics/AbcSize:
|
|
90
55
|
Exclude:
|
|
56
|
+
- 'lib/suma/cli/compare.rb'
|
|
91
57
|
- 'lib/suma/jsdai/figure.rb'
|
|
92
58
|
- 'lib/suma/jsdai/figure_image.rb'
|
|
93
59
|
- 'lib/suma/schema_attachment.rb'
|
|
94
60
|
- 'lib/suma/schema_document.rb'
|
|
95
61
|
- 'lib/suma/thor_ext.rb'
|
|
96
62
|
|
|
97
|
-
# Offense count:
|
|
63
|
+
# Offense count: 6
|
|
98
64
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
99
65
|
Metrics/CyclomaticComplexity:
|
|
100
66
|
Exclude:
|
|
67
|
+
- 'lib/suma/cli/compare.rb'
|
|
68
|
+
- 'lib/suma/eengine/wrapper.rb'
|
|
101
69
|
- 'lib/suma/jsdai/figure.rb'
|
|
102
70
|
- 'lib/suma/jsdai/figure_image.rb'
|
|
103
71
|
- 'lib/suma/thor_ext.rb'
|
|
104
72
|
|
|
105
|
-
# Offense count:
|
|
73
|
+
# Offense count: 5
|
|
74
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
75
|
+
Metrics/MethodLength:
|
|
76
|
+
Max: 60
|
|
77
|
+
|
|
78
|
+
# Offense count: 4
|
|
106
79
|
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
107
80
|
Metrics/PerceivedComplexity:
|
|
108
81
|
Exclude:
|
|
82
|
+
- 'lib/suma/cli/compare.rb'
|
|
83
|
+
- 'lib/suma/eengine/wrapper.rb'
|
|
109
84
|
- 'lib/suma/jsdai/figure_image.rb'
|
|
110
85
|
|
|
86
|
+
# Offense count: 1
|
|
87
|
+
# Configuration parameters: Mode, AllowedMethods, AllowedPatterns, AllowBangMethods, WaywardPredicates.
|
|
88
|
+
# AllowedMethods: call
|
|
89
|
+
# WaywardPredicates: nonzero?
|
|
90
|
+
Naming/PredicateMethod:
|
|
91
|
+
Exclude:
|
|
92
|
+
- 'lib/suma/eengine/wrapper.rb'
|
|
93
|
+
|
|
111
94
|
# Offense count: 6
|
|
112
95
|
# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers, AllowedPatterns.
|
|
113
96
|
# SupportedStyles: snake_case, normalcase, non_integer
|
|
@@ -117,10 +100,11 @@ Naming/VariableNumber:
|
|
|
117
100
|
- 'spec/suma/cli/export_spec.rb'
|
|
118
101
|
- 'spec/suma/cli/validate_ascii_spec.rb'
|
|
119
102
|
|
|
120
|
-
# Offense count:
|
|
103
|
+
# Offense count: 3
|
|
121
104
|
# Configuration parameters: MinSize.
|
|
122
105
|
Performance/CollectionLiteralInLoop:
|
|
123
106
|
Exclude:
|
|
107
|
+
- 'spec/suma/cli/compare_spec.rb'
|
|
124
108
|
- 'spec/suma/cli/export_spec.rb'
|
|
125
109
|
- 'spec/suma/cli_spec.rb'
|
|
126
110
|
|
|
@@ -131,20 +115,40 @@ RSpec/ContextWording:
|
|
|
131
115
|
Exclude:
|
|
132
116
|
- 'spec/suma/cli/export_spec.rb'
|
|
133
117
|
|
|
134
|
-
# Offense count:
|
|
118
|
+
# Offense count: 51
|
|
135
119
|
# Configuration parameters: CountAsOne.
|
|
136
120
|
RSpec/ExampleLength:
|
|
137
|
-
Max:
|
|
121
|
+
Max: 61
|
|
138
122
|
|
|
139
|
-
# Offense count:
|
|
123
|
+
# Offense count: 4
|
|
140
124
|
# Configuration parameters: Max, AllowedIdentifiers, AllowedPatterns.
|
|
141
125
|
RSpec/IndexedLet:
|
|
142
126
|
Exclude:
|
|
127
|
+
- 'spec/suma/cli/compare_spec.rb'
|
|
143
128
|
- 'spec/suma/cli/export_spec.rb'
|
|
144
129
|
|
|
145
|
-
# Offense count:
|
|
130
|
+
# Offense count: 22
|
|
131
|
+
# Configuration parameters: AssignmentOnly.
|
|
132
|
+
RSpec/InstanceVariable:
|
|
133
|
+
Exclude:
|
|
134
|
+
- 'spec/suma/cli/compare_spec.rb'
|
|
135
|
+
|
|
136
|
+
# Offense count: 3
|
|
137
|
+
# This cop supports safe autocorrection (--autocorrect).
|
|
138
|
+
RSpec/IteratedExpectation:
|
|
139
|
+
Exclude:
|
|
140
|
+
- 'spec/suma/cli/compare_spec.rb'
|
|
141
|
+
|
|
142
|
+
# Offense count: 1
|
|
143
|
+
# Configuration parameters: EnforcedStyle.
|
|
144
|
+
# SupportedStyles: have_received, receive
|
|
145
|
+
RSpec/MessageSpies:
|
|
146
|
+
Exclude:
|
|
147
|
+
- 'spec/suma/cli/compare_spec.rb'
|
|
148
|
+
|
|
149
|
+
# Offense count: 47
|
|
146
150
|
RSpec/MultipleExpectations:
|
|
147
|
-
Max:
|
|
151
|
+
Max: 23
|
|
148
152
|
|
|
149
153
|
# Offense count: 1
|
|
150
154
|
# Configuration parameters: CustomTransform, IgnoreMethods, IgnoreMetadata.
|
|
@@ -154,12 +158,14 @@ RSpec/SpecFilePathFormat:
|
|
|
154
158
|
- 'spec/suma/cli/expressir_spec.rb'
|
|
155
159
|
|
|
156
160
|
# Offense count: 1
|
|
157
|
-
|
|
158
|
-
# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
|
|
159
|
-
# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
|
|
160
|
-
# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object
|
|
161
|
-
# FunctionalMethods: let, let!, subject, watch
|
|
162
|
-
# AllowedMethods: lambda, proc, it
|
|
163
|
-
Style/BlockDelimiters:
|
|
161
|
+
RSpec/StubbedMock:
|
|
164
162
|
Exclude:
|
|
165
|
-
- 'spec/suma/cli/
|
|
163
|
+
- 'spec/suma/cli/compare_spec.rb'
|
|
164
|
+
|
|
165
|
+
# Offense count: 1
|
|
166
|
+
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
167
|
+
# Configuration parameters: AllowedReceivers.
|
|
168
|
+
# AllowedReceivers: Thread.current
|
|
169
|
+
Style/HashEachMethods:
|
|
170
|
+
Exclude:
|
|
171
|
+
- 'spec/suma/cli/compare_spec.rb'
|
data/Gemfile
CHANGED
data/README.adoc
CHANGED
|
@@ -698,6 +698,125 @@ express-files/
|
|
|
698
698
|
----
|
|
699
699
|
|
|
700
700
|
|
|
701
|
+
=== Compare schemas command
|
|
702
|
+
|
|
703
|
+
==== General
|
|
704
|
+
|
|
705
|
+
The `suma compare` command compares two EXPRESS schemas using eengine and
|
|
706
|
+
generates an EXPRESS Changes YAML file tracking the differences.
|
|
707
|
+
|
|
708
|
+
This command is essential for managing schema evolution across versions,
|
|
709
|
+
particularly when working with multiple git branches of the same repository.
|
|
710
|
+
|
|
711
|
+
[source,sh]
|
|
712
|
+
----
|
|
713
|
+
$ suma compare TRIAL_SCHEMA REFERENCE_SCHEMA --version VERSION [options]
|
|
714
|
+
----
|
|
715
|
+
|
|
716
|
+
Parameters:
|
|
717
|
+
|
|
718
|
+
`TRIAL_SCHEMA`:: Path to the new/trial EXPRESS schema file
|
|
719
|
+
`REFERENCE_SCHEMA`:: Path to the old/reference EXPRESS schema file
|
|
720
|
+
|
|
721
|
+
Options:
|
|
722
|
+
|
|
723
|
+
`--version=VERSION`, `-v VERSION`:: (required) Version number for this change version
|
|
724
|
+
`--output=PATH`, `-o PATH`:: Output Change YAML file path (default: `{schema}.changes.yaml` in trial schema directory)
|
|
725
|
+
`--mode=MODE`:: Schema comparison mode: `resource` or `module` (default: `resource`)
|
|
726
|
+
`--trial-stepmod=PATH`:: Override auto-detected trial repository root
|
|
727
|
+
`--reference-stepmod=PATH`:: Override auto-detected reference repository root
|
|
728
|
+
`--verbose`:: Enable verbose output
|
|
729
|
+
|
|
730
|
+
==== Typical workflow
|
|
731
|
+
|
|
732
|
+
The compare command is designed for a two-repository workflow where you have
|
|
733
|
+
different branches checked out:
|
|
734
|
+
|
|
735
|
+
[source,sh]
|
|
736
|
+
----
|
|
737
|
+
# 1. Check out old version at /path/to/repo-old
|
|
738
|
+
# 2. Check out new version at /path/to/repo-new
|
|
739
|
+
# 3. Compare schemas:
|
|
740
|
+
$ suma compare \
|
|
741
|
+
/path/to/repo-new/schemas/resources/action_schema/action_schema.exp \
|
|
742
|
+
/path/to/repo-old/schemas/resources/action_schema/action_schema.exp \
|
|
743
|
+
--version 2
|
|
744
|
+
----
|
|
745
|
+
|
|
746
|
+
==== Behavior
|
|
747
|
+
|
|
748
|
+
The command:
|
|
749
|
+
|
|
750
|
+
* Auto-detects git repository roots from schema file paths
|
|
751
|
+
* Uses detected roots as stepmod paths for eengine
|
|
752
|
+
* Generates or updates `.changes.yaml` file in the trial schema directory
|
|
753
|
+
* **Replaces** existing change version if the version already exists
|
|
754
|
+
* **Adds** new change version if the version is different
|
|
755
|
+
|
|
756
|
+
==== Requirements
|
|
757
|
+
|
|
758
|
+
This command requires `eengine` to be installed:
|
|
759
|
+
|
|
760
|
+
* macOS: https://github.com/expresslang/homebrew-eengine
|
|
761
|
+
* Linux: https://github.com/expresslang/eengine-releases
|
|
762
|
+
|
|
763
|
+
[example]
|
|
764
|
+
.To compare schemas with auto-detection
|
|
765
|
+
[source,sh]
|
|
766
|
+
----
|
|
767
|
+
$ suma compare \
|
|
768
|
+
~/iso-10303-new/schemas/resources/support_resource_schema/support_resource_schema.exp \
|
|
769
|
+
~/iso-10303-old/schemas/resources/support_resource_schema/support_resource_schema.exp \
|
|
770
|
+
--version 2
|
|
771
|
+
# => generates or updates support_resource_schema.changes.yaml
|
|
772
|
+
----
|
|
773
|
+
|
|
774
|
+
[example]
|
|
775
|
+
.To compare with verbose output
|
|
776
|
+
[source,sh]
|
|
777
|
+
----
|
|
778
|
+
$ suma compare schema_new.exp schema_old.exp --version 2 --verbose
|
|
779
|
+
# Shows: eengine version, detected repo roots, XML generation, etc.
|
|
780
|
+
----
|
|
781
|
+
|
|
782
|
+
[example]
|
|
783
|
+
.To specify custom output location
|
|
784
|
+
[source,sh]
|
|
785
|
+
----
|
|
786
|
+
$ suma compare schema_new.exp schema_old.exp \
|
|
787
|
+
--version 2 \
|
|
788
|
+
--output /path/to/custom.changes.yaml
|
|
789
|
+
----
|
|
790
|
+
|
|
791
|
+
[example]
|
|
792
|
+
.To override auto-detected repository roots
|
|
793
|
+
[source,sh]
|
|
794
|
+
----
|
|
795
|
+
$ suma compare schema_new.exp schema_old.exp \
|
|
796
|
+
--version 2 \
|
|
797
|
+
--trial-stepmod ~/repo-new \
|
|
798
|
+
--reference-stepmod ~/repo-old
|
|
799
|
+
----
|
|
800
|
+
|
|
801
|
+
==== Generated Change YAML format
|
|
802
|
+
|
|
803
|
+
The command generates EXPRESS Changes YAML files in the ISO 10303 format:
|
|
804
|
+
|
|
805
|
+
[source,yaml]
|
|
806
|
+
----
|
|
807
|
+
---
|
|
808
|
+
schema: support_resource_schema
|
|
809
|
+
versions:
|
|
810
|
+
- version: '2'
|
|
811
|
+
description: 'TYPE text: Underlying Type changed'
|
|
812
|
+
modifications:
|
|
813
|
+
- type: TYPE
|
|
814
|
+
name: text
|
|
815
|
+
----
|
|
816
|
+
|
|
817
|
+
For complete format documentation, see the
|
|
818
|
+
https://www.expresslang.org/docs/express-changes[EXPRESS Changes specification].
|
|
819
|
+
|
|
701
820
|
=== Expressir command
|
|
702
821
|
|
|
703
822
|
==== General
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "thor"
|
|
4
|
+
require_relative "../eengine/wrapper"
|
|
5
|
+
require_relative "../eengine_converter"
|
|
6
|
+
|
|
7
|
+
module Suma
|
|
8
|
+
module Cli
|
|
9
|
+
# Command to compare EXPRESS schemas using eengine
|
|
10
|
+
class Compare < Thor
|
|
11
|
+
desc "compare TRIAL_SCHEMA REFERENCE_SCHEMA",
|
|
12
|
+
"Compare EXPRESS schemas using eengine and generate Change YAML"
|
|
13
|
+
long_desc <<~DESC
|
|
14
|
+
Compare two EXPRESS schemas from different git branches/checkouts.
|
|
15
|
+
|
|
16
|
+
Typical workflow:
|
|
17
|
+
1. Check out old version of repo at /path/to/repo-old
|
|
18
|
+
2. Check out new version of repo at /path/to/repo-new
|
|
19
|
+
3. Run comparison:
|
|
20
|
+
suma compare \\
|
|
21
|
+
/path/to/repo-new/schemas/.../schema.exp \\
|
|
22
|
+
/path/to/repo-old/schemas/.../schema.exp \\
|
|
23
|
+
--version 2
|
|
24
|
+
|
|
25
|
+
The command will:
|
|
26
|
+
- Auto-detect repository roots from schema paths
|
|
27
|
+
- Use those as stepmod paths for eengine
|
|
28
|
+
- Generate/update the .changes.yaml file in the new repo
|
|
29
|
+
DESC
|
|
30
|
+
|
|
31
|
+
option :output, type: :string, aliases: "-o",
|
|
32
|
+
desc: "Output Change YAML file path " \
|
|
33
|
+
"(default: {schema}.changes.yaml in trial schema directory)"
|
|
34
|
+
option :version, type: :string, aliases: "-v", required: true,
|
|
35
|
+
desc: "Version number for this change version"
|
|
36
|
+
option :mode, type: :string, default: "resource",
|
|
37
|
+
enum: ["resource", "module"],
|
|
38
|
+
desc: "Schema comparison mode"
|
|
39
|
+
option :trial_stepmod, type: :string,
|
|
40
|
+
desc: "Override auto-detected trial repo root"
|
|
41
|
+
option :reference_stepmod, type: :string,
|
|
42
|
+
desc: "Override auto-detected reference repo root"
|
|
43
|
+
option :verbose, type: :boolean, default: false,
|
|
44
|
+
desc: "Enable verbose output"
|
|
45
|
+
|
|
46
|
+
def compare(trial_schema, reference_schema)
|
|
47
|
+
# Validate schema files exist
|
|
48
|
+
unless File.exist?(trial_schema)
|
|
49
|
+
say "Error: Trial schema not found: #{trial_schema}", :red
|
|
50
|
+
exit 1
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
unless File.exist?(reference_schema)
|
|
54
|
+
say "Error: Reference schema not found: #{reference_schema}", :red
|
|
55
|
+
exit 1
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Check eengine availability
|
|
59
|
+
unless Eengine::Wrapper.available?
|
|
60
|
+
say "Error: eengine not found in PATH", :red
|
|
61
|
+
say "Install eengine following instructions at:"
|
|
62
|
+
say " macOS: https://github.com/expresslang/homebrew-eengine"
|
|
63
|
+
say " Linux: https://github.com/expresslang/eengine-releases"
|
|
64
|
+
exit 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Auto-detect repo roots
|
|
68
|
+
trial_stepmod = options[:trial_stepmod] ||
|
|
69
|
+
detect_repo_root(trial_schema)
|
|
70
|
+
reference_stepmod = options[:reference_stepmod] ||
|
|
71
|
+
detect_repo_root(reference_schema)
|
|
72
|
+
|
|
73
|
+
if options[:verbose]
|
|
74
|
+
say "Using eengine version: #{Eengine::Wrapper.version}", :green
|
|
75
|
+
say "Trial repo root: #{trial_stepmod}", :cyan
|
|
76
|
+
say "Reference repo root: #{reference_stepmod}", :cyan
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Create a temporary directory for eengine output
|
|
80
|
+
require "tmpdir"
|
|
81
|
+
out_dir = nil
|
|
82
|
+
out_dir = Dir.mktmpdir("eengine-compare-")
|
|
83
|
+
|
|
84
|
+
# Run comparison
|
|
85
|
+
result = Eengine::Wrapper.compare(
|
|
86
|
+
trial_schema,
|
|
87
|
+
reference_schema,
|
|
88
|
+
mode: options[:mode],
|
|
89
|
+
trial_stepmod: trial_stepmod,
|
|
90
|
+
reference_stepmod: reference_stepmod,
|
|
91
|
+
out_dir: out_dir,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
unless result[:has_changes]
|
|
95
|
+
say "No changes detected between schemas", :yellow
|
|
96
|
+
# Clean up temp directory
|
|
97
|
+
FileUtils.rm_rf(out_dir) if out_dir && File.directory?(out_dir)
|
|
98
|
+
return
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
unless result[:xml_path]
|
|
102
|
+
say "Error: XML output not found", :red
|
|
103
|
+
exit 1
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
if options[:verbose]
|
|
107
|
+
say "Comparison XML generated: #{result[:xml_path]}", :green
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Convert to Change YAML
|
|
111
|
+
convert_to_change_yaml(result[:xml_path], trial_schema, out_dir)
|
|
112
|
+
rescue Eengine::EengineError => e
|
|
113
|
+
# Clean up temp directory
|
|
114
|
+
FileUtils.rm_rf(out_dir) if out_dir && File.directory?(out_dir)
|
|
115
|
+
say "Error: #{e.message}", :red
|
|
116
|
+
say e.stderr if e.respond_to?(:stderr) && options[:verbose]
|
|
117
|
+
exit 1
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
private
|
|
121
|
+
|
|
122
|
+
def detect_repo_root(schema_path)
|
|
123
|
+
# Walk up from schema path to find .git directory
|
|
124
|
+
current = File.expand_path(File.dirname(schema_path))
|
|
125
|
+
|
|
126
|
+
loop do
|
|
127
|
+
if File.directory?(File.join(current, ".git"))
|
|
128
|
+
return current
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
parent = File.dirname(current)
|
|
132
|
+
break if parent == current # reached root
|
|
133
|
+
|
|
134
|
+
current = parent
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# If no .git found, use the directory containing the schema
|
|
138
|
+
# (for non-git workflows)
|
|
139
|
+
File.dirname(schema_path)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def convert_to_change_yaml(xml_path, trial_schema, out_dir)
|
|
143
|
+
schema_name = extract_schema_name(trial_schema)
|
|
144
|
+
output_path = determine_output_path(trial_schema)
|
|
145
|
+
|
|
146
|
+
# Load existing ChangeSchema if it exists
|
|
147
|
+
existing_schema = if File.exist?(output_path)
|
|
148
|
+
if options[:verbose]
|
|
149
|
+
say "Loading existing change schema: " \
|
|
150
|
+
"#{output_path}", :cyan
|
|
151
|
+
end
|
|
152
|
+
require "expressir/changes"
|
|
153
|
+
Expressir::Changes::SchemaChange.from_file(output_path)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Convert using Suma's converter
|
|
157
|
+
converter = EengineConverter.new(xml_path, schema_name)
|
|
158
|
+
change_schema = converter.convert(
|
|
159
|
+
version: options[:version],
|
|
160
|
+
existing_change_schema: existing_schema,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Save using Expressir model
|
|
164
|
+
change_schema.to_file(output_path)
|
|
165
|
+
|
|
166
|
+
# Determine what action was taken
|
|
167
|
+
if existing_schema
|
|
168
|
+
existing_version = existing_schema.versions.find do |ed|
|
|
169
|
+
ed.version == options[:version]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
say "Change YAML file updated: #{output_path}", :green
|
|
173
|
+
if existing_version
|
|
174
|
+
say " Replaced existing version #{options[:version]}", :green
|
|
175
|
+
else
|
|
176
|
+
say " Added version #{options[:version]} to change versions",
|
|
177
|
+
:green
|
|
178
|
+
end
|
|
179
|
+
else
|
|
180
|
+
say "Change YAML file created: #{output_path}", :green
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
if options[:verbose]
|
|
184
|
+
say "\nGenerated change schema content:", :cyan
|
|
185
|
+
say File.read(output_path)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
# Clean up temp directory and XML file
|
|
189
|
+
FileUtils.rm_rf(out_dir) if out_dir && File.directory?(out_dir)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def extract_schema_name(path)
|
|
193
|
+
# Remove version suffix if present (e.g., schema_1.exp -> schema)
|
|
194
|
+
basename = File.basename(path, ".exp")
|
|
195
|
+
basename.sub(/_\d+$/, "")
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def determine_output_path(trial_schema)
|
|
199
|
+
if options[:output]
|
|
200
|
+
options[:output]
|
|
201
|
+
else
|
|
202
|
+
# Place .changes.yaml next to the trial schema in the NEW repo
|
|
203
|
+
base = extract_schema_name(trial_schema)
|
|
204
|
+
dir = File.dirname(trial_schema)
|
|
205
|
+
File.join(dir, "#{base}.changes.yaml")
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
data/lib/suma/cli/export.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "thor"
|
|
4
4
|
require_relative "../thor_ext"
|
|
5
|
+
require_relative "../export_standalone_schema"
|
|
5
6
|
|
|
6
7
|
module Suma
|
|
7
8
|
module Cli
|
|
@@ -86,22 +87,12 @@ module Suma
|
|
|
86
87
|
def create_schema_from_exp_file(exp_file)
|
|
87
88
|
# Create a schema object from a standalone EXPRESS file
|
|
88
89
|
# The id will be determined during parsing
|
|
89
|
-
|
|
90
|
+
ExportStandaloneSchema.new(
|
|
90
91
|
id: nil,
|
|
91
92
|
path: File.expand_path(exp_file),
|
|
92
93
|
)
|
|
93
94
|
end
|
|
94
95
|
|
|
95
|
-
# Simple schema class for standalone EXPRESS files
|
|
96
|
-
class StandaloneSchema
|
|
97
|
-
attr_accessor :id, :path
|
|
98
|
-
|
|
99
|
-
def initialize(id:, path:)
|
|
100
|
-
@id = id
|
|
101
|
-
@path = path
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
96
|
def self.exit_on_failure?
|
|
106
97
|
true
|
|
107
98
|
end
|
data/lib/suma/cli.rb
CHANGED
|
@@ -74,6 +74,25 @@ module Suma
|
|
|
74
74
|
Cli::Export.start
|
|
75
75
|
end
|
|
76
76
|
|
|
77
|
+
desc "compare TRIAL_SCHEMA REFERENCE_SCHEMA",
|
|
78
|
+
"Compare EXPRESS schemas using eengine and generate Change YAML"
|
|
79
|
+
option :output, type: :string, aliases: "-o",
|
|
80
|
+
desc: "Output Change YAML file path"
|
|
81
|
+
option :version, type: :string, aliases: "-v", required: true,
|
|
82
|
+
desc: "Version number for this change version"
|
|
83
|
+
option :mode, type: :string, default: "resource",
|
|
84
|
+
desc: "Schema comparison mode (resource/module)"
|
|
85
|
+
option :trial_stepmod, type: :string,
|
|
86
|
+
desc: "Override auto-detected trial repo root"
|
|
87
|
+
option :reference_stepmod, type: :string,
|
|
88
|
+
desc: "Override auto-detected reference repo root"
|
|
89
|
+
option :verbose, type: :boolean, default: false,
|
|
90
|
+
desc: "Enable verbose output"
|
|
91
|
+
def compare(_trial_schema, _reference_schema)
|
|
92
|
+
require_relative "cli/compare"
|
|
93
|
+
Cli::Compare.start
|
|
94
|
+
end
|
|
95
|
+
|
|
77
96
|
desc "validate SUBCOMMAND ...ARGS", "Validate express documents"
|
|
78
97
|
subcommand "validate", Cli::Validate
|
|
79
98
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Suma
|
|
4
|
+
module Eengine
|
|
5
|
+
# Base error class for eengine-related errors
|
|
6
|
+
class EengineError < StandardError; end
|
|
7
|
+
|
|
8
|
+
# Raised when eengine binary is not found in PATH
|
|
9
|
+
class EengineNotFoundError < EengineError
|
|
10
|
+
def initialize
|
|
11
|
+
super("eengine not found in PATH. Install eengine:\n " \
|
|
12
|
+
"macOS: https://github.com/expresslang/homebrew-eengine\n " \
|
|
13
|
+
"Linux: https://github.com/expresslang/eengine-releases")
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Raised when eengine comparison fails
|
|
18
|
+
class ComparisonError < EengineError
|
|
19
|
+
attr_reader :stderr
|
|
20
|
+
|
|
21
|
+
def initialize(message, stderr = nil)
|
|
22
|
+
super(message)
|
|
23
|
+
@stderr = stderr
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "open3"
|
|
4
|
+
require_relative "errors"
|
|
5
|
+
|
|
6
|
+
module Suma
|
|
7
|
+
module Eengine
|
|
8
|
+
# Wrapper for eengine binary to compare EXPRESS schemas
|
|
9
|
+
class Wrapper
|
|
10
|
+
class << self
|
|
11
|
+
# Compare two EXPRESS schemas using eengine
|
|
12
|
+
#
|
|
13
|
+
# @param trial_schema [String] Path to the new/trial schema
|
|
14
|
+
# @param reference_schema [String] Path to the old/reference schema
|
|
15
|
+
# @param options [Hash] Comparison options
|
|
16
|
+
# @option options [String] :mode Comparison mode (resource/module)
|
|
17
|
+
# @option options [String] :trial_stepmod Path to trial repo root
|
|
18
|
+
# @option options [String] :reference_stepmod Path to reference repo root
|
|
19
|
+
# @return [Hash] Result with :success, :xml_path, :has_changes, :output
|
|
20
|
+
def compare(trial_schema, reference_schema, options = {})
|
|
21
|
+
ensure_eengine_available!
|
|
22
|
+
|
|
23
|
+
cmd = build_command(trial_schema, reference_schema, options)
|
|
24
|
+
output, error, status = Open3.capture3(*cmd)
|
|
25
|
+
|
|
26
|
+
unless status.success?
|
|
27
|
+
error_message = error.empty? ? "Unknown eengine error" : error.strip
|
|
28
|
+
raise ComparisonError.new(error_message, error)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
parse_output(output, options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Check if eengine is available on the system
|
|
35
|
+
#
|
|
36
|
+
# @return [Boolean] true if eengine binary is found
|
|
37
|
+
def available?
|
|
38
|
+
return false if ENV["EENGINE_DISABLED"] == "true"
|
|
39
|
+
|
|
40
|
+
eengine_path && eengine_executable?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Get the eengine version
|
|
44
|
+
#
|
|
45
|
+
# @return [String, nil] Version string or nil if unavailable
|
|
46
|
+
def version
|
|
47
|
+
return nil unless available?
|
|
48
|
+
|
|
49
|
+
cmd = [eengine_path, "--version"]
|
|
50
|
+
output, _, status = Open3.capture3(*cmd)
|
|
51
|
+
status.success? ? parse_version(output) : nil
|
|
52
|
+
rescue StandardError
|
|
53
|
+
nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def eengine_path
|
|
59
|
+
@eengine_path ||= find_eengine_binary
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def find_eengine_binary
|
|
63
|
+
# Search for eengine or eengine-* in PATH
|
|
64
|
+
ENV["PATH"].split(File::PATH_SEPARATOR).each do |dir|
|
|
65
|
+
# First try plain eengine
|
|
66
|
+
plain_path = File.join(dir, "eengine")
|
|
67
|
+
return plain_path if File.exist?(plain_path) && File.executable?(plain_path)
|
|
68
|
+
|
|
69
|
+
# Then try eengine-* pattern
|
|
70
|
+
Dir.glob(File.join(dir, "eengine-*")).each do |path|
|
|
71
|
+
return path if File.executable?(path)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def eengine_executable?
|
|
78
|
+
eengine_path && File.executable?(eengine_path)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def ensure_eengine_available!
|
|
82
|
+
raise EengineNotFoundError unless available?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def build_command(trial, reference, options)
|
|
86
|
+
cmd = [
|
|
87
|
+
eengine_path,
|
|
88
|
+
"--compare",
|
|
89
|
+
"-trial_schema", trial,
|
|
90
|
+
"-trial_stepmod", options[:trial_stepmod] || ".",
|
|
91
|
+
"-reference_schema", reference,
|
|
92
|
+
"-reference_stepmod", options[:reference_stepmod] || ".",
|
|
93
|
+
"-mode", options[:mode] || "resource",
|
|
94
|
+
"--xml-output"
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
# Add output directory if specified
|
|
98
|
+
if options[:out_dir]
|
|
99
|
+
cmd += ["-out-dir", options[:out_dir]]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
cmd
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def parse_output(output, _options)
|
|
106
|
+
# Extract XML file path from output
|
|
107
|
+
# eengine prints: "Writing \"path/to/file.xml\""
|
|
108
|
+
xml_match = output.match(/Writing "(.+\.xml)"/)
|
|
109
|
+
xml_path = xml_match ? xml_match[1] : nil
|
|
110
|
+
|
|
111
|
+
# Expand to absolute path if found
|
|
112
|
+
xml_path = File.expand_path(xml_path) if xml_path
|
|
113
|
+
|
|
114
|
+
# Determine if changes were detected
|
|
115
|
+
has_changes = detect_changes(output)
|
|
116
|
+
|
|
117
|
+
{
|
|
118
|
+
success: true,
|
|
119
|
+
xml_path: xml_path,
|
|
120
|
+
has_changes: has_changes,
|
|
121
|
+
output: output,
|
|
122
|
+
}
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def detect_changes(output)
|
|
126
|
+
# Check for various indicators of changes in the output
|
|
127
|
+
return true if output.include?("Comparing TYPE")
|
|
128
|
+
return true if output.include?("Comparing ENTITY")
|
|
129
|
+
return true if output.include?("Comparing FUNCTION")
|
|
130
|
+
return true if output.include?("Comparing RULE")
|
|
131
|
+
return true if output.include?("Comparing PROCEDURE")
|
|
132
|
+
|
|
133
|
+
# Check for modification indicators
|
|
134
|
+
return true if output.include?("changed")
|
|
135
|
+
return true if output.include?("modified")
|
|
136
|
+
return true if output.include?("added")
|
|
137
|
+
return true if output.include?("removed")
|
|
138
|
+
|
|
139
|
+
false
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def parse_version(output)
|
|
143
|
+
# Extract version from output like "Express Engine 5.2.7"
|
|
144
|
+
version_match = output.match(/Express Engine ([\d.]+)/)
|
|
145
|
+
version_match ? version_match[1] : nil
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "expressir/commands/changes_import_eengine"
|
|
4
|
+
|
|
5
|
+
module Suma
|
|
6
|
+
# Converts eengine comparison XML to Expressir::Changes::SchemaChange
|
|
7
|
+
# This is a thin wrapper around Expressir's ChangesImportEengine command
|
|
8
|
+
class EengineConverter
|
|
9
|
+
def initialize(xml_path, schema_name)
|
|
10
|
+
@xml_path = xml_path
|
|
11
|
+
@schema_name = schema_name
|
|
12
|
+
@xml_content = File.read(xml_path)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Convert the eengine XML to a ChangeSchema
|
|
16
|
+
#
|
|
17
|
+
# @param version [String] Version number for this change version
|
|
18
|
+
# @param existing_change_schema [Expressir::Changes::SchemaChange, nil]
|
|
19
|
+
# Existing schema to append to, or nil to create new
|
|
20
|
+
# @return [Expressir::Changes::SchemaChange] The updated change schema
|
|
21
|
+
def convert(version:, existing_change_schema: nil)
|
|
22
|
+
# Use Expressir's built-in conversion which properly handles
|
|
23
|
+
# HTML elements in descriptions
|
|
24
|
+
Expressir::Commands::ChangesImportEengine.from_xml(
|
|
25
|
+
@xml_content,
|
|
26
|
+
@schema_name,
|
|
27
|
+
version,
|
|
28
|
+
existing_schema: existing_change_schema,
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Suma
|
|
4
|
+
# Simple schema class for standalone EXPRESS files
|
|
5
|
+
# Used when exporting individual .exp files that are not part of a manifest
|
|
6
|
+
class ExportStandaloneSchema
|
|
7
|
+
attr_accessor :id, :path
|
|
8
|
+
|
|
9
|
+
def initialize(id:, path:)
|
|
10
|
+
@id = id
|
|
11
|
+
@path = path
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
data/lib/suma/schema_exporter.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "express_schema"
|
|
4
4
|
require_relative "utils"
|
|
5
|
+
require_relative "export_standalone_schema"
|
|
5
6
|
require "fileutils"
|
|
6
7
|
|
|
7
8
|
module Suma
|
|
@@ -44,7 +45,7 @@ module Suma
|
|
|
44
45
|
def export_single_schema(schema)
|
|
45
46
|
# Check if this is a standalone EXPRESS file
|
|
46
47
|
# (not from a manifest structure)
|
|
47
|
-
is_standalone_file = schema.is_a?(
|
|
48
|
+
is_standalone_file = schema.is_a?(ExportStandaloneSchema)
|
|
48
49
|
schema_output_path = determine_output_path(schema, is_standalone_file)
|
|
49
50
|
|
|
50
51
|
express_schema = ExpressSchema.new(
|
data/lib/suma/version.rb
CHANGED
data/suma.gemspec
CHANGED
|
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
|
|
|
33
33
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
34
34
|
spec.require_paths = ["lib"]
|
|
35
35
|
|
|
36
|
-
spec.add_dependency "expressir", "~> 2.1"
|
|
36
|
+
spec.add_dependency "expressir", ">= 2.1.29", "~> 2.1"
|
|
37
37
|
spec.add_dependency "glossarist", "~> 2.3.7"
|
|
38
38
|
spec.add_dependency "lutaml-model", "~> 0.7"
|
|
39
39
|
spec.add_dependency "metanorma-cli"
|
metadata
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: suma
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.26
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-10-
|
|
11
|
+
date: 2025-10-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: expressir
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: 2.1.29
|
|
17
20
|
- - "~>"
|
|
18
21
|
- !ruby/object:Gem::Version
|
|
19
22
|
version: '2.1'
|
|
@@ -21,6 +24,9 @@ dependencies:
|
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
27
|
+
- - ">="
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: 2.1.29
|
|
24
30
|
- - "~>"
|
|
25
31
|
- !ruby/object:Gem::Version
|
|
26
32
|
version: '2.1'
|
|
@@ -162,6 +168,7 @@ files:
|
|
|
162
168
|
- lib/suma.rb
|
|
163
169
|
- lib/suma/cli.rb
|
|
164
170
|
- lib/suma/cli/build.rb
|
|
171
|
+
- lib/suma/cli/compare.rb
|
|
165
172
|
- lib/suma/cli/convert_jsdai.rb
|
|
166
173
|
- lib/suma/cli/export.rb
|
|
167
174
|
- lib/suma/cli/extract_terms.rb
|
|
@@ -172,6 +179,10 @@ files:
|
|
|
172
179
|
- lib/suma/cli/validate_links.rb
|
|
173
180
|
- lib/suma/collection_config.rb
|
|
174
181
|
- lib/suma/collection_manifest.rb
|
|
182
|
+
- lib/suma/eengine/errors.rb
|
|
183
|
+
- lib/suma/eengine/wrapper.rb
|
|
184
|
+
- lib/suma/eengine_converter.rb
|
|
185
|
+
- lib/suma/export_standalone_schema.rb
|
|
175
186
|
- lib/suma/express_schema.rb
|
|
176
187
|
- lib/suma/jsdai.rb
|
|
177
188
|
- lib/suma/jsdai/figure.rb
|