summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormo khan <mo.khan@gmail.com>2020-06-22 20:55:28 -0600
committerGitHub <noreply@github.com>2020-06-22 20:55:28 -0600
commit1cb18873b502a5e37d4d34d91244695c98670ea6 (patch)
treec8552e7ee0338fd38e61fca14f23cd254ec92425
parentf4452bdfe65b8f3c943c73f66f94f78dff59cb7f (diff)
parent2b496d743ec311f2749a6c96cab0397bf954f323 (diff)
Merge pull request #29 from spandx/streaming
Stream results to stdout
-rw-r--r--.github/licensed/bundler/oj.dep.yml32
-rw-r--r--.github/licensed/bundler/tty-cursor.dep.yml (renamed from .github/licensed/bundler/nanospinner.dep.yml)12
-rw-r--r--.github/licensed/bundler/tty-spinner.dep.yml (renamed from .github/licensed/bundler/tty-screen.dep.yml)7
-rw-r--r--.rubocop.yml3
-rw-r--r--CHANGELOG.md8
-rw-r--r--Dockerfile2
-rw-r--r--Gemfile.lock29
-rwxr-xr-xbin/json-benchmark29
-rwxr-xr-xexe/spandx1
-rw-r--r--lib/spandx.rb2
-rw-r--r--lib/spandx/cli.rb4
-rw-r--r--lib/spandx/cli/commands/scan.rb38
-rw-r--r--lib/spandx/cli/main.rb4
-rw-r--r--lib/spandx/cli/printer.rb27
-rw-r--r--lib/spandx/cli/printers/csv.rb17
-rw-r--r--lib/spandx/cli/printers/json.rb17
-rw-r--r--lib/spandx/cli/printers/table.rb41
-rw-r--r--lib/spandx/core/git.rb12
-rw-r--r--lib/spandx/core/plugin.rb6
-rw-r--r--lib/spandx/core/report.rb54
-rw-r--r--lib/spandx/core/spinner.rb51
-rw-r--r--lib/spandx/core/thread_pool.rb49
-rw-r--r--lib/spandx/dotnet/nuget_gateway.rb2
-rw-r--r--lib/spandx/js/parsers/npm.rb4
-rw-r--r--lib/spandx/js/yarn_pkg.rb2
-rw-r--r--lib/spandx/php/packagist_gateway.rb2
-rw-r--r--lib/spandx/php/parsers/composer.rb2
-rw-r--r--lib/spandx/python/parsers/pipfile_lock.rb2
-rw-r--r--lib/spandx/python/pypi.rb26
-rw-r--r--lib/spandx/python/source.rb2
-rw-r--r--lib/spandx/ruby/gateway.rb2
-rw-r--r--spandx.gemspec6
-rw-r--r--spec/fixtures/help-scan.expected20
-rw-r--r--spec/integration/cli/scan_spec.rb10
-rw-r--r--spec/integration/core/git_spec.rb12
-rw-r--r--spec/unit/cli/scan_spec.rb2
-rw-r--r--spec/unit/core/report_spec.rb17
-rw-r--r--spec/unit/python/pypi_spec.rb173
-rw-r--r--spec/unit/ruby/parsers/gemfile_lock_spec.rb19
39 files changed, 439 insertions, 309 deletions
diff --git a/.github/licensed/bundler/oj.dep.yml b/.github/licensed/bundler/oj.dep.yml
new file mode 100644
index 0000000..622bb0d
--- /dev/null
+++ b/.github/licensed/bundler/oj.dep.yml
@@ -0,0 +1,32 @@
+---
+name: oj
+version: 3.10.6
+type: bundler
+summary: A fast JSON parser and serializer.
+homepage: http://www.ohler.com/oj
+license: mit
+licenses:
+- sources: LICENSE
+ text: |
+ The MIT License (MIT)
+
+ Copyright (c) 2012 Peter Ohler
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+notices: []
diff --git a/.github/licensed/bundler/nanospinner.dep.yml b/.github/licensed/bundler/tty-cursor.dep.yml
index cc6f56f..177d1c6 100644
--- a/.github/licensed/bundler/nanospinner.dep.yml
+++ b/.github/licensed/bundler/tty-cursor.dep.yml
@@ -1,14 +1,16 @@
---
-name: nanospinner
-version: 1.0.0
+name: tty-cursor
+version: 0.7.1
type: bundler
-summary: A tiny commandline spinner
-homepage: http://github.com/julik/nanospinner
+summary: Terminal cursor positioning, visibility and text manipulation.
+homepage: https://ttytoolkit.org
license: mit
licenses:
- sources: LICENSE.txt
text: |
- Copyright (c) 2014 Julik Tarkhanov
+ Copyright (c) 2015 Piotr Murach
+
+ MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/.github/licensed/bundler/tty-screen.dep.yml b/.github/licensed/bundler/tty-spinner.dep.yml
index 1f592d7..417d94d 100644
--- a/.github/licensed/bundler/tty-screen.dep.yml
+++ b/.github/licensed/bundler/tty-spinner.dep.yml
@@ -1,9 +1,8 @@
---
-name: tty-screen
-version: 0.7.1
+name: tty-spinner
+version: 0.9.3
type: bundler
-summary: Terminal screen size detection which works on Linux, OS X and Windows/Cygwin
- platforms and supports MRI, JRuby and Rubinius interpreters.
+summary: A terminal spinner for tasks that have non-deterministic time frame.
homepage: https://ttytoolkit.org
license: mit
licenses:
diff --git a/.rubocop.yml b/.rubocop.yml
index b8ea25c..54503f6 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -22,6 +22,9 @@ Layout/EndOfLine:
Layout/FirstArrayElementIndentation:
EnforcedStyle: consistent
+Layout/FirstHashElementIndentation:
+ EnforcedStyle: consistent
+
Layout/MultilineMethodCallIndentation:
Enabled: true
EnforcedStyle: indented
diff --git a/CHANGELOG.md b/CHANGELOG.md
index db120de..8f592fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
+### Fixed
+- Process PyPI package urls with single digit versions.
+- Remove unsupported `hash` report from help text.
+
+### Changed
+- Stream output to output stream as soon as results are available.
+- Switch to `Oj` for JSON parsing.
+- Run spinner on background thread.
## [0.13.4] - 2020-05-26
### Added
diff --git a/Dockerfile b/Dockerfile
index 7dcc15b..905da3a 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
FROM alpine:latest
WORKDIR /scan
-ENV PACKAGES build-base bash ruby ruby-dev ruby-json ruby-rdoc git libxml2-dev openssl-dev
+ENV PACKAGES build-base bash ruby ruby-bigdecimal ruby-dev ruby-json ruby-rdoc git libxml2-dev openssl-dev
COPY . /opt/spandx/
RUN apk update && \
apk add $PACKAGES && \
diff --git a/Gemfile.lock b/Gemfile.lock
index 139dfba..a9dc845 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -4,13 +4,13 @@ PATH
spandx (0.13.4)
addressable (~> 2.7)
bundler (>= 1.16, < 3.0.0)
- nanospinner (~> 1.0.0)
net-hippie (~> 0.3)
nokogiri (~> 1.10)
+ oj (~> 3.10)
parslet (~> 2.0)
terminal-table (~> 1.8)
thor
- tty-screen (~> 0.7)
+ tty-spinner (~> 0.9)
zeitwerk (~> 2.3)
GEM
@@ -18,7 +18,7 @@ GEM
specs:
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
- ast (2.4.0)
+ ast (2.4.1)
benchmark-ips (2.8.2)
benchmark-malloc (0.2.0)
benchmark-perf (0.6.0)
@@ -34,7 +34,7 @@ GEM
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
hashdiff (1.0.1)
- licensed (2.10.0)
+ licensed (2.11.1)
bundler (>= 1.10)
licensee (>= 9.14.0, < 10.0.0)
parallel (>= 0.18.0)
@@ -51,15 +51,15 @@ GEM
thor (>= 0.19, < 2.0)
mini_portile2 (2.4.0)
multipart-post (2.1.1)
- nanospinner (1.0.0)
net-hippie (0.3.2)
nokogiri (1.10.9)
mini_portile2 (~> 2.4.0)
octokit (4.18.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
+ oj (3.10.6)
parallel (1.19.1)
- parser (2.7.1.2)
+ parser (2.7.1.3)
ast (~> 2.4.0)
parslet (2.0.0)
pathname-common_prefix (0.0.1)
@@ -68,6 +68,7 @@ GEM
rake (13.0.1)
rake-compiler (1.1.0)
rake
+ regexp_parser (1.7.1)
reverse_markdown (1.4.0)
nokogiri
rexml (3.2.4)
@@ -89,14 +90,18 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.3)
- rubocop (0.83.0)
+ rubocop (0.85.1)
parallel (~> 1.10)
parser (>= 2.7.0.1)
rainbow (>= 2.2.2, < 4.0)
+ regexp_parser (>= 1.7)
rexml
+ rubocop-ast (>= 0.0.3)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 2.0)
- rubocop-rspec (1.39.0)
+ rubocop-ast (0.0.3)
+ parser (>= 2.7.0.1)
+ rubocop-rspec (1.40.0)
rubocop (>= 0.68.1)
ruby-prof (1.4.1)
ruby-progressbar (1.10.1)
@@ -110,9 +115,11 @@ GEM
unicode-display_width (~> 1.1, >= 1.1.1)
thor (0.20.3)
tomlrb (1.3.0)
- tty-screen (0.7.1)
+ tty-cursor (0.7.1)
+ tty-spinner (0.9.3)
+ tty-cursor (~> 0.7)
unicode-display_width (1.7.0)
- vcr (5.1.0)
+ vcr (6.0.0)
webmock (3.8.3)
addressable (>= 2.3.6)
crack (>= 0.3.2)
@@ -135,7 +142,7 @@ DEPENDENCIES
rubocop-rspec (~> 1.22)
ruby-prof (~> 1.3)
spandx!
- vcr (~> 5.0)
+ vcr (~> 6.0)
webmock (~> 3.7)
BUNDLED WITH
diff --git a/bin/json-benchmark b/bin/json-benchmark
new file mode 100755
index 0000000..c678823
--- /dev/null
+++ b/bin/json-benchmark
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'bundler/inline'
+
+gemfile do
+ source 'https://rubygems.org'
+
+ gem 'benchmark-ips', '~> 2.8'
+ gem 'oj'
+end
+
+require 'benchmark/ips'
+require 'json'
+require 'oj'
+
+Oj.default_options = { mode: :strict }
+
+json = JSON.pretty_generate({
+ string: 'spandx',
+ number: 1234,
+ array: ['MIT']
+})
+
+Benchmark.ips do |x|
+ x.report('JSON.parse') { JSON.parse(json) }
+ x.report('OJ.load') { Oj.load(json) }
+ x.compare!
+end
diff --git a/exe/spandx b/exe/spandx
index 6ca8468..83c876e 100755
--- a/exe/spandx
+++ b/exe/spandx
@@ -4,7 +4,6 @@
require 'spandx'
Signal.trap('INT') do
- warn("\n#{caller.join("\n")}: interrupted")
exit(1)
end
diff --git a/lib/spandx.rb b/lib/spandx.rb
index b7a5bfa..78fbdcb 100644
--- a/lib/spandx.rb
+++ b/lib/spandx.rb
@@ -8,11 +8,11 @@ require 'json'
require 'logger'
require 'net/hippie'
require 'nokogiri'
+require 'oj'
require 'parslet'
require 'pathname'
require 'yaml'
require 'zeitwerk'
-require 'terminal-table'
require 'spandx/spandx'
loader = Zeitwerk::Loader.for_gem
diff --git a/lib/spandx/cli.rb b/lib/spandx/cli.rb
index 817ff89..e5a8d76 100644
--- a/lib/spandx/cli.rb
+++ b/lib/spandx/cli.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
-require 'nanospinner'
require 'thor'
-require 'tty-screen'
+require 'tty-spinner'
+require 'terminal-table'
module Spandx
module Cli
diff --git a/lib/spandx/cli/commands/scan.rb b/lib/spandx/cli/commands/scan.rb
index 9e874f3..22420fc 100644
--- a/lib/spandx/cli/commands/scan.rb
+++ b/lib/spandx/cli/commands/scan.rb
@@ -4,51 +4,49 @@ module Spandx
module Cli
module Commands
class Scan
- attr_reader :scan_path, :spinner
+ include Spandx::Core
+ attr_reader :scan_path
def initialize(scan_path, options)
@scan_path = ::Pathname.new(scan_path)
@options = options
- @spinner = options[:show_progress] ? ::Spandx::Core::Spinner.new : ::Spandx::Core::Spinner::NULL
require(options[:require]) if options[:require]
end
def execute(output: $stdout)
- report = ::Spandx::Core::Report.new
- each_file do |file|
- spinner.spin(file)
- each_dependency_from(file) do |dependency|
- spinner.spin(file)
- report.add(dependency)
+ with_printer(output) do |printer|
+ each_dependency do |dependency|
+ printer.print_line(Plugin.enhance(dependency), output)
end
end
- spinner.stop
- output.puts(format(report.to(@options[:format])))
end
private
def each_file
- Spandx::Core::PathTraversal
+ PathTraversal
.new(scan_path, recursive: @options[:recursive])
.each { |file| yield file }
end
- def each_dependency_from(file)
- ::Spandx::Core::Parser
- .parse(file)
- .map { |x| enhance(x) }
- .each { |dependency| yield dependency }
+ def each_dependency
+ each_file do |file|
+ Parser.parse(file).each do |dependency|
+ yield dependency
+ end
+ end
end
def format(output)
Array(output).map(&:to_s)
end
- def enhance(dependency)
- ::Spandx::Core::Plugin
- .all
- .inject(dependency) { |memo, plugin| plugin.enhance(memo) }
+ def with_printer(output)
+ printer = ::Spandx::Cli::Printer.for(@options[:format])
+ printer.print_header(output)
+ yield printer
+ ensure
+ printer.print_footer(output)
end
end
end
diff --git a/lib/spandx/cli/main.rb b/lib/spandx/cli/main.rb
index f22dd34..bb27f83 100644
--- a/lib/spandx/cli/main.rb
+++ b/lib/spandx/cli/main.rb
@@ -8,14 +8,14 @@ module Spandx
method_option :recursive, aliases: '-R', type: :boolean, desc: 'Perform recursive scan', default: false
method_option :airgap, aliases: '-a', type: :boolean, desc: 'Disable network connections', default: false
method_option :logfile, aliases: '-l', type: :string, desc: 'Path to a logfile', default: '/dev/null'
- method_option :format, aliases: '-f', type: :string, desc: 'Format of report. (table, csv, json, hash)', default: 'table'
+ method_option :format, aliases: '-f', type: :string, desc: 'Format of report. (table, csv, json)', default: 'table'
method_option :pull, aliases: '-p', type: :boolean, desc: 'Pull the latest cache before the scan', default: false
method_option :require, aliases: '-r', type: :string, desc: 'Causes spandx to load the library using require.', default: nil
- method_option :show_progress, aliases: '-sp', type: :boolean, desc: 'Shows a progress bar', default: true
def scan(lockfile = Pathname.pwd)
if options[:help]
invoke :help, ['scan']
else
+ Oj.default_options = { mode: :strict }
Spandx.airgap = options[:airgap]
Spandx.logger = Logger.new(options[:logfile])
pull if options[:pull]
diff --git a/lib/spandx/cli/printer.rb b/lib/spandx/cli/printer.rb
new file mode 100644
index 0000000..f21be93
--- /dev/null
+++ b/lib/spandx/cli/printer.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module Spandx
+ module Cli
+ class Printer
+ def match?(_format)
+ raise ::Spandx::Error, :match?
+ end
+
+ def print_header(io); end
+
+ def print_line(dependency, io)
+ io.puts(dependency.to_s)
+ end
+
+ def print_footer(io); end
+
+ class << self
+ include Core::Registerable
+
+ def for(format)
+ find { |x| x.match?(format) } || new
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spandx/cli/printers/csv.rb b/lib/spandx/cli/printers/csv.rb
new file mode 100644
index 0000000..ab73960
--- /dev/null
+++ b/lib/spandx/cli/printers/csv.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Spandx
+ module Cli
+ module Printers
+ class Csv < Printer
+ def match?(format)
+ format.to_sym == :csv
+ end
+
+ def print_line(dependency, io)
+ io.puts(CSV.generate_line(dependency.to_a))
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spandx/cli/printers/json.rb b/lib/spandx/cli/printers/json.rb
new file mode 100644
index 0000000..b796d89
--- /dev/null
+++ b/lib/spandx/cli/printers/json.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Spandx
+ module Cli
+ module Printers
+ class Json < Printer
+ def match?(format)
+ format.to_sym == :json
+ end
+
+ def print_line(dependency, io)
+ io.puts(Oj.dump(dependency.to_h))
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spandx/cli/printers/table.rb b/lib/spandx/cli/printers/table.rb
new file mode 100644
index 0000000..931b739
--- /dev/null
+++ b/lib/spandx/cli/printers/table.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Spandx
+ module Cli
+ module Printers
+ class Table < Printer
+ HEADINGS = ['Name', 'Version', 'Licenses', 'Location'].freeze
+
+ def initialize
+ @spinner = TTY::Spinner.new(output: $stderr)
+ end
+
+ def match?(format)
+ format.to_sym == :table
+ end
+
+ def print_header(_io)
+ @dependencies = SortedSet.new
+ @spinner.auto_spin
+ end
+
+ def print_line(dependency, _io)
+ @dependencies << dependency
+ end
+
+ def print_footer(io)
+ @spinner.stop
+ io.puts(to_table(@dependencies.map(&:to_a)))
+ end
+
+ private
+
+ def to_table(rows)
+ Terminal::Table.new(headings: HEADINGS) do |table|
+ rows.each { |row| table.add_row(row) }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spandx/core/git.rb b/lib/spandx/core/git.rb
index f98734d..25716ab 100644
--- a/lib/spandx/core/git.rb
+++ b/lib/spandx/core/git.rb
@@ -11,9 +11,8 @@ module Spandx
end
def read(path)
- full_path = File.join(root, path)
-
- IO.read(full_path) if File.exist?(full_path)
+ full_path = root.join(path)
+ full_path.read if full_path.exist?
end
def update!
@@ -25,15 +24,16 @@ module Spandx
def path_for(url)
uri = URI.parse(url)
name = uri.path.gsub(/\.git$/, '')
- File.expand_path(File.join(Dir.home, '.local', 'share', name))
+ Pathname(File.expand_path(File.join(Dir.home, '.local', 'share', name)))
end
def dotgit?
- File.directory?(File.join(root, '.git'))
+ root.join('.git').directory?
end
def clone!
- system('git', 'clone', '--quiet', '--depth=1', '--single-branch', '--branch', 'master', url, root)
+ system('rm', '-rf', root.to_s) if root.exist?
+ system('git', 'clone', '--quiet', '--depth=1', '--single-branch', '--branch', 'master', url, root.to_s)
end
def pull!
diff --git a/lib/spandx/core/plugin.rb b/lib/spandx/core/plugin.rb
index f4841cf..6564c60 100644
--- a/lib/spandx/core/plugin.rb
+++ b/lib/spandx/core/plugin.rb
@@ -9,6 +9,12 @@ module Spandx
class << self
include Registerable
+
+ def enhance(dependency)
+ Plugin.all.inject(dependency) do |memo, plugin|
+ plugin.enhance(memo)
+ end
+ end
end
end
end
diff --git a/lib/spandx/core/report.rb b/lib/spandx/core/report.rb
deleted file mode 100644
index dc57f6e..0000000
--- a/lib/spandx/core/report.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: true
-
-module Spandx
- module Core
- class Report
- attr_reader :dependencies
-
- FORMATS = {
- csv: :to_csv,
- hash: :to_h,
- json: :to_json,
- table: :to_table,
- }.freeze
-
- def initialize
- @dependencies = SortedSet.new
- end
-
- def add(dependency)
- @dependencies << dependency
- end
-
- def to(format, formats: FORMATS)
- public_send(formats.fetch(format&.to_sym, :to_json))
- end
-
- def to_table
- Terminal::Table.new(headings: ['Name', 'Version', 'Licenses', 'Location']) do |t|
- dependencies.each do |d|
- t.add_row d.to_a
- end
- end
- end
-
- def to_h
- { version: '1.0', dependencies: [] }.tap do |report|
- dependencies.each do |dependency|
- report[:dependencies].push(dependency.to_h)
- end
- end
- end
-
- def to_json(*_args)
- JSON.pretty_generate(to_h)
- end
-
- def to_csv
- dependencies.map do |dependency|
- CSV.generate_line(dependency.to_a)
- end
- end
- end
- end
-end
diff --git a/lib/spandx/core/spinner.rb b/lib/spandx/core/spinner.rb
deleted file mode 100644
index af3c7a7..0000000
--- a/lib/spandx/core/spinner.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module Spandx
- module Core
- class Spinner
- NULL = Class.new do
- def self.spin(*args); end
-
- def self.stop(*args); end
- end
-
- attr_reader :columns, :spinner
-
- def initialize(columns: TTY::Screen.columns, output: $stderr)
- @columns = columns
- @spinner = Nanospinner.new(output)
- @queue = Queue.new
- @thread = Thread.new { work }
- end
-
- def spin(message)
- @queue.enq(justify(message))
- yield if block_given?
- end
-
- def stop
- @queue.clear
- @queue.enq(:stop)
- @thread.join
- end
-
- private
-
- def justify(message)
- message.to_s.ljust(columns - 3)
- end
-
- def work
- last_message = justify('')
- loop do
- message = @queue.empty? ? last_message : @queue.deq
- break if message == :stop
-
- spinner.spin(message)
- last_message = message
- sleep 0.1
- end
- end
- end
- end
-end
diff --git a/lib/spandx/core/thread_pool.rb b/lib/spandx/core/thread_pool.rb
new file mode 100644
index 0000000..fdbced5
--- /dev/null
+++ b/lib/spandx/core/thread_pool.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Spandx
+ module Core
+ class ThreadPool
+ def initialize(size: 1)
+ @size = size
+ @queue = Queue.new
+ @pool = size.times.map { start_worker_thread(@queue) }
+ end
+
+ def run(*args, &job)
+ @queue.enq([job, args])
+ end
+
+ def done?
+ @queue.empty?
+ end
+
+ def shutdown
+ @size.times do
+ run { throw :exit }
+ end
+
+ @pool.map(&:join)
+ end
+
+ def self.open(**args)
+ pool = new(**args)
+ yield pool
+ ensure
+ pool.shutdown
+ end
+
+ private
+
+ def start_worker_thread(queue)
+ Thread.new(queue) do |q|
+ catch(:exit) do
+ loop do
+ job, args = q.deq
+ job.call(args)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/spandx/dotnet/nuget_gateway.rb b/lib/spandx/dotnet/nuget_gateway.rb
index 6776553..089d2bb 100644
--- a/lib/spandx/dotnet/nuget_gateway.rb
+++ b/lib/spandx/dotnet/nuget_gateway.rb
@@ -69,7 +69,7 @@ module Spandx
def fetch_json(url)
response = http.get(url)
- http.ok?(response) ? JSON.parse(response.body) : {}
+ http.ok?(response) ? Oj.load(response.body) : {}
end
def fetch_xml(url)
diff --git a/lib/spandx/js/parsers/npm.rb b/lib/spandx/js/parsers/npm.rb
index b92e1a2..2402454 100644
--- a/lib/spandx/js/parsers/npm.rb
+++ b/lib/spandx/js/parsers/npm.rb
@@ -18,8 +18,8 @@ module Spandx
private
- def each_metadata(file_path)
- package_lock = JSON.parse(IO.read(file_path))
+ def each_metadata(path)
+ package_lock = Oj.load(path.read)
package_lock['dependencies'].each do |name, metadata|
yield metadata.merge('name' => name)
end
diff --git a/lib/spandx/js/yarn_pkg.rb b/lib/spandx/js/yarn_pkg.rb
index 19a8dd3..bb479b4 100644
--- a/lib/spandx/js/yarn_pkg.rb
+++ b/lib/spandx/js/yarn_pkg.rb
@@ -27,7 +27,7 @@ module Spandx
response = http.get(uri, escape: false)
if http.ok?(response)
- json = JSON.parse(response.body)
+ json = Oj.load(response.body)
json['versions'] ? json['versions'][dependency.version] : json
else
{}
diff --git a/lib/spandx/php/packagist_gateway.rb b/lib/spandx/php/packagist_gateway.rb
index 88ec6d3..8580072 100644
--- a/lib/spandx/php/packagist_gateway.rb
+++ b/lib/spandx/php/packagist_gateway.rb
@@ -17,7 +17,7 @@ module Spandx
response = http.get("https://repo.packagist.org/p/#{dependency.name}.json")
return [] unless http.ok?(response)
- json = JSON.parse(response.body)
+ json = Oj.load(response.body)
json['packages'][dependency.name][dependency.version]['license']
end
end
diff --git a/lib/spandx/php/parsers/composer.rb b/lib/spandx/php/parsers/composer.rb
index 61c29a8..e1bb240 100644
--- a/lib/spandx/php/parsers/composer.rb
+++ b/lib/spandx/php/parsers/composer.rb
@@ -10,7 +10,7 @@ module Spandx
def parse(path)
items = Set.new
- composer_lock = JSON.parse(path.read)
+ composer_lock = Oj.load(path.read)
composer_lock['packages'].concat(composer_lock['packages-dev']).each do |dependency|
items.add(map_from(path, dependency))
end
diff --git a/lib/spandx/python/parsers/pipfile_lock.rb b/lib/spandx/python/parsers/pipfile_lock.rb
index 08b8644..e3ea58d 100644
--- a/lib/spandx/python/parsers/pipfile_lock.rb
+++ b/lib/spandx/python/parsers/pipfile_lock.rb
@@ -19,7 +19,7 @@ module Spandx
private
def dependencies_from(lockfile)
- json = JSON.parse(lockfile.read)
+ json = Oj.load(lockfile.read)
each_dependency(json) do |name, version|
yield ::Spandx::Core::Dependency.new(
path: lockfile,
diff --git a/lib/spandx/python/pypi.rb b/lib/spandx/python/pypi.rb
index 7849f29..ef3080a 100644
--- a/lib/spandx/python/pypi.rb
+++ b/lib/spandx/python/pypi.rb
@@ -49,19 +49,26 @@ module Spandx
end
def version_from(url)
- path = SUBSTITUTIONS.inject(URI.parse(url).path.split('/')[-1]) do |memo, item|
- memo.gsub(item, '')
- end
-
+ path = cleanup(url)
return if path.rindex('-').nil?
- path.scan(/-\d+\..*/)[-1][1..-1]
+ section = path.scan(/-\d+\..*/)
+ section = path.scan(/-\d+\.?.*/) if section.empty?
+ section[-1][1..-1]
+ rescue StandardError => error
+ warn([url, error].inspect)
end
private
attr_reader :http
+ def cleanup(url)
+ SUBSTITUTIONS.inject(URI.parse(url).path.split('/')[-1]) do |memo, item|
+ memo.gsub(item, '')
+ end
+ end
+
def sources_for(dependency)
return default_sources if dependency.meta.empty?
@@ -76,7 +83,7 @@ module Spandx
sources.each do |source|
html_from(source, '/simple/').css('a[href*="/simple"]').each do |node|
each_version(source, node[:href]) do |dependency|
- definition = source.lookup(dependency[:name], dependency[:version])
+ definition = source.lookup(dependency[:name], dependency[:version], http: http)
yield dependency.merge(license: definition['license'])
end
end
@@ -93,7 +100,12 @@ module Spandx
def html_from(source, path)
url = URI.join(source.uri.to_s, path).to_s
- Nokogiri::HTML(http.get(url).body)
+ response = http.get(url)
+ if http.ok?(response)
+ Nokogiri::HTML(response.body)
+ else
+ Nokogiri::HTML('<html><head></head><body></body></html>')
+ end
end
end
end
diff --git a/lib/spandx/python/source.rb b/lib/spandx/python/source.rb
index af0cbbb..2379c16 100644
--- a/lib/spandx/python/source.rb
+++ b/lib/spandx/python/source.rb
@@ -22,7 +22,7 @@ module Spandx
def lookup(name, version, http: Spandx.http)
response = http.get(uri_for(name, version))
if http.ok?(response)
- JSON.parse(response.body)
+ Oj.load(response.body)
else
{}
end
diff --git a/lib/spandx/ruby/gateway.rb b/lib/spandx/ruby/gateway.rb
index 54e8107..208eb9e 100644
--- a/lib/spandx/ruby/gateway.rb
+++ b/lib/spandx/ruby/gateway.rb
@@ -27,7 +27,7 @@ module Spandx
end
def parse(json)
- JSON.parse(json)
+ Oj.load(json)
end
end
end
diff --git a/spandx.gemspec b/spandx.gemspec
index 3f36023..100db55 100644
--- a/spandx.gemspec
+++ b/spandx.gemspec
@@ -34,13 +34,13 @@ Gem::Specification.new do |spec|
spec.add_dependency 'addressable', '~> 2.7'
spec.add_dependency 'bundler', '>= 1.16', '< 3.0.0'
- spec.add_dependency 'nanospinner', '~> 1.0.0'
spec.add_dependency 'net-hippie', '~> 0.3'
spec.add_dependency 'nokogiri', '~> 1.10'
+ spec.add_dependency 'oj', '~> 3.10'
spec.add_dependency 'parslet', '~> 2.0'
spec.add_dependency 'terminal-table', '~> 1.8'
spec.add_dependency 'thor'
- spec.add_dependency 'tty-screen', '~> 0.7'
+ spec.add_dependency 'tty-spinner', '~> 0.9'
spec.add_dependency 'zeitwerk', '~> 2.3'
spec.add_development_dependency 'benchmark-ips', '~> 2.8'
@@ -54,6 +54,6 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'rubocop', '~> 0.52'
spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
spec.add_development_dependency 'ruby-prof', '~> 1.3'
- spec.add_development_dependency 'vcr', '~> 5.0'
+ spec.add_development_dependency 'vcr', '~> 6.0'
spec.add_development_dependency 'webmock', '~> 3.7'
end
diff --git a/spec/fixtures/help-scan.expected b/spec/fixtures/help-scan.expected
index e9b1c5a..d1c7f56 100644
--- a/spec/fixtures/help-scan.expected
+++ b/spec/fixtures/help-scan.expected
@@ -2,16 +2,14 @@ Usage:
spandx scan LOCKFILE
Options:
- -h, [--help], [--no-help] # Display usage information
- -R, [--recursive], [--no-recursive] # Perform recursive scan
- -a, [--airgap], [--no-airgap] # Disable network connections
- -l, [--logfile=LOGFILE] # Path to a logfile
- # Default: /dev/null
- -f, [--format=FORMAT] # Format of report. (table, csv, json, hash)
- # Default: table
- -p, [--pull], [--no-pull] # Pull the latest cache before the scan
- -r, [--require=REQUIRE] # Causes spandx to load the library using require.
- -sp, [--show-progress], [--no-show-progress] # Shows a progress bar
- # Default: true
+ -h, [--help], [--no-help] # Display usage information
+ -R, [--recursive], [--no-recursive] # Perform recursive scan
+ -a, [--airgap], [--no-airgap] # Disable network connections
+ -l, [--logfile=LOGFILE] # Path to a logfile
+ # Default: /dev/null
+ -f, [--format=FORMAT] # Format of report. (table, csv, json)
+ # Default: table
+ -p, [--pull], [--no-pull] # Pull the latest cache before the scan
+ -r, [--require=REQUIRE] # Causes spandx to load the library using require.
Scan a lockfile and list dependencies/licenses
diff --git a/spec/integration/cli/scan_spec.rb b/spec/integration/cli/scan_spec.rb
index c92ea29..1a6b3f2 100644
--- a/spec/integration/cli/scan_spec.rb
+++ b/spec/integration/cli/scan_spec.rb
@@ -7,27 +7,27 @@ RSpec.describe '`spandx scan` command', type: :cli do
end
it 'executes `spandx scan Gemfile.lock`' do
- output = `spandx scan #{fixture_file('bundler/Gemfile.lock')} --no-show-progress`
+ output = `spandx scan #{fixture_file('bundler/Gemfile.lock')} 2> /dev/null`
expect(output).to eq(fixture_file_content('bundler/Gemfile.lock.expected'))
end
it 'executes `spandx scan gems.lock' do
- output = `spandx scan #{fixture_file('bundler/gems.lock')} --no-show-progress`
+ output = `spandx scan #{fixture_file('bundler/gems.lock')} 2> /dev/null`
expect(output).to eq(fixture_file_content('bundler/gems.lock.expected'))
end
it 'executes `spandx scan Pipfile.lock`' do
- output = `spandx scan #{fixture_file('pip/Pipfile.lock')} --no-show-progress`
+ output = `spandx scan #{fixture_file('pip/Pipfile.lock')} 2> /dev/null`
expect(output).to eq(fixture_file_content('pip/Pipfile.lock.expected'))
end
it 'executes `spandx scan yarnfile.lock`' do
- output = `spandx scan #{fixture_file('js/yarn.lock')} --no-show-progress`
+ output = `spandx scan #{fixture_file('js/yarn.lock')} 2> /dev/null`
expect(output).to eq(fixture_file_content('js/yarn.lock.expected'))
end
it 'executes `spandx scan composer.lock`' do
- output = `spandx scan #{fixture_file('composer/composer.lock')} --no-show-progress`
+ output = `spandx scan #{fixture_file('composer/composer.lock')} 2> /dev/null`
expect(output).to eq(fixture_file_content('composer/composer.lock.expected'))
end
end
diff --git a/spec/integration/core/git_spec.rb b/spec/integration/core/git_spec.rb
index 186c5b7..63bb4d8 100644
--- a/spec/integration/core/git_spec.rb
+++ b/spec/integration/core/git_spec.rb
@@ -17,15 +17,17 @@ RSpec.describe Spandx::Core::Git do
describe '#root' do
let(:expected_path) { File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'spdx', 'license-list-data')) }
- it { expect(subject.root).to eql(expected_path) }
+ it { expect(subject.root.to_s).to eql(expected_path) }
end
describe 'update!' do
let(:expected_path) { File.expand_path(File.join(ENV['HOME'], '.local', 'share', 'spdx', 'license-list-data')) }
context 'when the repository has not been cloned' do
+ let(:git_path) { instance_double(Pathname, directory?: false) }
+
before do
- allow(File).to receive(:directory?).with(File.join(expected_path, '.git')).and_return(false)
+ allow(subject.root).to receive(:join).with('.git').and_return(git_path)
subject.update!
end
@@ -34,9 +36,11 @@ RSpec.describe Spandx::Core::Git do
end
context 'when the repository has already been cloned' do
+ let(:git_path) { instance_double(Pathname, directory?: true) }
+
before do
- allow(File).to receive(:directory?).with(File.join(expected_path, '.git')).and_return(true)
- allow(Dir).to receive(:chdir).with(expected_path).and_yield
+ allow(subject.root).to receive(:join).with('.git').and_return(git_path)
+ allow(Dir).to receive(:chdir).with(Pathname(expected_path)).and_yield
subject.update!
end
diff --git a/spec/unit/cli/scan_spec.rb b/spec/unit/cli/scan_spec.rb
index 7e33e7f..a11842d 100644
--- a/spec/unit/cli/scan_spec.rb
+++ b/spec/unit/cli/scan_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Spandx::Cli::Commands::Scan do
let(:lockfile) { fixture_file(path) }
let(:output) { StringIO.new }
- let(:options) { { format: 'table', show_progress: false, recursive: true } }
+ let(:options) { { format: 'table', recursive: true } }
before do
stub_request(:get, Spandx::Spdx::Gateway::URL)
diff --git a/spec/unit/core/report_spec.rb b/spec/unit/core/report_spec.rb
deleted file mode 100644
index d543087..0000000
--- a/spec/unit/core/report_spec.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe Spandx::Core::Report do
- def build(name, version, path)
- Spandx::Core::Dependency.new(name: name, version: version, path: path)
- end
-
- describe '#dependencies' do
- before do
- subject.add(build('spandx', '0.1.0', Pathname('./Gemfile.lock')))
- subject.add(build('spandx', '0.1.0', Pathname('./Gemfile.lock')))
- end
-
- specify { expect(subject.dependencies.count).to be(1) }
- specify { expect(subject.dependencies.to_a).to eql([build('spandx', '0.1.0', Pathname('./Gemfile.lock'))]) }
- end
-end
diff --git a/spec/unit/python/pypi_spec.rb b/spec/unit/python/pypi_spec.rb
index cb09c4a..a0617bd 100644
--- a/spec/unit/python/pypi_spec.rb
+++ b/spec/unit/python/pypi_spec.rb
@@ -28,107 +28,108 @@ RSpec.describe Spandx::Python::Pypi do
describe '#version_from' do
[
- { url: 'https://files.pythonhosted.org/packages/8c/e6/83748ba1e232167de61f2bf31ec53f4b7acdd1ced52bdf3ea3366ea48132/0-0.0.0-py2.py3-none-any.whl#sha256=d8c8aeb13d410f713ea132d4268ef3dc1e113be6ec3ef2c31420df5c44e8e634', version: '0.0.0' },
- { url: 'https://files.pythonhosted.org/packages/ff/b9/6246538b88db7272f62d4eb0bd1afbb5ec402b24866be95059cc037d6970/00000a-0.0.2.tar.gz#sha256=3c1a3cdcc6cd2ca9a8dd44009509039dfa84928a4293069a74d5fc5c39e4b7a1', version: '0.0.2' },
- { url: 'https://files.pythonhosted.org/packages/a3/b4/61ad204de90c962698982b0e4aac34d4db9737041396b2c6c6860276cdf0/0.0.1-0.0.1.tar.gz#sha256=b5ebdc3ae6be725b4e8c4959790022b431e183b275dfa673a7521c2acf851d40', version: '0.0.1' },
- { url: 'https://files.pythonhosted.org/packages/79/29/f31b78d51b59eafae5b7a876e5d18870c597ca8913436f0ab4b16bc3b9fa/007-0.0.1.tar.gz#sha256=570f9b3c06b04d1e53cc9304e2a3b127731e31e7c8636df5a02aba664e618a88', version: '0.0.1' },
- { url: 'https://files.pythonhosted.org/packages/fd/49/c01735a9c8d028f22356f8e3086b412530a2f288b072945e0c079ef29bd6/007-0.0.2.tar.gz#sha256=a5f7fe73035bcd3944ac30843a595dc47a0e5d20110d70c9998f0396d104ee6c', version: '0.0.2' },
- { url: 'https://files.pythonhosted.org/packages/28/77/b367493f392d23b5e91220a92ec87aa94ca0ef4ee82b7baacc13ca48c585/00print_lol-1.0.0.tar.gz#sha256=03a146dc09b0076f2e82d39563a5b8ba93c64536609d9806be7b5b3ea87a4162', version: '1.0.0' },
- { url: 'https://files.pythonhosted.org/packages/c6/ab/4a317ae0d0c7c911f1c77719c553fc46a12d981899ceb5d47220fc3d535c/00print_lol-1.1.0.tar.gz#sha256=c452b0cc78f3a5edecbc6d160d2fa14c012d78403b0206558bcf1444eb5d1e2e', version: '1.1.0' },
- { url: 'https://files.pythonhosted.org/packages/99/b1/8329b44e81c794ebe8772531fbb94df3afb107102d183c1b0a17abb49471/0121-0.0.1.tar.gz#sha256=c340f511c652c50e67fac4e85528064f4253f5850446c9258949574a5d541f92', version: '0.0.1' },
- { url: 'https://files.pythonhosted.org/packages/95/47/2444989f005f7f3f892fc2bd375946072c23325becde4a5e2bae729579f3/01d61084-d29e-11e9-96d1-7c5cf84ffe8e-0.1.0.tar.gz#sha256=8b97d404c652de7ebc481b4ccc22c5d837d2e1d0938efcb2ce47a4220784247a', version: '0.1.0' },
- { url: 'https://files.pythonhosted.org/packages/ac/78/83c3d46cdcf616bf64b60cc35bbcc2dc9504811516e07527a4ab3af6e0c7/01d61084_d29e_11e9_96d1_7c5cf84ffe8e-0.1.0-py3-none-any.whl#sha256=258f18753542f8bb6715fdfe5691313443c92fc80b2050e36eebac81a42ec3b4', version: '0.1.0' },
- { url: 'https://files.pythonhosted.org/packages/b0/e9/0bf97f93c7fe78b0983c5d375d670bebcdb3526e6f2e60c4c7e733021c27/021-1.0.tar.gz#sha256=6ff3159b4fe981c0702437a0c3004940c623ea6cdf4efd9ac74dac094e622160', version: '1.0' },
- { url: 'https://files.pythonhosted.org/packages/b0/81/b2cb9d8fdcffdbe1988009b7fef8ec0a29cf07c8016e66a02dd9941cfe62/02exercicio-1.0.0.tar.gz#sha256=71a5ffda2437ca70bb90069155fba43bfd8694eab65d9a7875286fd955cbe02d', version: '1.0.0' },
- { url: 'https://files.pythonhosted.org/packages/ec/65/c0116953c9a3f47de89e71964d6c7b0c783b01f29fa3390584dbf3046b4d/0805nexter-1.1.0.zip#sha256=52cd128ad3afe539478abc7440d4b043384295fbe6b0958a237cb6d926465035', version: '1.1.0' },
- { url: 'https://files.pythonhosted.org/packages/c4/a0/4562cda161dc4ecbbe9e2a11eb365400c0461845c5be70d73869786809c4/0805nexter-1.2.0.zip#sha256=49785c6ae39ea511b3c253d7621c0b1b6228be2f965aca8a491e6b84126d0709', version: '1.2.0' },
- { url: 'https://files.pythonhosted.org/packages/65/3a/33138bb0c82a08a50a427a067a26310b7d6c17b0fec5e286c5d72a4f7f98/090807040506030201testpip-0.1dev.tar.gz#sha256=e32ccda7c353012cfdbf038a2e38014813442c9fbff4fade4df1901ecd2fbe17', version: '0.1dev' },
- { url: 'https://files.pythonhosted.org/packages/d3/cb/91061d33b8991125641585251a5251ac054d3bc7606cd80a0968995430c7/0-core-client-1.1.0a3.tar.gz#sha256=d47d162505074abfaed298d5463ab40e804438c59bc1d5f165b03d257c1de0ff', version: '1.1.0a3' },
- { url: 'https://files.pythonhosted.org/packages/c3/82/c0ef77f86571d9d6bdc697424cfdc3b04f6a8db6a1497b851a0f4a862401/0_core_client-1.1.0a3-py3-none-any.whl#sha256=092c89c05104a59d11ac2604c5af10cb0106bbbb521b42844dee13dd2c80606b', version: '1.1.0a3' },
- { url: 'https://files.pythonhosted.org/packages/9b/16/0160f8c9dfafb8d59e0b2eac3b0264660e8cef16e4f7dcd2da34f4073f2d/0-core-client-1.1.0a4.tar.gz#sha256=601b69c5c93d4990399ddacd79d1a81e9af3570a44a3a55bb7edff315b7c084d', version: '1.1.0a4' },
+ { url: 'https://files.pythonhosted.org/packages/01/d4/b73510e90eaace314156d4ffeddcdc32925e0ea93924c2f29266d55df475/0lever_utils-0.1.5-py3-none-any.whl#sha256=930cf8cf0edd37eb60fb0ca3760a23e5ad3c52a1295d01b73e489f2d3d0df511', version: '0.1.5' },
+ { url: 'https://files.pythonhosted.org/packages/06/83/ed65c68212f5f145063ba6e3df8e8a58f724564db0f33224f3e4b567f78f/0-orchestrator-1.1.0a8.tar.gz#sha256=bf89940a3d3f3d1b8fac912cbc9b173f7ca0aa2aee623fa206771f230d0467dd', version: '1.1.0a8' },
+ { url: 'https://files.pythonhosted.org/packages/08/13/1bce760f7456e598f7156d4488a29a65419b8cf72b1004de3db459c25ba8/0lever_utils-0.1.6-py2-none-any.whl#sha256=bcdd895c07615e93dd261db391807871e3ff9898ee6ada10c5ea88a55bf04264', version: '0.1.6' },
+ { url: 'https://files.pythonhosted.org/packages/0c/a7/0bb4c480f4111c80400139261abef84fa8e178b03baf0e2ae21410b4ddac/0lever_so-1.0.8-py3-none-any.whl#sha256=4b36e040be49fe7ddc7ed9a5620d35525f4eebaef9113b787d8ac77c8b2a6b27', version: '1.0.8' },
+ { url: 'https://files.pythonhosted.org/packages/0c/b5/20dbb950ab388c9d7b3e5099d8956d5098a8acb02497a010b5cc21d34c0a/0lever_utils-0.1.5-py2-none-any.whl#sha256=6d12dae3ee2608fa071ca5caf76f1c2bf18519e49c4afbffdef611847b8b6aba', version: '0.1.5' },
+ { url: 'https://files.pythonhosted.org/packages/0d/9f/a24c516016770a80bb33dffd852762fe8e61a5127d94b4bdb290003a6b6a/0x01-letsencrypt-0.1.tar.gz#sha256=3b6786a2f24382ea7b42bbc543c2fce70c4fe4c0de49a24c1098cb41e271526e', version: '0.1' },
+ { url: 'https://files.pythonhosted.org/packages/0d/ce/6e7c14ebc167f31a8bb9d0b48116359794c902a60c29e0c8d197b13e8bdd/0_orchestrator-1.1.0a7.post1-py3-none-any.whl#sha256=72f076dec0cbe098ebc085fa083b30e2671a310d8186620f1c52e73c220ab81f', version: '1.1.0a7.post1' },
+ { url: 'https://files.pythonhosted.org/packages/0e/e7/2bc27a48170fc7d4f458fda9d9ff973f1780bf1b0fa2fd71de89124d7014/0x_contract_addresses-2.1.0-py3-none-any.whl#sha256=dd78dd0429bac1ff88e1d1bf5422f9f17d7738e1fa49da97755056792d9f5945', version: '2.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/14/19/93882065e97fe8d30b246ad47365b4a18c63846b1c8b5f294c4abcedba49/0-orchestrator-1.1.0a3.tar.gz#sha256=d9248bc9b55f645b6045f6bb4846ae0df0f7193e39633295d9967ba68665d177', version: '1.1.0a3' },
{ url: 'https://files.pythonhosted.org/packages/15/cf/129954b87fcb2a093a16c2f926bbd7600d97676df577c56fc88c955322b6/0-core-client-1.1.0a5.tar.gz#sha256=4f7c6ea029298a0343d05c1a7a136930ea78f15ecfdb9004265b758486c3a0ca', version: '1.1.0a5' },
- { url: 'https://files.pythonhosted.org/packages/28/af/8f35eed98331dd634761917747b278b5705bea44d394784bd83c6074f869/0_core_client-1.1.0a5-py3-none-any.whl#sha256=1f58f5251752a21f9e2d52239ba61b160f7c38dfac45d5206fc41b877a6e3194', version: '1.1.0a5' },
- { url: 'https://files.pythonhosted.org/packages/f5/90/897a16f3cd9044fe18a238ecaa9c421f8b54531bd7ef34e7ec405c5a319a/0-core-client-1.1.0a7.tar.gz#sha256=2f45465e53f57b6f7570aa959d27f6ab5ea32ee395e210df8de23f1335b3bcc8', version: '1.1.0a7' },
+ { url: 'https://files.pythonhosted.org/packages/19/91/69bcda2d03734913a26469f21868d32621c624aaa82762908e2febe98ca8/0lever_utils-0.0.3-py3-none-any.whl#sha256=db0849f8f05c04ae3f4745d00355c61280b627ffc520b7cc8aa904e4fd17e097', version: '0.0.3' },
+ { url: 'https://files.pythonhosted.org/packages/1d/34/ba1fa03f9db5cd5267167fd6093bc478e92a3699ca1d2fc16f6950af89c5/0lever_utils-0.0.3-py2-none-any.whl#sha256=fb4684d2026ff6bc26df92c8cf6332fe9593e55b27a6c306a3aeda5fe07179d5', version: '0.0.3' },
+ { url: 'https://files.pythonhosted.org/packages/1f/c8/32dd25d1e72229a37548eba24a873c63a368714382fc6bf18a041dd212b1/0lever_utils-0.1.0-py3-none-any.whl#sha256=3a4f2eadad572878b04b2f8fc9d6bcb31550bb742b95bed0d9c568d9cc7ae5f1', version: '0.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/21/53/f43b2f754284fe76436e06aac50c42ad984587dcfcb3e35c0999158223d5/0_orchestrator-1.1.0a8-py3-none-any.whl#sha256=5460255971955f78265894404032a33a14d3a6c93c1099d5c130b520e96d2cd9', version: '1.1.0a8' },
+ { url: 'https://files.pythonhosted.org/packages/23/b0/55c18ecf8e093fb0c08024ad7d2559d4023639259692d9dd01e5ffcd30e3/0x_contract_addresses-2.0.0-py3-none-any.whl#sha256=f285f96d401eb13f572343dc4f658689b745642a66e0767ecea94e0d3be629ac', version: '2.0.0' },
{ url: 'https://files.pythonhosted.org/packages/25/3e/d455e956af418f0632326604d19253b6d0558809ed582afffaed72200b0a/0_core_client-1.1.0a7-py3-none-any.whl#sha256=c81dfe9de503d0dc9770bf27f6177d8bf31626830b290ed5afbc0b3579f8fd2e', version: '1.1.0a7' },
- { url: 'https://files.pythonhosted.org/packages/cd/1c/52c3a1c88b2a2821ea7d2afc3c7883a8d73880dd4de4199b8d5e7d9773bd/0-core-client-1.1.0a8.tar.gz#sha256=663508e24643ad3a261b8b317e34ad6f096d2bae8997fb9155629e941b78986b', version: '1.1.0a8' },
- { url: 'https://files.pythonhosted.org/packages/66/fa/acc0e598ef7bc9af8dc67b76776fff86e163b702742c3a842d1ae7956203/0_core_client-1.1.0a8-py3-none-any.whl#sha256=3a5566dcb6d8c971c4ec74b3910b1d5b25b5e18ce6263161a1b7f9d41f3188e4', version: '1.1.0a8' },
- { url: 'https://files.pythonhosted.org/packages/78/62/2d4e6938f108aad2cf13a5b4900e371a041446402cbe8167e1900f6d1716/0lever_so-1.0.8-py2-none-any.whl#sha256=9151d51d191a66d5808269245afb8fa0c09313996d382eb320d64c53f079acb8', version: '1.0.8' },
- { url: 'https://files.pythonhosted.org/packages/0c/a7/0bb4c480f4111c80400139261abef84fa8e178b03baf0e2ae21410b4ddac/0lever_so-1.0.8-py3-none-any.whl#sha256=4b36e040be49fe7ddc7ed9a5620d35525f4eebaef9113b787d8ac77c8b2a6b27', version: '1.0.8' },
- { url: 'https://files.pythonhosted.org/packages/fd/ee/207c1511984df8cb7bb44b2de96c72b954618fe697c187eb4ef6fae1c7ad/0lever_so-1.0.9-py2-none-any.whl#sha256=abd147124d326cceb24b42eb88586ddbfbff7ff69a82380282a855a1ac30eca4', version: '1.0.9' },
- { url: 'https://files.pythonhosted.org/packages/70/ec/625463a29987be8d2c8d8d00951e66d975afb9b673b4da023f5362964096/0lever_so-1.0.9-py3-none-any.whl#sha256=f56846a01fb8e826e82a0a8e0d0ae5feec8da3f56f2f5e2069e340b25d49945a', version: '1.0.9' },
+ { url: 'https://files.pythonhosted.org/packages/27/ee/23aee13ec331d77b4f7e4a14546ff0030a88c5f90c1ec5b1e4ed5545d426/0lever_so-1.1.2-py3-none-any.whl#sha256=43c51847b0a8b690203bf8658616e5b10cbf127865199f5def73f967708ef2cf', version: '1.1.2' },
+ { url: 'https://files.pythonhosted.org/packages/28/77/b367493f392d23b5e91220a92ec87aa94ca0ef4ee82b7baacc13ca48c585/00print_lol-1.0.0.tar.gz#sha256=03a146dc09b0076f2e82d39563a5b8ba93c64536609d9806be7b5b3ea87a4162', version: '1.0.0' },
+ { url: 'https://files.pythonhosted.org/packages/28/af/8f35eed98331dd634761917747b278b5705bea44d394784bd83c6074f869/0_core_client-1.1.0a5-py3-none-any.whl#sha256=1f58f5251752a21f9e2d52239ba61b160f7c38dfac45d5206fc41b877a6e3194', version: '1.1.0a5' },
+ { url: 'https://files.pythonhosted.org/packages/2e/f3/e9e87d7d80bda76d4dacfcea880274c3bbd8f8c195b02348ecf07ee0179c/0lever_utils-0.0.2-py2-none-any.whl#sha256=1e91f3df348f5d1775d2f258503daf62d92fdfdf7f2678a50c775b64350eab4d', version: '0.0.2' },
+ { url: 'https://files.pythonhosted.org/packages/31/94/3f5aead5e720ab41e7a6d6ecd247bb5f72f4ad0706d3b622c967474ddc64/0x-contract-addresses-2.0.0.tar.gz#sha256=5df5c618005262df882094d72af31c7a390ce21e8f9d235d008ccf2a311a8125', version: '2.0.0' },
+ { url: 'https://files.pythonhosted.org/packages/33/c0/d82e190c0b6284b1d0bdd8493f11edf3a80ed601b92c44dacc0dd4b43648/0wdg9nbmpm-0.1.tar.gz#sha256=7130b1f19df69c3dc91b99fa3b31ebae873ef93b3d601285dbd3b3f97271d625', version: '0.1' },
+ { url: 'https://files.pythonhosted.org/packages/34/fc/f4a8a1569c906c325d0b41d5b3ac6d115bb1fa860ec46362cf61cf649495/0x-0.1.tar.gz#sha256=4d3f4ad49c37166c79d33f8c58c92558d0f044336248f70296661a046a9b5f1b', version: '0.1' },
{ url: 'https://files.pythonhosted.org/packages/39/04/27b147c0d0ce31e0163d6adc6e52f64733a393ec35407d502a8e84e377fe/0lever_so-1.1.0-py2-none-any.whl#sha256=202c1db424ac7ef180a442f37c7336d99678f1481de2f443614c558b03b5ed18', version: '1.1.0' },
- { url: 'https://files.pythonhosted.org/packages/eb/fe/3832155e33dc6ff60586a6552f21eaf3214fff816ac2cae5deffae730ef2/0lever_so-1.1.0-py3-none-any.whl#sha256=06851a36f3853530971b6c21b3db38360d72f6493738ad74351ce9fbaa97e8d6', version: '1.1.0' },
- { url: 'https://files.pythonhosted.org/packages/d1/bb/1f526e72697d8ccd77c7f513ba7d1b23e45642a0ed2bb2dd49f875310c13/0lever_so-1.1.1-py2-none-any.whl#sha256=ca2347e28940daf1cd780f767a4b4bc86ba2f1ac79194552221b98cc8425d25a', version: '1.1.1' },
- { url: 'https://files.pythonhosted.org/packages/c9/3d/947b2c7b6b18b94c524384463ba255db77e36756c800406f453eac69e5f4/0lever_so-1.1.1-py3-none-any.whl#sha256=2386ed3c8da48edf47bb884bc15d6b72666e2e9232d1b3b003852371aa4fe622', version: '1.1.1' },
+ { url: 'https://files.pythonhosted.org/packages/39/8f/a57ca099de0406ea8567adb18ba8545bb2bdeda2073028ee74b658f841be/0lever_utils-0.0.1-py2-none-any.whl#sha256=377b2adb6e59373dfbfabdfbb90babf35d2cf761ec02e122994c20291f879691', version: '0.0.1' },
+ { url: 'https://files.pythonhosted.org/packages/47/52/d189b2c6d2954effaf12960b8916b9d62fb8150083a42ef9b5e62462ac32/0x-contract-addresses-2.1.0.tar.gz#sha256=d1df84b35d9a35b73c1054c090942e31ff152526249d8d251c7b2fc684e045ab', version: '2.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/48/fa/2bfa40b043c9539b12aed4ff6fee834c8bbdeacf3e8388842d2fef0d1b84/0x-contract-addresses-3.0.0.tar.gz#sha256=677f7390d6505b85647af3dfa4765c307a26344d94716d263993c1f7efbf88d8', version: '3.0.0' },
+ { url: 'https://files.pythonhosted.org/packages/4b/ab/1df6cee9478914fc9119e9f7fe0463d4a57e63149aa70c496cce48457c07/0x_contract_artifacts-2.0.0-py3-none-any.whl#sha256=44146561e762958fcae64b0202da3416b78a3780f0265a4b57f7e3b6af26b120', version: '2.0.0' },
+ { url: 'https://files.pythonhosted.org/packages/4b/f7/90b5cf54de20704b5e09247594ed656e7511b8dea12ae6fea177ede9c700/0x_contract_addresses-3.0.0.dev1-py3-none-any.whl#sha256=1d045c6733b727a965470933e4184494636d3ab07675681c3e65ccef80eb721d', version: '3.0.0.dev1' },
{ url: 'https://files.pythonhosted.org/packages/50/71/49ed67c436959dbf2d9acd36369932d8e5383a407cd1cb40b333707744b7/0lever_so-1.1.2-py2-none-any.whl#sha256=a5a0afbb41a24674259390bcdbf92a6bcd69314aa299de693fa97aa3f62b4fab', version: '1.1.2' },
- { url: 'https://files.pythonhosted.org/packages/27/ee/23aee13ec331d77b4f7e4a14546ff0030a88c5f90c1ec5b1e4ed5545d426/0lever_so-1.1.2-py3-none-any.whl#sha256=43c51847b0a8b690203bf8658616e5b10cbf127865199f5def73f967708ef2cf', version: '1.1.2' },
+ { url: 'https://files.pythonhosted.org/packages/56/79/2f81c26461433b3036cd34d396325c38ade3a9aa64e6636540b67bc084d4/0x-contract-artifacts-2.0.0.tar.gz#sha256=7c1a0b4204cf08f46efad2b1a19d19e2d6189e1bea9e220e41caa0f145159316', version: '2.0.0' },
+ { url: 'https://files.pythonhosted.org/packages/5c/c8/9d580a308885959eb79107c7286995fe30c2b1065a04a28b9e7746788718/0lever_utils-0.0.7-py2-none-any.whl#sha256=91a8683614eedb2b3e8877fb6690965f39ed6feb3aa27e5ea9bed949b36503be', version: '0.0.7' },
+ { url: 'https://files.pythonhosted.org/packages/5d/be/460cab4688fa1025c65ecba1f3d56264faa0319ee3ad6e38475f8125aca1/0x_contract_addresses-3.0.0.dev3-py3-none-any.whl#sha256=63f47a7735e5bdf089a2d87c469540b58ce82f10bae4ae076fac25a5f5e9f02c', version: '3.0.0.dev3' },
+ { url: 'https://files.pythonhosted.org/packages/5f/6e/0954156529b22e5b1193d7413a8cdc6ad88ec1a552238956dc2e93c043a8/0lever_utils-0.1.2-py2-none-any.whl#sha256=ae47664c69e2379882a8ef7058267aace7970bd1f9c45c24bc7500aaaaa25fa3', version: '0.1.2' },
+ { url: 'https://files.pythonhosted.org/packages/61/cf/40bdc4ca91d23e7cc77e01e9084fdd62f38832e908175e04453863b60c8c/aangifte-3.tar.gz#sha256=009c5da775e74f0c8f22a5f15b031de7f7fc6f86c197c4844a1776e1d680c3e7', version: '3' },
+ { url: 'https://files.pythonhosted.org/packages/65/3a/33138bb0c82a08a50a427a067a26310b7d6c17b0fec5e286c5d72a4f7f98/090807040506030201testpip-0.1dev.tar.gz#sha256=e32ccda7c353012cfdbf038a2e38014813442c9fbff4fade4df1901ecd2fbe17', version: '0.1dev' },
+ { url: 'https://files.pythonhosted.org/packages/66/fa/acc0e598ef7bc9af8dc67b76776fff86e163b702742c3a842d1ae7956203/0_core_client-1.1.0a8-py3-none-any.whl#sha256=3a5566dcb6d8c971c4ec74b3910b1d5b25b5e18ce6263161a1b7f9d41f3188e4', version: '1.1.0a8' },
+ { url: 'https://files.pythonhosted.org/packages/68/8b/bbed7b15b68637bb66fa28047b082fb5383f6ddb61ef8a723b3e46e5c4dd/0_orchestrator-1.1.0a3-py3-none-any.whl#sha256=237e32c255663a74cfc9b4f20cf69949ba10cfa52e5d3099194ad2ad35201b4c', version: '1.1.0a3' },
+ { url: 'https://files.pythonhosted.org/packages/6a/c6/cedc13f810e7561247df40ba8ead02831ebf7eee2a12537c4f507e33ace1/0lever_utils-0.1.1-py2-none-any.whl#sha256=47dda1e5c1dee794bcc1ba4d5fefd6bca99cf26c11613243af77a19e40443341', version: '0.1.1' },
+ { url: 'https://files.pythonhosted.org/packages/70/0f/f8459388d19c9cca20d86e6453afca76567fff7405feea80de0f8e003efc/0lever_utils-0.0.6-py3-none-any.whl#sha256=29206dab46a7405ac455b6b39b7501b37c3be6728051bf35b1487c27c943fb3b', version: '0.0.6' },
+ { url: 'https://files.pythonhosted.org/packages/70/ec/625463a29987be8d2c8d8d00951e66d975afb9b673b4da023f5362964096/0lever_so-1.0.9-py3-none-any.whl#sha256=f56846a01fb8e826e82a0a8e0d0ae5feec8da3f56f2f5e2069e340b25d49945a', version: '1.0.9' },
+ { url: 'https://files.pythonhosted.org/packages/74/77/2a5ccb2440d54b7a87e5716206c973ea329232c3a74f06860ad2fa979a67/0x-contract-addresses-3.0.0.dev2.tar.gz#sha256=6759639fcbcfc577a727145dbfa08faf5115d5729858cdb1e508510ed0dfdc87', version: '3.0.0.dev2' },
+ { url: 'https://files.pythonhosted.org/packages/76/f7/c6971f37fe7890d8747f8e7de1c2613a75c154d3f05aca0f88fe7d0c0ff9/0x-contract-addresses-3.0.0.dev3.tar.gz#sha256=31fa7d3598fd9667a9d747287cc3c531e0f0fb5999e198903b6f681edbd8f270', version: '3.0.0.dev3' },
{ url: 'https://files.pythonhosted.org/packages/78/21/a60c322d212bdf67b0fceabd48873040a1908b6ff56ac6047ac0f61dd502/0lever_so-1.1.3-py2-none-any.whl#sha256=475e9dc19597e247b510d62bf9e11a564a03678129095ae92c97c3ff4e1ba932', version: '1.1.3' },
- { url: 'https://files.pythonhosted.org/packages/ec/75/e1d501829ca2ceb2c678fff9ff37182da5c860d16d0702f4d82a8acf7f31/0lever_so-1.2.0-py2-none-any.whl#sha256=45fd5de96b0d8a3e83e160835f72f6233ca657fa627f0c87b61cc15f6f0f845a', version: '1.2.0' },
- { url: 'https://files.pythonhosted.org/packages/39/8f/a57ca099de0406ea8567adb18ba8545bb2bdeda2073028ee74b658f841be/0lever_utils-0.0.1-py2-none-any.whl#sha256=377b2adb6e59373dfbfabdfbb90babf35d2cf761ec02e122994c20291f879691', version: '0.0.1' },
- { url: 'https://files.pythonhosted.org/packages/2e/f3/e9e87d7d80bda76d4dacfcea880274c3bbd8f8c195b02348ecf07ee0179c/0lever_utils-0.0.2-py2-none-any.whl#sha256=1e91f3df348f5d1775d2f258503daf62d92fdfdf7f2678a50c775b64350eab4d', version: '0.0.2' },
- { url: 'https://files.pythonhosted.org/packages/f0/ae/24eb23ed53ea412ec6bbf4a3f38d53773eb0bf05a46f9aa05975abb01c02/0lever_utils-0.0.2-py3-none-any.whl#sha256=49dda99e024f5af08dde0a6602ee2725fdc6e0c8eaeebbb87582c334d19a4f7c', version: '0.0.2' },
- { url: 'https://files.pythonhosted.org/packages/1d/34/ba1fa03f9db5cd5267167fd6093bc478e92a3699ca1d2fc16f6950af89c5/0lever_utils-0.0.3-py2-none-any.whl#sha256=fb4684d2026ff6bc26df92c8cf6332fe9593e55b27a6c306a3aeda5fe07179d5', version: '0.0.3' },
- { url: 'https://files.pythonhosted.org/packages/19/91/69bcda2d03734913a26469f21868d32621c624aaa82762908e2febe98ca8/0lever_utils-0.0.3-py3-none-any.whl#sha256=db0849f8f05c04ae3f4745d00355c61280b627ffc520b7cc8aa904e4fd17e097', version: '0.0.3' },
- { url: 'https://files.pythonhosted.org/packages/ea/92/b711c82299975869648a8f79bce2b28c4120e2c6088482b896110d0c0397/0lever_utils-0.0.4-py2-none-any.whl#sha256=6042aff9fc2c31eda24a004dc1b70fcaea2eb9d5901ad90327e10b924e190cf0', version: '0.0.4' },
- { url: 'https://files.pythonhosted.org/packages/f5/32/6cc29ecda3cf752556247a39bcf34d440e236f817f458ff354e1f1d0521b/0lever_utils-0.0.4-py3-none-any.whl#sha256=ff1160a666afddb87892d3c50869bddb01f6e05c35ab62825414c86fe433acec', version: '0.0.4' },
- { url: 'https://files.pythonhosted.org/packages/fa/2a/ddb55bee3ebf13139eafa0a4dc5ba151561d318138508c5282f33578f74a/0lever_utils-0.0.5-py2-none-any.whl#sha256=5516c223f26b8dd3655619976a472e653bc1679cc1db02f506a7b17c138bd649', version: '0.0.5' },
- { url: 'https://files.pythonhosted.org/packages/c4/89/09009be8d127201e3541435ac84ff57c4e3cd2213f8ae7d97f0f32cea31c/0lever_utils-0.0.5-py3-none-any.whl#sha256=4eac2c9963216b58792e5a2f5fd5e37755d82c0dd6ba1454313d92790a61fbb7', version: '0.0.5' },
+ { url: 'https://files.pythonhosted.org/packages/78/62/2d4e6938f108aad2cf13a5b4900e371a041446402cbe8167e1900f6d1716/0lever_so-1.0.8-py2-none-any.whl#sha256=9151d51d191a66d5808269245afb8fa0c09313996d382eb320d64c53f079acb8', version: '1.0.8' },
+ { url: 'https://files.pythonhosted.org/packages/79/29/f31b78d51b59eafae5b7a876e5d18870c597ca8913436f0ab4b16bc3b9fa/007-0.0.1.tar.gz#sha256=570f9b3c06b04d1e53cc9304e2a3b127731e31e7c8636df5a02aba664e618a88', version: '0.0.1' },
{ url: 'https://files.pythonhosted.org/packages/80/f5/61a6a5f709ca20158fed62b8b8755b8765e3320860f6368487dda143a772/0lever_utils-0.0.6-py2-none-any.whl#sha256=edcfc3a5243feb2c7db3d8a19dbc629d89c583784f21edd5410be3e65ddc2e06', version: '0.0.6' },
- { url: 'https://files.pythonhosted.org/packages/70/0f/f8459388d19c9cca20d86e6453afca76567fff7405feea80de0f8e003efc/0lever_utils-0.0.6-py3-none-any.whl#sha256=29206dab46a7405ac455b6b39b7501b37c3be6728051bf35b1487c27c943fb3b', version: '0.0.6' },
- { url: 'https://files.pythonhosted.org/packages/5c/c8/9d580a308885959eb79107c7286995fe30c2b1065a04a28b9e7746788718/0lever_utils-0.0.7-py2-none-any.whl#sha256=91a8683614eedb2b3e8877fb6690965f39ed6feb3aa27e5ea9bed949b36503be', version: '0.0.7' },
+ { url: 'https://files.pythonhosted.org/packages/82/bb/a0c60cf1a52fdaabfee3172412137ffc11fe3d4f54be7d4b9c608d5f8b20/0-orchestrator-1.1.0a5.tar.gz#sha256=21edefac10907b2ce36f07c20b01c1abc1944ab0e32989c81ad853b9f3a8f99c', version: '1.1.0a5' },
+ { url: 'https://files.pythonhosted.org/packages/84/f5/53e108fd0c64063620fac17858f359973e236c71b35729997287540aee1d/0x-contract-addresses-3.0.0.dev1.tar.gz#sha256=eed2f645e3f7990fd286ef73888b301d3413ca2efaada7e791bcd7100a58b9c2', version: '3.0.0.dev1' },
+ { url: 'https://files.pythonhosted.org/packages/8c/e6/83748ba1e232167de61f2bf31ec53f4b7acdd1ced52bdf3ea3366ea48132/0-0.0.0-py2.py3-none-any.whl#sha256=d8c8aeb13d410f713ea132d4268ef3dc1e113be6ec3ef2c31420df5c44e8e634', version: '0.0.0' },
{ url: 'https://files.pythonhosted.org/packages/94/65/133d48c0af2b1b7b55e5a15a5a787020d35df1046425e26b971bd35d7d52/0lever_utils-0.0.7-py3-none-any.whl#sha256=aef746f3855927e09e4090cfd16abc7d75230d2ea53c751699db073e64687ad5', version: '0.0.7' },
- { url: 'https://files.pythonhosted.org/packages/c4/9d/db08970b39a542c5f30f08aa35352174456881c60f80ec9f4b1770a5789e/0lever_utils-0.1.0-py2-none-any.whl#sha256=5a03ca33e6d9bad4ed42a6667d3d5c5fc3efef099a37ef750d34e5e5da6c49fb', version: '0.1.0' },
- { url: 'https://files.pythonhosted.org/packages/1f/c8/32dd25d1e72229a37548eba24a873c63a368714382fc6bf18a041dd212b1/0lever_utils-0.1.0-py3-none-any.whl#sha256=3a4f2eadad572878b04b2f8fc9d6bcb31550bb742b95bed0d9c568d9cc7ae5f1', version: '0.1.0' },
- { url: 'https://files.pythonhosted.org/packages/6a/c6/cedc13f810e7561247df40ba8ead02831ebf7eee2a12537c4f507e33ace1/0lever_utils-0.1.1-py2-none-any.whl#sha256=47dda1e5c1dee794bcc1ba4d5fefd6bca99cf26c11613243af77a19e40443341', version: '0.1.1' },
- { url: 'https://files.pythonhosted.org/packages/5f/6e/0954156529b22e5b1193d7413a8cdc6ad88ec1a552238956dc2e93c043a8/0lever_utils-0.1.2-py2-none-any.whl#sha256=ae47664c69e2379882a8ef7058267aace7970bd1f9c45c24bc7500aaaaa25fa3', version: '0.1.2' },
+ { url: 'https://files.pythonhosted.org/packages/94/68/acdf5c33b26f88186bd3f40d912d7388a8b6a10437f33ec85c49deb3b550/0x-contract-artifacts-3.0.0.dev0.tar.gz#sha256=fd9a55411968b844a3a81bcae1167682f31dd304adbbc6f720d1c7b43aaf6acd', version: '3.0.0.dev0' },
+ { url: 'https://files.pythonhosted.org/packages/95/47/2444989f005f7f3f892fc2bd375946072c23325becde4a5e2bae729579f3/01d61084-d29e-11e9-96d1-7c5cf84ffe8e-0.1.0.tar.gz#sha256=8b97d404c652de7ebc481b4ccc22c5d837d2e1d0938efcb2ce47a4220784247a', version: '0.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/99/b1/8329b44e81c794ebe8772531fbb94df3afb107102d183c1b0a17abb49471/0121-0.0.1.tar.gz#sha256=c340f511c652c50e67fac4e85528064f4253f5850446c9258949574a5d541f92', version: '0.0.1' },
+ { url: 'https://files.pythonhosted.org/packages/9b/16/0160f8c9dfafb8d59e0b2eac3b0264660e8cef16e4f7dcd2da34f4073f2d/0-core-client-1.1.0a4.tar.gz#sha256=601b69c5c93d4990399ddacd79d1a81e9af3570a44a3a55bb7edff315b7c084d', version: '1.1.0a4' },
{ url: 'https://files.pythonhosted.org/packages/a0/01/63afd94765200387f5e377697b64c2ae150c7bbf97579602c0e6b5723000/0lever_utils-0.1.3-py2-none-any.whl#sha256=64b20e6ccc6bf993e4ad5b217199c88c489cf2530cee3c70333b56fce057dccf', version: '0.1.3' },
- { url: 'https://files.pythonhosted.org/packages/fe/a6/3189d263fed5988920a18c090e9f182cc32a8ded0e8df3ac86956cf41ed2/0lever_utils-0.1.4-py2-none-any.whl#sha256=8174bb227226c068ebf6fd5e845ae4193502a6488cf2ac01a9482d579161e9c8', version: '0.1.4' },
- { url: 'https://files.pythonhosted.org/packages/0c/b5/20dbb950ab388c9d7b3e5099d8956d5098a8acb02497a010b5cc21d34c0a/0lever_utils-0.1.5-py2-none-any.whl#sha256=6d12dae3ee2608fa071ca5caf76f1c2bf18519e49c4afbffdef611847b8b6aba', version: '0.1.5' },
- { url: 'https://files.pythonhosted.org/packages/01/d4/b73510e90eaace314156d4ffeddcdc32925e0ea93924c2f29266d55df475/0lever_utils-0.1.5-py3-none-any.whl#sha256=930cf8cf0edd37eb60fb0ca3760a23e5ad3c52a1295d01b73e489f2d3d0df511', version: '0.1.5' },
- { url: 'https://files.pythonhosted.org/packages/08/13/1bce760f7456e598f7156d4488a29a65419b8cf72b1004de3db459c25ba8/0lever_utils-0.1.6-py2-none-any.whl#sha256=bcdd895c07615e93dd261db391807871e3ff9898ee6ada10c5ea88a55bf04264', version: '0.1.6' },
- { url: 'https://files.pythonhosted.org/packages/f8/f3/ae0893b39b5074047ca858a4f945339effdeeed3b9cb307548af2c900492/0lever_utils-0.1.6-py3-none-any.whl#sha256=e0b63d97eacaa571f4da3ce55846b09935060b1bf60bc60d5ea1bf9c336ea766', version: '0.1.6' },
- { url: 'https://files.pythonhosted.org/packages/de/0a/742998c97b906aee0a0d4878d20c5090141fd8110f72d83d52f4c1941f67/0-orchestrator-1.1.0a0.tar.gz#sha256=bef128cef7e57e648ef6a651379793b1a63df90b4da9ffc995dd688e62ddb6d7', version: '1.1.0a0' },
- { url: 'https://files.pythonhosted.org/packages/e6/e2/813b1755dccc504d2494e924ca3253a612674379d987be606581fb297289/0_orchestrator-1.1.0a0-py3-none-any.whl#sha256=a1ba77c79f65e71fe92fe1050fe89b4fe88b9faaa3c16fe324f5da4c7e2d14e9', version: '1.1.0a0' },
- { url: 'https://files.pythonhosted.org/packages/14/19/93882065e97fe8d30b246ad47365b4a18c63846b1c8b5f294c4abcedba49/0-orchestrator-1.1.0a3.tar.gz#sha256=d9248bc9b55f645b6045f6bb4846ae0df0f7193e39633295d9967ba68665d177', version: '1.1.0a3' },
- { url: 'https://files.pythonhosted.org/packages/68/8b/bbed7b15b68637bb66fa28047b082fb5383f6ddb61ef8a723b3e46e5c4dd/0_orchestrator-1.1.0a3-py3-none-any.whl#sha256=237e32c255663a74cfc9b4f20cf69949ba10cfa52e5d3099194ad2ad35201b4c', version: '1.1.0a3' },
- { url: 'https://files.pythonhosted.org/packages/f7/c2/89c3dd8686fd4e69871e11f69f87971dd090b769450c39a6d0f002a0fcb9/0-orchestrator-1.1.0a4.tar.gz#sha256=36e8fd4b8ccd29d4f144134a5624b835749ab6d15fc85e6db5c46a7082b5303f', version: '1.1.0a4' },
+ { url: 'https://files.pythonhosted.org/packages/a3/b4/61ad204de90c962698982b0e4aac34d4db9737041396b2c6c6860276cdf0/0.0.1-0.0.1.tar.gz#sha256=b5ebdc3ae6be725b4e8c4959790022b431e183b275dfa673a7521c2acf851d40', version: '0.0.1' },
{ url: 'https://files.pythonhosted.org/packages/aa/2d/a4193ef2473ec3b370e1f09beb57f161a24f7ca0fe96258f33759dda33b6/0_orchestrator-1.1.0a4-py3-none-any.whl#sha256=f3a74112dd8a2a0622c77b276ad59d483f62b6bdfce8697f1d6e0b2524860bfe', version: '1.1.0a4' },
- { url: 'https://files.pythonhosted.org/packages/82/bb/a0c60cf1a52fdaabfee3172412137ffc11fe3d4f54be7d4b9c608d5f8b20/0-orchestrator-1.1.0a5.tar.gz#sha256=21edefac10907b2ce36f07c20b01c1abc1944ab0e32989c81ad853b9f3a8f99c', version: '1.1.0a5' },
- { url: 'https://files.pythonhosted.org/packages/d4/75/06331e14b61541ac67afecb713ce6d0e3be5b52a513887c4cc74ef8bb568/0_orchestrator-1.1.0a5-py3-none-any.whl#sha256=581ee83684cb57ba5c55a0b7d3a8aa24f0ccca087b7e205d5c0ca22b47fea303', version: '1.1.0a5' },
- { url: 'https://files.pythonhosted.org/packages/f7/92/d10e965ef66b41fdad63a44899a7cb6084eaff81eb35de275ee48f10b9d5/0-orchestrator-1.1.0a7.tar.gz#sha256=2cfc80c8589f2f622db351c2aaf49136d3125318304463e9a127ad68902b9262', version: '1.1.0a7' },
- { url: 'https://files.pythonhosted.org/packages/eb/ae/8c0ce308eaed5419cc1e5b097e635c2f0d19fe94a71310e325413a58671a/0_orchestrator-1.1.0a7-py3-none-any.whl#sha256=b09acf91c50222fc64664095684c5945a8a3f9ed275739d713d4b01c8ae43746', version: '1.1.0a7' },
+ { url: 'https://files.pythonhosted.org/packages/ab/c1/3962bef93118a862cb38f3fc3b1f9e6d3acfb8e1fff64879d2c54463b258/0x-contract-addresses-3.0.0.dev0.tar.gz#sha256=5a9a21d2c76ff6a10cbb9573d239a487e8e4cb90620d6e6806f72f6e6bf6a12a', version: '3.0.0.dev0' },
+ { url: 'https://files.pythonhosted.org/packages/ac/78/83c3d46cdcf616bf64b60cc35bbcc2dc9504811516e07527a4ab3af6e0c7/01d61084_d29e_11e9_96d1_7c5cf84ffe8e-0.1.0-py3-none-any.whl#sha256=258f18753542f8bb6715fdfe5691313443c92fc80b2050e36eebac81a42ec3b4', version: '0.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/b0/81/b2cb9d8fdcffdbe1988009b7fef8ec0a29cf07c8016e66a02dd9941cfe62/02exercicio-1.0.0.tar.gz#sha256=71a5ffda2437ca70bb90069155fba43bfd8694eab65d9a7875286fd955cbe02d', version: '1.0.0' },
+ { url: 'https://files.pythonhosted.org/packages/b0/e9/0bf97f93c7fe78b0983c5d375d670bebcdb3526e6f2e60c4c7e733021c27/021-1.0.tar.gz#sha256=6ff3159b4fe981c0702437a0c3004940c623ea6cdf4efd9ac74dac094e622160', version: '1.0' },
+ { url: 'https://files.pythonhosted.org/packages/b9/24/6526bbe0e479f4272887998feb7e801f10d37a3e325fd129da448f795211/0x10c-asm-0.0.1.tar.gz#sha256=6d4c95c53b4c989d9a26d16b21d643bff1c40c9e1b213d6a800616d04eee0d18', version: '0.0.1' },
+ { url: 'https://files.pythonhosted.org/packages/ba/a1/568bdbb82f1ae8a283f147c31deca9cea2e9cc7d47e4227681d71c55dda4/0x_contract_addresses-3.0.0-py3-none-any.whl#sha256=7ca9f02bfc9fb1ea7368f929dd9f90bef2baaa996642de45ab2304f7c914bec0', version: '3.0.0' },
+ { url: 'https://files.pythonhosted.org/packages/c3/72/441451eb853fca52c8630b3d0cd6c555e135621ae07810fd688ee9d05b2b/0x-contract-addresses-2.0.1.tar.gz#sha256=df8280ebf1abaa0e62ea8872c1ca93b7329b117df930ab32be478405712b4630', version: '2.0.1' },
+ { url: 'https://files.pythonhosted.org/packages/c3/82/c0ef77f86571d9d6bdc697424cfdc3b04f6a8db6a1497b851a0f4a862401/0_core_client-1.1.0a3-py3-none-any.whl#sha256=092c89c05104a59d11ac2604c5af10cb0106bbbb521b42844dee13dd2c80606b', version: '1.1.0a3' },
+ { url: 'https://files.pythonhosted.org/packages/c4/89/09009be8d127201e3541435ac84ff57c4e3cd2213f8ae7d97f0f32cea31c/0lever_utils-0.0.5-py3-none-any.whl#sha256=4eac2c9963216b58792e5a2f5fd5e37755d82c0dd6ba1454313d92790a61fbb7', version: '0.0.5' },
+ { url: 'https://files.pythonhosted.org/packages/c4/9d/db08970b39a542c5f30f08aa35352174456881c60f80ec9f4b1770a5789e/0lever_utils-0.1.0-py2-none-any.whl#sha256=5a03ca33e6d9bad4ed42a6667d3d5c5fc3efef099a37ef750d34e5e5da6c49fb', version: '0.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/c4/a0/4562cda161dc4ecbbe9e2a11eb365400c0461845c5be70d73869786809c4/0805nexter-1.2.0.zip#sha256=49785c6ae39ea511b3c253d7621c0b1b6228be2f965aca8a491e6b84126d0709', version: '1.2.0' },
+ { url: 'https://files.pythonhosted.org/packages/c6/ab/4a317ae0d0c7c911f1c77719c553fc46a12d981899ceb5d47220fc3d535c/00print_lol-1.1.0.tar.gz#sha256=c452b0cc78f3a5edecbc6d160d2fa14c012d78403b0206558bcf1444eb5d1e2e', version: '1.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/c9/3d/947b2c7b6b18b94c524384463ba255db77e36756c800406f453eac69e5f4/0lever_so-1.1.1-py3-none-any.whl#sha256=2386ed3c8da48edf47bb884bc15d6b72666e2e9232d1b3b003852371aa4fe622', version: '1.1.1' },
+ { url: 'https://files.pythonhosted.org/packages/cd/1c/52c3a1c88b2a2821ea7d2afc3c7883a8d73880dd4de4199b8d5e7d9773bd/0-core-client-1.1.0a8.tar.gz#sha256=663508e24643ad3a261b8b317e34ad6f096d2bae8997fb9155629e941b78986b', version: '1.1.0a8' },
+ { url: 'https://files.pythonhosted.org/packages/d1/bb/1f526e72697d8ccd77c7f513ba7d1b23e45642a0ed2bb2dd49f875310c13/0lever_so-1.1.1-py2-none-any.whl#sha256=ca2347e28940daf1cd780f767a4b4bc86ba2f1ac79194552221b98cc8425d25a', version: '1.1.1' },
{ url: 'https://files.pythonhosted.org/packages/d2/5b/92b1be5d9ff54b2409b4f77d85e90f2e3bf6488d040f6f3269de0ed3aa0e/0-orchestrator-1.1.0-alpha-7-1.tar.gz#sha256=7789ed84a06a08f072ed92dfba91e46c2aab6616df80afdbdb570c017ea4852f', version: '1.1.0-alpha-7-1' },
- { url: 'https://files.pythonhosted.org/packages/0d/ce/6e7c14ebc167f31a8bb9d0b48116359794c902a60c29e0c8d197b13e8bdd/0_orchestrator-1.1.0a7.post1-py3-none-any.whl#sha256=72f076dec0cbe098ebc085fa083b30e2671a310d8186620f1c52e73c220ab81f', version: '1.1.0a7.post1' },
- { url: 'https://files.pythonhosted.org/packages/06/83/ed65c68212f5f145063ba6e3df8e8a58f724564db0f33224f3e4b567f78f/0-orchestrator-1.1.0a8.tar.gz#sha256=bf89940a3d3f3d1b8fac912cbc9b173f7ca0aa2aee623fa206771f230d0467dd', version: '1.1.0a8' },
- { url: 'https://files.pythonhosted.org/packages/21/53/f43b2f754284fe76436e06aac50c42ad984587dcfcb3e35c0999158223d5/0_orchestrator-1.1.0a8-py3-none-any.whl#sha256=5460255971955f78265894404032a33a14d3a6c93c1099d5c130b520e96d2cd9', version: '1.1.0a8' },
- { url: 'https://files.pythonhosted.org/packages/33/c0/d82e190c0b6284b1d0bdd8493f11edf3a80ed601b92c44dacc0dd4b43648/0wdg9nbmpm-0.1.tar.gz#sha256=7130b1f19df69c3dc91b99fa3b31ebae873ef93b3d601285dbd3b3f97271d625', version: '0.1' },
- { url: 'https://files.pythonhosted.org/packages/34/fc/f4a8a1569c906c325d0b41d5b3ac6d115bb1fa860ec46362cf61cf649495/0x-0.1.tar.gz#sha256=4d3f4ad49c37166c79d33f8c58c92558d0f044336248f70296661a046a9b5f1b', version: '0.1' },
+ { url: 'https://files.pythonhosted.org/packages/d2/5b/92b1be5d9ff54b2409b4f77d85e90f2e3bf6488d040f6f3269de0ed3aa0e/0-orchestrator-1.1.0-alpha-7-1.tar.gz#sha256=7789ed84a06a08f072ed92dfba91e46c2aab6616df80afdbdb570c017ea4852f', version: '1.1.0-alpha-7-1' },
+ { url: 'https://files.pythonhosted.org/packages/d3/cb/91061d33b8991125641585251a5251ac054d3bc7606cd80a0968995430c7/0-core-client-1.1.0a3.tar.gz#sha256=d47d162505074abfaed298d5463ab40e804438c59bc1d5f165b03d257c1de0ff', version: '1.1.0a3' },
+ { url: 'https://files.pythonhosted.org/packages/d4/75/06331e14b61541ac67afecb713ce6d0e3be5b52a513887c4cc74ef8bb568/0_orchestrator-1.1.0a5-py3-none-any.whl#sha256=581ee83684cb57ba5c55a0b7d3a8aa24f0ccca087b7e205d5c0ca22b47fea303', version: '1.1.0a5' },
+ { url: 'https://files.pythonhosted.org/packages/d9/f0/151d0f3bb569e3496ff6edbe8705ce077ac765aea80f8922f16c5d8376c4/0x_contract_addresses-3.0.0.dev2-py3-none-any.whl#sha256=001df466ee9c04c2379357f361c6ac55ec155dcf0da2e89c91a4d58b1fce481d', version: '3.0.0.dev2' },
+ { url: 'https://files.pythonhosted.org/packages/de/0a/742998c97b906aee0a0d4878d20c5090141fd8110f72d83d52f4c1941f67/0-orchestrator-1.1.0a0.tar.gz#sha256=bef128cef7e57e648ef6a651379793b1a63df90b4da9ffc995dd688e62ddb6d7', version: '1.1.0a0' },
{ url: 'https://files.pythonhosted.org/packages/df/4a/170d68a650f57aea9bda4a814642301504f750385891f56ed0d9d2c46cc7/0x01-autocert-dns-aliyun-0.1.tar.gz#sha256=f3ceaa3f0b8c3ffe10705b890f2a96dabc64e2923debbaa4908eb939efd49499', version: '0.1' },
- { url: 'https://files.pythonhosted.org/packages/0d/9f/a24c516016770a80bb33dffd852762fe8e61a5127d94b4bdb290003a6b6a/0x01-letsencrypt-0.1.tar.gz#sha256=3b6786a2f24382ea7b42bbc543c2fce70c4fe4c0de49a24c1098cb41e271526e', version: '0.1' },
- { url: 'https://files.pythonhosted.org/packages/b9/24/6526bbe0e479f4272887998feb7e801f10d37a3e325fd129da448f795211/0x10c-asm-0.0.1.tar.gz#sha256=6d4c95c53b4c989d9a26d16b21d643bff1c40c9e1b213d6a800616d04eee0d18', version: '0.0.1' },
{ url: 'https://files.pythonhosted.org/packages/e1/3a/6588c9c52a06e64a903314bc810ca712c3fc6c27b86779c057e23e7512b6/0x10c-asm-0.0.2.tar.gz#sha256=e4703f8bd0a44c473469ce6b57d4dde3c7acbf7e6c2df75d83570ae94fb08d6f', version: '0.0.2' },
- { url: 'https://files.pythonhosted.org/packages/31/94/3f5aead5e720ab41e7a6d6ecd247bb5f72f4ad0706d3b622c967474ddc64/0x-contract-addresses-2.0.0.tar.gz#sha256=5df5c618005262df882094d72af31c7a390ce21e8f9d235d008ccf2a311a8125', version: '2.0.0' },
- { url: 'https://files.pythonhosted.org/packages/23/b0/55c18ecf8e093fb0c08024ad7d2559d4023639259692d9dd01e5ffcd30e3/0x_contract_addresses-2.0.0-py3-none-any.whl#sha256=f285f96d401eb13f572343dc4f658689b745642a66e0767ecea94e0d3be629ac', version: '2.0.0' },
- { url: 'https://files.pythonhosted.org/packages/c3/72/441451eb853fca52c8630b3d0cd6c555e135621ae07810fd688ee9d05b2b/0x-contract-addresses-2.0.1.tar.gz#sha256=df8280ebf1abaa0e62ea8872c1ca93b7329b117df930ab32be478405712b4630', version: '2.0.1' },
- { url: 'https://files.pythonhosted.org/packages/fe/ec/0c4b906147bfdb09ede4deff7489ea33267daf14f6d8c9706ed1b1ac3597/0x_contract_addresses-2.0.1-py3-none-any.whl#sha256=0514f73c92694bbeee2704374fcd2f0eefbe8bbdfc43dd95dc0ab6c262d4c058', version: '2.0.1' },
- { url: 'https://files.pythonhosted.org/packages/47/52/d189b2c6d2954effaf12960b8916b9d62fb8150083a42ef9b5e62462ac32/0x-contract-addresses-2.1.0.tar.gz#sha256=d1df84b35d9a35b73c1054c090942e31ff152526249d8d251c7b2fc684e045ab', version: '2.1.0' },
- { url: 'https://files.pythonhosted.org/packages/0e/e7/2bc27a48170fc7d4f458fda9d9ff973f1780bf1b0fa2fd71de89124d7014/0x_contract_addresses-2.1.0-py3-none-any.whl#sha256=dd78dd0429bac1ff88e1d1bf5422f9f17d7738e1fa49da97755056792d9f5945', version: '2.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/e6/e2/813b1755dccc504d2494e924ca3253a612674379d987be606581fb297289/0_orchestrator-1.1.0a0-py3-none-any.whl#sha256=a1ba77c79f65e71fe92fe1050fe89b4fe88b9faaa3c16fe324f5da4c7e2d14e9', version: '1.1.0a0' },
+ { url: 'https://files.pythonhosted.org/packages/ea/92/b711c82299975869648a8f79bce2b28c4120e2c6088482b896110d0c0397/0lever_utils-0.0.4-py2-none-any.whl#sha256=6042aff9fc2c31eda24a004dc1b70fcaea2eb9d5901ad90327e10b924e190cf0', version: '0.0.4' },
+ { url: 'https://files.pythonhosted.org/packages/eb/ae/8c0ce308eaed5419cc1e5b097e635c2f0d19fe94a71310e325413a58671a/0_orchestrator-1.1.0a7-py3-none-any.whl#sha256=b09acf91c50222fc64664095684c5945a8a3f9ed275739d713d4b01c8ae43746', version: '1.1.0a7' },
+ { url: 'https://files.pythonhosted.org/packages/eb/fe/3832155e33dc6ff60586a6552f21eaf3214fff816ac2cae5deffae730ef2/0lever_so-1.1.0-py3-none-any.whl#sha256=06851a36f3853530971b6c21b3db38360d72f6493738ad74351ce9fbaa97e8d6', version: '1.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/ec/65/c0116953c9a3f47de89e71964d6c7b0c783b01f29fa3390584dbf3046b4d/0805nexter-1.1.0.zip#sha256=52cd128ad3afe539478abc7440d4b043384295fbe6b0958a237cb6d926465035', version: '1.1.0' },
+ { url: 'https://files.pythonhosted.org/packages/ec/75/e1d501829ca2ceb2c678fff9ff37182da5c860d16d0702f4d82a8acf7f31/0lever_so-1.2.0-py2-none-any.whl#sha256=45fd5de96b0d8a3e83e160835f72f6233ca657fa627f0c87b61cc15f6f0f845a', version: '1.2.0' },
{ url: 'https://files.pythonhosted.org/packages/ed/e2/23a769ee1845baa615fcfa20f540844b95193111c8c9317f3840ecf764de/0x-contract-addresses-2.2.0.tar.gz#sha256=b9cc6fc7210e8c2e0bb3154d0cdd65fa747145ceb3a388a0146a781b029f6617', version: '2.2.0' },
+ { url: 'https://files.pythonhosted.org/packages/f0/ae/24eb23ed53ea412ec6bbf4a3f38d53773eb0bf05a46f9aa05975abb01c02/0lever_utils-0.0.2-py3-none-any.whl#sha256=49dda99e024f5af08dde0a6602ee2725fdc6e0c8eaeebbb87582c334d19a4f7c', version: '0.0.2' },
+ { url: 'https://files.pythonhosted.org/packages/f5/32/6cc29ecda3cf752556247a39bcf34d440e236f817f458ff354e1f1d0521b/0lever_utils-0.0.4-py3-none-any.whl#sha256=ff1160a666afddb87892d3c50869bddb01f6e05c35ab62825414c86fe433acec', version: '0.0.4' },
+ { url: 'https://files.pythonhosted.org/packages/f5/90/897a16f3cd9044fe18a238ecaa9c421f8b54531bd7ef34e7ec405c5a319a/0-core-client-1.1.0a7.tar.gz#sha256=2f45465e53f57b6f7570aa959d27f6ab5ea32ee395e210df8de23f1335b3bcc8', version: '1.1.0a7' },
+ { url: 'https://files.pythonhosted.org/packages/f7/92/d10e965ef66b41fdad63a44899a7cb6084eaff81eb35de275ee48f10b9d5/0-orchestrator-1.1.0a7.tar.gz#sha256=2cfc80c8589f2f622db351c2aaf49136d3125318304463e9a127ad68902b9262', version: '1.1.0a7' },
+ { url: 'https://files.pythonhosted.org/packages/f7/c2/89c3dd8686fd4e69871e11f69f87971dd090b769450c39a6d0f002a0fcb9/0-orchestrator-1.1.0a4.tar.gz#sha256=36e8fd4b8ccd29d4f144134a5624b835749ab6d15fc85e6db5c46a7082b5303f', version: '1.1.0a4' },
+ { url: 'https://files.pythonhosted.org/packages/f8/f3/ae0893b39b5074047ca858a4f945339effdeeed3b9cb307548af2c900492/0lever_utils-0.1.6-py3-none-any.whl#sha256=e0b63d97eacaa571f4da3ce55846b09935060b1bf60bc60d5ea1bf9c336ea766', version: '0.1.6' },
+ { url: 'https://files.pythonhosted.org/packages/fa/2a/ddb55bee3ebf13139eafa0a4dc5ba151561d318138508c5282f33578f74a/0lever_utils-0.0.5-py2-none-any.whl#sha256=5516c223f26b8dd3655619976a472e653bc1679cc1db02f506a7b17c138bd649', version: '0.0.5' },
{ url: 'https://files.pythonhosted.org/packages/fa/f5/7a29cb2377058c738d29bb9232168fdea17d94801fbace3e90054e2139de/0x_contract_addresses-2.2.0-py3-none-any.whl#sha256=4cc518ee16bd06cc8bfc531fd54b3da905dc17ac59b66d52b66e27ccbdb151cc', version: '2.2.0' },
- { url: 'https://files.pythonhosted.org/packages/ab/c1/3962bef93118a862cb38f3fc3b1f9e6d3acfb8e1fff64879d2c54463b258/0x-contract-addresses-3.0.0.dev0.tar.gz#sha256=5a9a21d2c76ff6a10cbb9573d239a487e8e4cb90620d6e6806f72f6e6bf6a12a', version: '3.0.0.dev0' },
+ { url: 'https://files.pythonhosted.org/packages/fd/49/c01735a9c8d028f22356f8e3086b412530a2f288b072945e0c079ef29bd6/007-0.0.2.tar.gz#sha256=a5f7fe73035bcd3944ac30843a595dc47a0e5d20110d70c9998f0396d104ee6c', version: '0.0.2' },
{ url: 'https://files.pythonhosted.org/packages/fd/51/a7a8468a4bc226a4e96fda87acfb36bde1582b04c4435d4fb56dce2cd0d6/0x_contract_addresses-3.0.0.dev0-py3-none-any.whl#sha256=cbe05e7827fe3e6b44e237fccbed3803bf881f4bfaf195043d2b472606dbd148', version: '3.0.0.dev0' },
- { url: 'https://files.pythonhosted.org/packages/84/f5/53e108fd0c64063620fac17858f359973e236c71b35729997287540aee1d/0x-contract-addresses-3.0.0.dev1.tar.gz#sha256=eed2f645e3f7990fd286ef73888b301d3413ca2efaada7e791bcd7100a58b9c2', version: '3.0.0.dev1' },
- { url: 'https://files.pythonhosted.org/packages/4b/f7/90b5cf54de20704b5e09247594ed656e7511b8dea12ae6fea177ede9c700/0x_contract_addresses-3.0.0.dev1-py3-none-any.whl#sha256=1d045c6733b727a965470933e4184494636d3ab07675681c3e65ccef80eb721d', version: '3.0.0.dev1' },
- { url: 'https://files.pythonhosted.org/packages/74/77/2a5ccb2440d54b7a87e5716206c973ea329232c3a74f06860ad2fa979a67/0x-contract-addresses-3.0.0.dev2.tar.gz#sha256=6759639fcbcfc577a727145dbfa08faf5115d5729858cdb1e508510ed0dfdc87', version: '3.0.0.dev2' },
- { url: 'https://files.pythonhosted.org/packages/d9/f0/151d0f3bb569e3496ff6edbe8705ce077ac765aea80f8922f16c5d8376c4/0x_contract_addresses-3.0.0.dev2-py3-none-any.whl#sha256=001df466ee9c04c2379357f361c6ac55ec155dcf0da2e89c91a4d58b1fce481d', version: '3.0.0.dev2' },
- { url: 'https://files.pythonhosted.org/packages/76/f7/c6971f37fe7890d8747f8e7de1c2613a75c154d3f05aca0f88fe7d0c0ff9/0x-contract-addresses-3.0.0.dev3.tar.gz#sha256=31fa7d3598fd9667a9d747287cc3c531e0f0fb5999e198903b6f681edbd8f270', version: '3.0.0.dev3' },
- { url: 'https://files.pythonhosted.org/packages/5d/be/460cab4688fa1025c65ecba1f3d56264faa0319ee3ad6e38475f8125aca1/0x_contract_addresses-3.0.0.dev3-py3-none-any.whl#sha256=63f47a7735e5bdf089a2d87c469540b58ce82f10bae4ae076fac25a5f5e9f02c', version: '3.0.0.dev3' },
- { url: 'https://files.pythonhosted.org/packages/48/fa/2bfa40b043c9539b12aed4ff6fee834c8bbdeacf3e8388842d2fef0d1b84/0x-contract-addresses-3.0.0.tar.gz#sha256=677f7390d6505b85647af3dfa4765c307a26344d94716d263993c1f7efbf88d8', version: '3.0.0' },
- { url: 'https://files.pythonhosted.org/packages/ba/a1/568bdbb82f1ae8a283f147c31deca9cea2e9cc7d47e4227681d71c55dda4/0x_contract_addresses-3.0.0-py3-none-any.whl#sha256=7ca9f02bfc9fb1ea7368f929dd9f90bef2baaa996642de45ab2304f7c914bec0', version: '3.0.0' },
- { url: 'https://files.pythonhosted.org/packages/56/79/2f81c26461433b3036cd34d396325c38ade3a9aa64e6636540b67bc084d4/0x-contract-artifacts-2.0.0.tar.gz#sha256=7c1a0b4204cf08f46efad2b1a19d19e2d6189e1bea9e220e41caa0f145159316', version: '2.0.0' },
- { url: 'https://files.pythonhosted.org/packages/4b/ab/1df6cee9478914fc9119e9f7fe0463d4a57e63149aa70c496cce48457c07/0x_contract_artifacts-2.0.0-py3-none-any.whl#sha256=44146561e762958fcae64b0202da3416b78a3780f0265a4b57f7e3b6af26b120', version: '2.0.0' },
- { url: 'https://files.pythonhosted.org/packages/94/68/acdf5c33b26f88186bd3f40d912d7388a8b6a10437f33ec85c49deb3b550/0x-contract-artifacts-3.0.0.dev0.tar.gz#sha256=fd9a55411968b844a3a81bcae1167682f31dd304adbbc6f720d1c7b43aaf6acd', version: '3.0.0.dev0' },
- { url: 'https://files.pythonhosted.org/packages/d2/5b/92b1be5d9ff54b2409b4f77d85e90f2e3bf6488d040f6f3269de0ed3aa0e/0-orchestrator-1.1.0-alpha-7-1.tar.gz#sha256=7789ed84a06a08f072ed92dfba91e46c2aab6616df80afdbdb570c017ea4852f', version: '1.1.0-alpha-7-1' },
+ { url: 'https://files.pythonhosted.org/packages/fd/ee/207c1511984df8cb7bb44b2de96c72b954618fe697c187eb4ef6fae1c7ad/0lever_so-1.0.9-py2-none-any.whl#sha256=abd147124d326cceb24b42eb88586ddbfbff7ff69a82380282a855a1ac30eca4', version: '1.0.9' },
+ { url: 'https://files.pythonhosted.org/packages/fe/a6/3189d263fed5988920a18c090e9f182cc32a8ded0e8df3ac86956cf41ed2/0lever_utils-0.1.4-py2-none-any.whl#sha256=8174bb227226c068ebf6fd5e845ae4193502a6488cf2ac01a9482d579161e9c8', version: '0.1.4' },
+ { url: 'https://files.pythonhosted.org/packages/fe/ec/0c4b906147bfdb09ede4deff7489ea33267daf14f6d8c9706ed1b1ac3597/0x_contract_addresses-2.0.1-py3-none-any.whl#sha256=0514f73c92694bbeee2704374fcd2f0eefbe8bbdfc43dd95dc0ab6c262d4c058', version: '2.0.1' },
+ { url: 'https://files.pythonhosted.org/packages/ff/b9/6246538b88db7272f62d4eb0bd1afbb5ec402b24866be95059cc037d6970/00000a-0.0.2.tar.gz#sha256=3c1a3cdcc6cd2ca9a8dd44009509039dfa84928a4293069a74d5fc5c39e4b7a1', version: '0.0.2' },
].each do |item|
specify { expect(subject.version_from(item[:url])).to eql(item[:version]) }
end
diff --git a/spec/unit/ruby/parsers/gemfile_lock_spec.rb b/spec/unit/ruby/parsers/gemfile_lock_spec.rb
index 3d3f442..321aeab 100644
--- a/spec/unit/ruby/parsers/gemfile_lock_spec.rb
+++ b/spec/unit/ruby/parsers/gemfile_lock_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe Spandx::Ruby::Parsers::GemfileLock do
specify do
expect(subject).to match_array([
build('addressable', '2.7.0', path),
- build('ast', '2.4.0', path),
+ build('ast', '2.4.1', path),
build('benchmark-ips', '2.8.2', path),
build('benchmark-malloc', '0.2.0', path),
build('benchmark-perf', '0.6.0', path),
@@ -51,22 +51,23 @@ RSpec.describe Spandx::Ruby::Parsers::GemfileLock do
build('dotenv', '2.7.5', path),
build('faraday', '1.0.1', path),
build('hashdiff', '1.0.1', path),
- build('licensed', '2.10.0', path),
+ build('licensed', '2.11.1', path),
build('licensee', '9.14.0', path),
build('mini_portile2', '2.4.0', path),
build('multipart-post', '2.1.1', path),
- build('nanospinner', '1.0.0', path),
build('net-hippie', '0.3.2', path),
build('nokogiri', '1.10.9', path),
build('octokit', '4.18.0', path),
+ build('oj', '3.10.6', path),
build('parallel', '1.19.1', path),
- build('parser', '2.7.1.2', path),
+ build('parser', '2.7.1.3', path),
build('parslet', '2.0.0', path),
build('pathname-common_prefix', '0.0.1', path),
build('public_suffix', '4.0.5', path),
build('rainbow', '3.0.0', path),
build('rake', '13.0.1', path),
build('rake-compiler', '1.1.0', path),
+ build('regexp_parser', '1.7.1', path),
build('reverse_markdown', '1.4.0', path),
build('rexml', '3.2.4', path),
build('rspec', '3.9.0', path),
@@ -75,8 +76,9 @@ RSpec.describe Spandx::Ruby::Parsers::GemfileLock do
build('rspec-expectations', '3.9.2', path),
build('rspec-mocks', '3.9.1', path),
build('rspec-support', '3.9.3', path),
- build('rubocop', '0.83.0', path),
- build('rubocop-rspec', '1.39.0', path),
+ build('rubocop', '0.85.1', path),
+ build('rubocop-ast', '0.0.3', path),
+ build('rubocop-rspec', '1.40.0', path),
build('ruby-prof', '1.4.1', path),
build('ruby-progressbar', '1.10.1', path),
build('ruby-xxHash', '0.4.0.1', path),
@@ -87,9 +89,10 @@ RSpec.describe Spandx::Ruby::Parsers::GemfileLock do
build('terminal-table', '1.8.0', path),
build('thor', '0.20.3', path),
build('tomlrb', '1.3.0', path),
- build('tty-screen', '0.7.1', path),
+ build('tty-cursor', '0.7.1', path),
+ build('tty-spinner', '0.9.3', path),
build('unicode-display_width', '1.7.0', path),
- build('vcr', '5.1.0', path),
+ build('vcr', '6.0.0', path),
build('webmock', '3.8.3', path),
build('zeitwerk', '2.3.0', path),
])