diff options
| -rw-r--r-- | lib/spandx/terraform/parsers/hcl.rb | 58 | ||||
| -rw-r--r-- | spec/unit/terraform/parsers/hcl_spec.rb | 35 |
2 files changed, 78 insertions, 15 deletions
diff --git a/lib/spandx/terraform/parsers/hcl.rb b/lib/spandx/terraform/parsers/hcl.rb index 0a2b99f..5788ab0 100644 --- a/lib/spandx/terraform/parsers/hcl.rb +++ b/lib/spandx/terraform/parsers/hcl.rb @@ -4,24 +4,28 @@ module Spandx module Terraform module Parsers class Hcl < Parslet::Parser - rule(:anything) { match('.').repeat } rule(:alpha) { match['a-zA-Z'] } rule(:assign) { str('=') } rule(:crlf) { match('[\r\n]') } rule(:digit) { match('\d') } rule(:dot) { str('.') } rule(:eol) { whitespace? >> crlf.repeat } + rule(:hyphen) { str('-') } rule(:lcurly) { str('{') } + rule(:major) { number } + rule(:major_minor) { (number >> dot >> number) } + rule(:major_minor_patch) { number >> dot >> number >> dot >> number } rule(:number) { digit.repeat } + rule(:pre_release) { hyphen >> (alpha | digit).repeat } + rule(:pre_release?) { pre_release.maybe } rule(:quote) { str('"') } rule(:rcurly) { str('}') } rule(:space) { match('\s') } - rule(:pre_release) { hyphen >> (alpha | digit).repeat } - rule(:pre_release?) { pre_release.maybe } + rule(:tilda_wacka) { str("~>") } rule(:version) { number >> dot >> number >> dot >> number >> pre_release? } rule(:whitespace) { space.repeat } rule(:whitespace?) { whitespace.maybe } - rule(:hyphen) { str('-') } + rule(:greater_than_or_equal_to) { str('>=') } rule :attribute_name do alpha.repeat @@ -35,29 +39,55 @@ module Spandx match('[0-9A-Za-z.~> ]') end + rule(:version_constraint) do + pessimistic_version_constraint | greater_than_or_equal_to_version + end + rule :version_assignment do - whitespace? >> str('version') >> whitespace >> assign >> whitespace >> quote >> version.as(:version) >> quote + str('version') >> whitespace >> assign >> whitespace >> quote >> version.as(:version) >> quote + end + + rule :constraint_assignment do + str("constraints") >> whitespace >> assign >> whitespace >> quote >> version_constraint.as(:constraints) >> quote + end + + rule(:pessimistic_version_constraint) do + tilda_wacka >> whitespace >> ( + major_minor_patch | + major_minor | + major + ) end - rule :constraints do - anything + rule(:greater_than_or_equal_to_version) do + greater_than_or_equal_to >> whitespace >> ( + major_minor_patch | + major_minor | + major + ) end - rule :hashes do - anything + rule :argument do + ( + str('version') | + str('constraints') + ).as(:argument) >> whitespace >> assign >> whitespace >> quote >> ( + version | + version_constraint + ).as(:value) >> quote end - rule :assignments do - # (version_assignment | constraints | hashes).repeat - version_assignment >> eol + rule :arguments do + #((version_assignment | constraint_assignment) >> eol).repeat + (argument >> eol).repeat end rule :block do - whitespace >> lcurly >> eol >> assignments >> rcurly >> eol + whitespace >> lcurly >> eol >> arguments >> rcurly >> eol end rule :identifier do - whitespace >> quote >> match('[a-zA-Z./]').repeat.as(:name) >> quote >> whitespace + whitespace >> quote >> ((alpha | match('[./]')).repeat).as(:name) >> quote >> whitespace end rule :provider do diff --git a/spec/unit/terraform/parsers/hcl_spec.rb b/spec/unit/terraform/parsers/hcl_spec.rb index 87acd4a..fc4a29f 100644 --- a/spec/unit/terraform/parsers/hcl_spec.rb +++ b/spec/unit/terraform/parsers/hcl_spec.rb @@ -11,13 +11,18 @@ RSpec.describe Spandx::Terraform::Parsers::Hcl do <<~HCL provider "registry.terraform.io/hashicorp/aws" { version = "3.39.0" + constraints = "~> 3.27" } HCL end specify { expect(subject[0].dig(:provider, :name).to_s).to eql('registry.terraform.io/hashicorp/aws') } - specify { expect(subject[0].dig(:provider, :version).to_s).to eql('3.39.0') } + specify { expect(subject[1].dig(:provider, :version).to_s).to eql('3.39.0') } + specify { expect(subject[2].dig(:provider, :constraints).to_s).to eql('~> 3.27') } specify { expect(subject).to be_truthy } + specify do + puts subject + end end end @@ -53,6 +58,34 @@ RSpec.describe Spandx::Terraform::Parsers::Hcl do end end + describe '#constraint_assignment' do + subject { parser.constraint_assignment } + + [ + 'constraints = ">= 3"', + 'constraints = ">= 3.27"', + 'constraints = ">= 3.27.0"', + 'constraints = "~> 3"', + 'constraints = "~> 3.27"', + 'constraints = "~> 3.27.0"', + ].each do |raw| + specify { expect(subject).to parse(raw) } + end + end + + describe '#version_constraint' do + [ + '~> 3', + '~> 3.27', + '~> 3.27.0', + '>= 1.2.0', + '>= 1.20', + '>= 10', + ].each do |raw| + specify { expect(parser.version_constraint).to parse(raw) } + end + end + (('a'..'z').to_a + ('A'..'Z').to_a).each do |letter| specify { expect(parser.alpha).to parse(letter) } end |
