summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authormo khan <mo.khan@gmail.com>2020-05-07 17:25:56 -0600
committermo khan <mo.khan@gmail.com>2020-05-07 17:25:56 -0600
commitcc9eda11425e6f6ec3243fbcd768c4e2a37adf2a (patch)
tree52745bf01649b5f7b3be20ce6f68f173c65ca921 /lib
parent99dc28a123b59d5052db3e20ec428c023091ee13 (diff)
Build a composite license that traverses and expression tree
Diffstat (limited to 'lib')
-rw-r--r--lib/spandx/core/guess.rb9
-rw-r--r--lib/spandx/spdx/composite_license.rb59
2 files changed, 61 insertions, 7 deletions
diff --git a/lib/spandx/core/guess.rb b/lib/spandx/core/guess.rb
index 4383374..62967ce 100644
--- a/lib/spandx/core/guess.rb
+++ b/lib/spandx/core/guess.rb
@@ -7,7 +7,6 @@ module Spandx
def initialize(catalogue)
@catalogue = catalogue
- @expression_cache = {}
end
def license_for(raw)
@@ -79,12 +78,8 @@ module Spandx
end
def from_expression(content)
- @expression_cache.fetch(content.raw) do
- tree = Spdx::Expression.new.parse(content.raw)
- @expression_cache[content.raw] = catalogue[tree[0][:left].to_s]
- end
- rescue Parslet::ParseFailed
- nil
+ Spandx::Spdx::CompositeLicense
+ .from_expression(content.raw, catalogue)
end
end
end
diff --git a/lib/spandx/spdx/composite_license.rb b/lib/spandx/spdx/composite_license.rb
new file mode 100644
index 0000000..e429778
--- /dev/null
+++ b/lib/spandx/spdx/composite_license.rb
@@ -0,0 +1,59 @@
+
+module Spandx
+ module Spdx
+ class CompositeLicense < License
+ def self.from_expression(expression, catalogue)
+ tree = Spdx::Expression.new.parse(expression)
+ new(tree[0], catalogue)
+ rescue Parslet::ParseFailed
+ nil
+ end
+
+ def initialize(tree, catalogue)
+ @catalogue = catalogue
+ @tree = tree
+ super({ })
+ end
+
+ def id
+ if right
+ ["(#{left.id}", operator, "#{right.id})"].compact.join(' ').squeeze(' ').strip
+ else
+ "#{left.id}"
+ end
+ end
+
+ def name
+ if right
+ [left.name, operator, right.name].compact.join(' ').squeeze(' ').strip
+ else
+ left.name
+ end
+ end
+
+ private
+
+ def left
+ node_for(@tree[:left])
+ end
+
+ def operator
+ @tree[:op].to_s.upcase
+ end
+
+ def right
+ node_for(@tree[:right])
+ end
+
+ def node_for(item)
+ return if item.nil?
+
+ if item.is_a?(Hash)
+ self.class.new(item, @catalogue)
+ else
+ @catalogue[item.to_s] || License.unknown(item.to_s)
+ end
+ end
+ end
+ end
+end