-
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
base: master
Are you sure you want to change the base?
Erb template #40
Changes from 7 commits
1582ed5
e95debc
2d35534
4301929
5739d8c
9548488
d23b7fe
2fd84f5
9d25e81
e27c140
ab087ef
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require "erb" | ||
|
|
||
| module SDF | ||
| # Module for handling ERB files | ||
| module ERB | ||
| module_function | ||
|
|
||
|
Rezenders marked this conversation as resolved.
Outdated
|
||
| # Parses an ERB string and returns the raw rendered string | ||
| # | ||
| # @param [String] erb_content ERB template file content as string | ||
| # @param [Hash] erb_args the configuration arguments to evaluate | ||
| # @return [String] the raw rendered XML string representing the model | ||
| def parse_erb_as_str(erb_content, **erb_args) | ||
| erb_engine = ::ERB.new(erb_content, trim_mode: "-") | ||
|
|
||
| # Render the ERB template with the passed hash arguments | ||
| erb_engine.result_with_hash(erb_args) | ||
| end | ||
|
|
||
| # Renders an ERB template and returns it as a REXML::Document | ||
| # | ||
| # @return [REXML::Document] the rendered sdf model | ||
| def render_erb_sdf_model(path, **erb_args) | ||
| erb_content = File.read(path) | ||
| solved_erb_as_sdf_str = parse_erb_as_str(erb_content, **erb_args) | ||
|
|
||
| REXML::Document.new(solved_erb_as_sdf_str) | ||
| end | ||
| end | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative "erb" | ||
| require_relative "sdf_loader" | ||
|
|
||
| module SDF | ||
| # class to load SDF and ERB templated SDF files | ||
| class ERBLoader < Loader | ||
|
Rezenders marked this conversation as resolved.
Outdated
|
||
| def initialize(erb_args: {}) | ||
| super() | ||
| @erb_args = erb_args | ||
| end | ||
|
|
||
| def parse_sdf_document(sdf_file) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you should make a difference between erb and non-erb files, that is parse ERB only when the extension is
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I told him to do it like this. If you mean for having an explicit error when a non-erb file is given to an ERBLoader, I feel this is overkill and it would painful in the Robot level to constantly juggle between loaders when the model file changes (I dont think you mean this, just getting it out there). In the case you want to split the functionality between
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @jhonasiv on this one, but in this case I would simply remove the base In case we enforce the files to end with But anyway, I don't have a strong opinion on this, so I would happily go with any
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A part from this comment, the review was addressed. I didn't address this one as it seems there is no consensus yet, let me know what to do about this one
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I strongly want the ERB files to have This comes from experience (the orogen configuration files
The whole "having different loaders" because of this makes no sense to me. The difference between ERB and non-ERB files is minimal (the ERB processing itself). Actually having a single loader makes sure we align both codepaths behaviours.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand @jhonasiv's concern about the errors though. But now, having the separation .sdf / .sdf.erb also makes sure that tooling that knows nothing about .sdf (a.k.a. "non-rock tooling") isn't accidentally given something they can't handle.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validated that ERB markers are invalid XML. We could handle invalid XML in the |
||
| SDF::ERB.render_erb_sdf_model(sdf_file, **@erb_args) | ||
| end | ||
| end | ||
| end | ||
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative "erb" | ||
| require_relative "exceptions" | ||
|
|
||
| module SDF | ||
| # class to load SDF and ERB templated SDF files | ||
| class Loader | ||
| # 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) | ||
| find_or_raise_file_not_found(sdf_file) | ||
|
|
||
| sdf = begin | ||
| parse_sdf_document(sdf_file) | ||
| rescue REXML::ParseException => e | ||
| unless e.message.include?("No root") | ||
| raise SDF::XML::InvalidXML, | ||
| "Cannot load #{sdf_file}: #{e.message}" | ||
| end | ||
|
|
||
| REXML::Document.new | ||
|
Rezenders marked this conversation as resolved.
Outdated
|
||
| end | ||
| validate_sdf_root(sdf, sdf_file) | ||
|
|
||
| sdf | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def find_or_raise_file_not_found(sdf_file) | ||
| return if File.exist?(sdf_file) | ||
|
|
||
| file_name = File.basename(sdf_file) | ||
| dir_path = File.dirname(sdf_file) | ||
| raise Errno::ENOENT, | ||
| "Cannot find '#{file_name}' in '#{dir_path}'." \ | ||
| "You probably want to update the GAZEBO_MODEL_PATH " \ | ||
| "environment variable, or set SDF.model_path explicitly." | ||
|
Rezenders marked this conversation as resolved.
Outdated
|
||
| end | ||
|
|
||
| def parse_sdf_document(sdf_file) | ||
| File.open(sdf_file) do |io| | ||
| REXML::Document.new(io) | ||
| end | ||
| end | ||
|
|
||
| def validate_sdf_root(sdf, sdf_file) | ||
| unless sdf.root | ||
| raise SDF::XML::NotSDF, | ||
| "#{sdf_file} can be parsed as an XML file, but it " \ | ||
| "does not have a root" | ||
| end | ||
| return if %w[sdf gazebo].include?(sdf.root.name) | ||
|
Rezenders marked this conversation as resolved.
Outdated
|
||
|
|
||
| raise SDF::XML::NotSDF, "#{sdf_file} is not a SDF file" | ||
| end | ||
| end | ||
| end | ||
Uh oh!
There was an error while loading. Please reload this page.