-
Notifications
You must be signed in to change notification settings - Fork 4
Erb template #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Rezenders
wants to merge
14
commits into
rock-control:master
Choose a base branch
from
tidewise:erb_template
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Erb template #40
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
1582ed5
improvements YARD docs
Rezenders e95debc
fix expected paths in test_xml.rb
Rezenders 2d35534
fallback to model.sdf.erb when there is no model.sdf file
Rezenders 4301929
add render_erb_sdf_model to erb module
Rezenders 5739d8c
move XML exceptions to exceptions.rb
Rezenders 9548488
add SDF::Loader that works for both .sdf and .sdf.erb
Rezenders d23b7fe
SDF::Loader -> SDF::ERBLoader and new SDF::Loader for SDF only
Rezenders 2fd84f5
mv methods from ERB module to ERBLoader
Rezenders 9d25e81
add `default_loader` as singleton variable of SDF::XML
Rezenders e27c140
1 loader only & erb templates must have ".sdf.erb" extension
Rezenders ab087ef
rm validate_sdf_root and move check into load_sdf_raw
Rezenders 73cbee3
WIP: erb context
Rezenders 4fec095
rm `respond_to_missing?` and update tests
Rezenders 2388f45
rm SDFPoseParameter from test
Rezenders File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module SDF | ||
| # class to represent the context for ERB evaluation | ||
| class ERBContext < BasicObject | ||
| class MissingArgumentError < ::ArgumentError; end | ||
|
|
||
| def initialize(args: {}) | ||
| @args = deep_symbolize_keys(args) | ||
| end | ||
|
|
||
| def defaults(document) | ||
| @args = deep_merge(deep_symbolize_keys(document), @args) | ||
| end | ||
|
|
||
| # Recursively converts all hash keys to symbols | ||
| def deep_symbolize_keys(val) | ||
| return val unless val.kind_of?(::Hash) | ||
|
|
||
| val.transform_keys(&:to_sym).transform_values { |v| deep_symbolize_keys(v) } | ||
| end | ||
|
|
||
| # Recursively merges defaults with overrides | ||
| def deep_merge(defaults, overrides) | ||
| defaults.merge(overrides) do |_, oldval, newval| | ||
| if oldval.kind_of?(::Hash) && newval.kind_of?(::Hash) | ||
| deep_merge(oldval, newval) | ||
| else | ||
| newval | ||
| end | ||
| end | ||
| end | ||
|
|
||
| # rubocop:disable Style/OptionalBooleanParameter | ||
| def respond_to?(method_name, include_all = false) | ||
| sym = method_name.to_sym | ||
| return true if ERBContext.method_defined?(sym) | ||
| return true if include_all && ERBContext.private_method_defined?(sym) | ||
|
|
||
| @args.key?(method_name.to_sym) | ||
| end | ||
| # rubocop:enable Style/OptionalBooleanParameter | ||
|
|
||
| # rubocop:disable Style/MissingRespondToMissing | ||
| def method_missing(method_name, *) | ||
| if @args.key?(method_name) | ||
| val = @args[method_name] | ||
| return val.kind_of?(::Hash) ? ERBContext.new(args: val) : val | ||
| end | ||
| ::Kernel.raise MissingArgumentError.new( | ||
| "no ERB argument available named '#{method_name}'" | ||
| ) | ||
| end | ||
| # rubocop:enable Style/MissingRespondToMissing | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,24 @@ | ||
| module SDF | ||
| class InternalError < RuntimeError; end | ||
|
|
||
| module XML | ||
| # Exception raised when trying to load a model URI, but the model does | ||
| # not contain a SDF entry for the required SDF version | ||
| class UnavailableSDFVersionInModel < ArgumentError; end | ||
| # Exception raised when trying to load a file that is not a SDF file | ||
| class NotSDF < ArgumentError; end | ||
| # Exception raised when trying to load a malformed XML file | ||
| class InvalidXML < ArgumentError; end | ||
|
|
||
| # Exception raised when trying to resolve a model that cannot be found | ||
| # in {model_path} | ||
| class NoSuchModel < ArgumentError | ||
| attr_reader :model_name | ||
|
|
||
| def initialize(model_name) | ||
| super | ||
| @model_name = model_name | ||
| end | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require "erb" | ||
| require "sdf/erb_context" | ||
|
|
||
| module SDF | ||
| # class to load SDF and ERB templated SDF files | ||
| class Loader | ||
| def initialize(erb_args: {}) | ||
| @erb_args = erb_args | ||
| end | ||
|
|
||
| # Open a SDF file SDF file and returns its XML representation. | ||
| # | ||
| # @param [String] sdf_file the path to the SDF file | ||
| # @raise [Errno::ENOENT] if the files does not exist | ||
| # @raise [NotSDF] if the file is not a SDF file | ||
| # @raise [InvalidXML] if the file is not a valid XML file | ||
| # @return [REXML::Element] sdf_file's content as a REXML::Element instance | ||
| def load_sdf_raw(sdf_file) | ||
| xml_string = File.read(sdf_file) | ||
| if sdf_file.end_with?(".sdf.erb") | ||
| erb_context = SDF::ERBContext.new(args: @erb_args) | ||
| xml_string = ::ERB.new(xml_string, trim_mode: "-").result( | ||
| erb_context.instance_eval { ::Kernel.binding } | ||
| ) | ||
| end | ||
| sdf = REXML::Document.new(xml_string) | ||
|
|
||
| return sdf if sdf.root.name == "sdf" | ||
|
|
||
| raise SDF::XML::NotSDF, "#{sdf_file} is not a SDF file" | ||
| rescue REXML::ParseException => e | ||
| error_message = "Cannot load #{sdf_file}: #{e.message}" | ||
|
|
||
| if xml_string.match?(/<%.*?%>/m) | ||
| error_message += "\nHint: This file appears to be an ERB template. " \ | ||
| "Make sure it ends with the extension .sdf.erb" | ||
| end | ||
|
|
||
| raise SDF::XML::InvalidXML, error_message | ||
| end | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
test/data/invalid_models/erb_model_with_sdf_extension/model.config
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <?xml version="1.0"?> | ||
| <model> | ||
| <name>simple_model</name> | ||
| <sdf version="1.5">model.sdf</sdf> | ||
| </model> |
42 changes: 42 additions & 0 deletions
42
test/data/invalid_models/erb_model_with_sdf_extension/model.sdf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| <?xml version="1.0" ?> | ||
| <% | ||
| default_gps_pose = [-0.679, 0.0, 1.920, 0.0, 0.0, 0.0] | ||
| default_gps2_pose = [2.571, 0.044, 0.808, 0.0, 0.0, 0.0] | ||
|
|
||
| gps1_pose = (defined?(links) && links.find { |link| link[:name] == "gps" }&.dig(:pose)) || default_gps_pose | ||
| gps2_pose = (defined?(links) && links.find { |link| link[:name] == "gps2" }&.dig(:pose)) || default_gps2_pose | ||
| %> | ||
| <sdf version="1.6"> | ||
| <model name="simple_model_erb"> | ||
| <link name="root"> | ||
| <sensor name="g" type="gps" /> | ||
| </link> | ||
| <link name="child" /> | ||
| <joint name="roo2child" type="revolute"> | ||
| <parent>root</parent> | ||
| <child>child</child> | ||
| <axis> | ||
| </axis> | ||
| </joint> | ||
|
|
||
| <link name="gps"> | ||
| <pose><%= gps1_pose.join(' ') %></pose> | ||
| </link> | ||
| <joint name="gps_attachment" type="fixed"> | ||
| <parent>root</parent> | ||
| <child>gps</child> | ||
| </joint> | ||
|
|
||
| <link name="gps2"> | ||
| <pose><%= gps2_pose.join(' ') %></pose> | ||
| </link> | ||
| <joint name="gps2_attachment" type="fixed"> | ||
| <parent>root</parent> | ||
| <child>gps2</child> | ||
| </joint> | ||
|
|
||
| <plugin name="gps_test"> | ||
| <task model="rock_gazebo::GPSTask"/> | ||
| </plugin> | ||
| </model> | ||
| </sdf> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1 @@ | ||
| <?xml version="1.0"?> | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| <?xml version="1.0"?> | ||
| <model> | ||
| <name>simple_model</name> | ||
| <sdf version="1.5">model.sdf.erb</sdf> | ||
| </model> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| <?xml version="1.0" ?> | ||
| <% | ||
| defaults({ | ||
| poses: { | ||
| gps: [-0.679, 0.0, 1.920, 0.0, 0.0, 0.0], | ||
| gps2: [2.571, 0.044, 0.808, 0.0, 0.0, 0.0] | ||
| } | ||
| }) | ||
| %> | ||
| <sdf version="1.6"> | ||
| <model name="simple_model_erb"> | ||
| <link name="root"> | ||
| <sensor name="g" type="gps" /> | ||
| </link> | ||
| <link name="child" /> | ||
| <joint name="roo2child" type="revolute"> | ||
| <parent>root</parent> | ||
| <child>child</child> | ||
| <axis> | ||
| </axis> | ||
| </joint> | ||
|
|
||
| <link name="gps"> | ||
| <pose><%= poses.gps.join(' ') %></pose> | ||
| </link> | ||
| <joint name="gps_attachment" type="fixed"> | ||
| <parent>root</parent> | ||
| <child>gps</child> | ||
| </joint> | ||
|
|
||
| <link name="gps2"> | ||
| <pose><%= poses.gps2.join(' ') %></pose> | ||
| </link> | ||
| <joint name="gps2_attachment" type="fixed"> | ||
| <parent>root</parent> | ||
| <child>gps2</child> | ||
| </joint> | ||
|
|
||
| <plugin name="gps_test"> | ||
| <task model="rock_gazebo::GPSTask"/> | ||
| </plugin> | ||
| </model> | ||
| </sdf> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.