licensed 5.0.4 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3a586e2e8aa3d3294b92e84252f95d05f8d27c9077b36da193daa33d6f4243a7
4
- data.tar.gz: c4452cafe3fb8316b7a38a3f9e57d65a4fd039b1ac39b6ff6ad944b2d8e3161e
3
+ metadata.gz: 93373cde622ea3d33acda4c6a94ddff7c309d6381b5578c5d8224aca5d899cf3
4
+ data.tar.gz: c03ab707bbc5f0aaecca317e2bfa3418d716a4aaba648cd1327626ef67ec8454
5
5
  SHA512:
6
- metadata.gz: 246d00fceee3b3c766d6653c70b7ec709259418eff549091796598f6c67cfe191e225bf5462b150f9f34605920f3dedc4acf635ff3942ffaa001ea7b1ce79cdb
7
- data.tar.gz: 3a88e5f7008e31107a29412f6aa84c98cede336c1039166092fb07f5cd29511e25e3c18aa37a7924eb784e9af8b933bdb553adc51fda1dd67dc860bd7598bca7
6
+ metadata.gz: c440e8a50d67a00eedd20ab514c66d922b6ffa7c7d24a8419ed558839d2355c8315dc865785110d176718015ed93004023557b763ff6e2c5003025e27ff3a770
7
+ data.tar.gz: 422a67416d5799789e0f2755190a112561cf1870627dc46d628311b175f1c96d27a222c7cc67113636853ef320348f45e8affd3e1c646b1b0a3005fb49eb95c4
data/Brewfile CHANGED
@@ -1,3 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- brew "ruby@3.1", version_file: ".ruby-version"
3
+ brew "ruby", version_file: ".ruby-version"
4
+
5
+ # Needed for building rugged
6
+ brew "cmake"
7
+ brew "pkgconf"
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- licensed (5.0.4)
4
+ licensed (5.0.7)
5
5
  csv (~> 3.3)
6
6
  json (~> 2.6)
7
7
  licensee (~> 9.16)
8
+ ostruct (~> 0.6.3)
8
9
  parallel (~> 1.22)
9
10
  pathname-common_prefix (~> 0.0.1)
10
11
  reverse_markdown (>= 2.1, < 4.0)
@@ -15,118 +16,121 @@ PATH
15
16
  GEM
16
17
  remote: https://rubygems.org/
17
18
  specs:
18
- activesupport (7.2.2.1)
19
+ activesupport (8.1.3)
19
20
  base64
20
- benchmark (>= 0.3)
21
21
  bigdecimal
22
22
  concurrent-ruby (~> 1.0, >= 1.3.1)
23
23
  connection_pool (>= 2.2.5)
24
24
  drb
25
25
  i18n (>= 1.6, < 2)
26
+ json
26
27
  logger (>= 1.4.2)
27
28
  minitest (>= 5.1)
28
29
  securerandom (>= 0.3)
29
30
  tzinfo (~> 2.0, >= 2.0.5)
30
- addressable (2.8.7)
31
- public_suffix (>= 2.0.2, < 7.0)
32
- ast (2.4.2)
33
- base64 (0.2.0)
34
- benchmark (0.4.0)
35
- bigdecimal (3.1.9)
31
+ uri (>= 0.13.1)
32
+ addressable (2.9.0)
33
+ public_suffix (>= 2.0.2, < 8.0)
34
+ ast (2.4.3)
35
+ base64 (0.3.0)
36
+ bigdecimal (4.1.1)
36
37
  byebug (12.0.0)
37
- concurrent-ruby (1.3.5)
38
- connection_pool (2.5.0)
39
- csv (3.3.4)
40
- dotenv (3.1.7)
41
- drb (2.2.1)
42
- faraday (2.12.2)
38
+ concurrent-ruby (1.3.6)
39
+ connection_pool (3.0.2)
40
+ csv (3.3.5)
41
+ dotenv (3.2.0)
42
+ drb (2.2.3)
43
+ faraday (2.14.1)
43
44
  faraday-net_http (>= 2.0, < 3.5)
44
45
  json
45
46
  logger
46
- faraday-net_http (3.4.0)
47
- net-http (>= 0.5.0)
48
- i18n (1.14.7)
47
+ faraday-net_http (3.4.2)
48
+ net-http (~> 0.5)
49
+ i18n (1.14.8)
49
50
  concurrent-ruby (~> 1.0)
50
- json (2.11.3)
51
- language_server-protocol (3.17.0.4)
52
- licensee (9.18.0)
51
+ json (2.19.3)
52
+ language_server-protocol (3.17.0.5)
53
+ licensee (9.19.0)
53
54
  dotenv (>= 2, < 4)
54
- octokit (>= 4.20, < 10.0)
55
+ octokit (>= 4.20, < 11.0)
55
56
  reverse_markdown (>= 1, < 4)
56
57
  rugged (>= 0.24, < 2.0)
57
58
  thor (>= 0.19, < 2.0)
58
59
  lint_roller (1.1.0)
59
- logger (1.6.6)
60
- mini_portile2 (2.8.8)
61
- minitest (5.25.5)
62
- minitest-hooks (1.5.2)
60
+ logger (1.7.0)
61
+ mini_portile2 (2.8.9)
62
+ minitest (5.27.0)
63
+ minitest-hooks (1.5.3)
63
64
  minitest (> 5.3)
64
- mocha (2.7.1)
65
+ mocha (3.1.0)
65
66
  ruby2_keywords (>= 0.0.5)
66
- net-http (0.6.0)
67
- uri
68
- nokogiri (1.18.8)
67
+ net-http (0.9.1)
68
+ uri (>= 0.11.1)
69
+ nokogiri (1.19.2)
69
70
  mini_portile2 (~> 2.8.2)
70
71
  racc (~> 1.4)
71
- octokit (9.2.0)
72
+ octokit (10.0.0)
72
73
  faraday (>= 1, < 3)
73
74
  sawyer (~> 0.9)
74
- parallel (1.27.0)
75
- parser (3.3.7.1)
75
+ ostruct (0.6.3)
76
+ parallel (1.28.0)
77
+ parser (3.3.11.1)
76
78
  ast (~> 2.4.1)
77
79
  racc
78
80
  pathname-common_prefix (0.0.2)
79
- public_suffix (6.0.1)
81
+ prism (1.9.0)
82
+ public_suffix (7.0.5)
80
83
  racc (1.8.1)
81
- rack (3.1.12)
84
+ rack (3.2.6)
82
85
  rainbow (3.1.1)
83
- rake (13.2.1)
84
- regexp_parser (2.10.0)
85
- reverse_markdown (3.0.0)
86
+ rake (13.4.1)
87
+ regexp_parser (2.12.0)
88
+ reverse_markdown (3.0.2)
86
89
  nokogiri
87
- rubocop (1.73.2)
90
+ rubocop (1.86.1)
88
91
  json (~> 2.3)
89
92
  language_server-protocol (~> 3.17.0.2)
90
93
  lint_roller (~> 1.1.0)
91
- parallel (~> 1.10)
94
+ parallel (>= 1.10)
92
95
  parser (>= 3.3.0.2)
93
96
  rainbow (>= 2.2.2, < 4.0)
94
97
  regexp_parser (>= 2.9.3, < 3.0)
95
- rubocop-ast (>= 1.38.0, < 2.0)
98
+ rubocop-ast (>= 1.49.0, < 2.0)
96
99
  ruby-progressbar (~> 1.7)
97
100
  unicode-display_width (>= 2.4.0, < 4.0)
98
- rubocop-ast (1.38.1)
99
- parser (>= 3.3.1.0)
100
- rubocop-github (0.23.0)
101
- rubocop (>= 1.72)
101
+ rubocop-ast (1.49.1)
102
+ parser (>= 3.3.7.2)
103
+ prism (~> 1.7)
104
+ rubocop-github (0.27.0)
105
+ rubocop (>= 1.76)
102
106
  rubocop-performance (>= 1.24)
103
107
  rubocop-rails (>= 2.23)
104
- rubocop-performance (1.24.0)
108
+ rubocop-performance (1.26.1)
105
109
  lint_roller (~> 1.1)
106
- rubocop (>= 1.72.1, < 2.0)
107
- rubocop-ast (>= 1.38.0, < 2.0)
108
- rubocop-rails (2.30.3)
110
+ rubocop (>= 1.75.0, < 2.0)
111
+ rubocop-ast (>= 1.47.1, < 2.0)
112
+ rubocop-rails (2.34.3)
109
113
  activesupport (>= 4.2.0)
110
114
  lint_roller (~> 1.1)
111
115
  rack (>= 1.1)
112
- rubocop (>= 1.72.1, < 2.0)
113
- rubocop-ast (>= 1.38.0, < 2.0)
116
+ rubocop (>= 1.75.0, < 2.0)
117
+ rubocop-ast (>= 1.44.0, < 2.0)
114
118
  ruby-progressbar (1.13.0)
115
119
  ruby-xxHash (0.4.0.2)
116
120
  ruby2_keywords (0.0.5)
117
121
  rugged (1.9.0)
118
- sawyer (0.9.2)
122
+ sawyer (0.9.3)
119
123
  addressable (>= 2.3.5)
120
124
  faraday (>= 0.17.3, < 3)
121
125
  securerandom (0.4.1)
122
- thor (1.3.2)
123
- tomlrb (2.0.3)
126
+ thor (1.5.0)
127
+ tomlrb (2.0.4)
124
128
  tzinfo (2.0.6)
125
129
  concurrent-ruby (~> 1.0)
126
- unicode-display_width (3.1.4)
127
- unicode-emoji (~> 4.0, >= 4.0.4)
128
- unicode-emoji (4.0.4)
129
- uri (1.0.3)
130
+ unicode-display_width (3.2.0)
131
+ unicode-emoji (~> 4.1)
132
+ unicode-emoji (4.2.0)
133
+ uri (1.1.1)
130
134
 
131
135
  PLATFORMS
132
136
  ruby
@@ -136,9 +140,9 @@ DEPENDENCIES
136
140
  licensed!
137
141
  minitest (~> 5.17)
138
142
  minitest-hooks (~> 1.5)
139
- mocha (~> 2.0)
143
+ mocha (~> 3.0)
140
144
  rake (~> 13.0)
141
145
  rubocop-github (~> 0.20)
142
146
 
143
147
  BUNDLED WITH
144
- 2.3.26
148
+ 4.0.8
data/README.md CHANGED
@@ -94,7 +94,7 @@ To get started after checking out the repo, run
94
94
 
95
95
  You can also run `script/console` for an interactive prompt that will allow you to experiment.
96
96
 
97
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then create a release on GitHub.
97
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, create a GitHub release from the matching `vX.Y.Z` tag.
98
98
 
99
99
  ### Adding a new source
100
100
 
@@ -45,7 +45,7 @@ jobs:
45
45
  - uses: actions/checkout@v1
46
46
 
47
47
  # install ruby
48
- - uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc
48
+ - uses: ruby/setup-ruby@80740b3b13bf9857e28854481ca95a84e78a2bdf
49
49
  with:
50
50
  ruby-version: "3.0"
51
51
 
@@ -71,7 +71,7 @@ jobs:
71
71
  - uses: actions/checkout@v1
72
72
 
73
73
  # install ruby and bundler
74
- - uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc
74
+ - uses: ruby/setup-ruby@80740b3b13bf9857e28854481ca95a84e78a2bdf
75
75
  with:
76
76
  ruby-version: "3.0"
77
77
 
@@ -95,7 +95,7 @@ jobs:
95
95
  - uses: actions/checkout@v1
96
96
 
97
97
  # install ruby and bundler
98
- - uses: ruby/setup-ruby@a2bbe5b1b236842c1cb7dd11e8e3b51e0a616acc
98
+ - uses: ruby/setup-ruby@80740b3b13bf9857e28854481ca95a84e78a2bdf
99
99
  with:
100
100
  ruby-version: "3.0"
101
101
 
@@ -59,6 +59,8 @@ end
59
59
 
60
60
  module Bundler
61
61
  class LazySpecification
62
- prepend ::Licensed::Bundler::LazySpecification
62
+ if Gem::Version.new(::Bundler::VERSION) < Gem::Version.new("4.0.0")
63
+ prepend ::Licensed::Bundler::LazySpecification
64
+ end
63
65
  end
64
66
  end
@@ -20,7 +20,7 @@ module Licensed
20
20
  metadata: {
21
21
  "type" => self.class.type,
22
22
  "summary" => package["Summary"],
23
- "homepage" => package["Home-page"]
23
+ "homepage" => homepage(package)
24
24
  }
25
25
  )
26
26
  end
@@ -39,7 +39,7 @@ module Licensed
39
39
  # Returns the location of license files in the package, checking for the inclusion of a new `license_files`
40
40
  # folder per https://peps.python.org/pep-0639/
41
41
  def package_license_location(package)
42
- dist_info = File.join(package["Location"], package["Name"].gsub("-", "_") + "-" + package["Version"] + ".dist-info")
42
+ dist_info = package_dist_info_path(package)
43
43
 
44
44
  license_path = ["license_files", "licenses"]
45
45
  .map { |directory| File.join(dist_info, directory) }
@@ -48,6 +48,15 @@ module Licensed
48
48
  license_path || dist_info
49
49
  end
50
50
 
51
+ # Returns the package's .dist-info path, matching case-insensitively to support
52
+ # filesystems where installed wheel metadata directories may be lowercase.
53
+ def package_dist_info_path(package)
54
+ expected = "#{package["Name"].tr("-", "_")}-#{package["Version"]}.dist-info".downcase
55
+ dist_infos = Dir.glob(File.join(package["Location"], "*.dist-info"))
56
+ dist_infos.find { |path| File.basename(path).downcase == expected } ||
57
+ File.join(package["Location"], "#{package["Name"].tr("-", "_")}-#{package["Version"]}.dist-info")
58
+ end
59
+
51
60
  # Returns parsed information for all packages used by the project,
52
61
  # using `pip list` to determine what packages are used and `pip show`
53
62
  # to gather package information
@@ -68,20 +77,36 @@ module Licensed
68
77
  @package_names ||= begin
69
78
  JSON.parse(pip_list_command).map { |package| package["name"] }
70
79
  rescue JSON::ParserError => e
71
- message = "Licensed was unable to parse the output from 'npm list'. JSON Error: #{e.message}"
80
+ message = "Licensed was unable to parse the output from 'pip list'. JSON Error: #{e.message}"
72
81
  raise Licensed::Sources::Source::Error, message
73
82
  end
74
83
  end
75
84
 
76
85
  # Returns a hash filled with package info parsed from the email-header formatted output
77
- # returned by `pip show`
86
+ # returned by `pip show --verbose`, including continuation lines for multi-line fields.
78
87
  def parse_package_info(package_info)
88
+ current_key = nil
89
+
79
90
  package_info.lines.each_with_object(Hash.new(0)) do |pkg, a|
80
- next if pkg.start_with?(/^\s/)
91
+ if pkg.match?(/^\s/)
92
+ if current_key
93
+ current_value = a[current_key]
94
+ continuation = pkg.strip
95
+ a[current_key] =
96
+ if current_value.to_s.empty?
97
+ continuation
98
+ else
99
+ "#{current_value}\n#{continuation}"
100
+ end
101
+ end
102
+ next
103
+ end
81
104
 
82
105
  k, v = pkg.split(":", 2)
83
106
  next if k.nil? || k.empty?
84
- a[k.strip] = v&.strip
107
+
108
+ current_key = k.strip
109
+ a[current_key] = v&.strip
85
110
  end
86
111
  end
87
112
 
@@ -92,7 +117,39 @@ module Licensed
92
117
 
93
118
  # Returns the output from `pip show <package> <package> ...`
94
119
  def pip_show_command(package)
95
- Licensed::Shell.execute(*pip_command, "--disable-pip-version-check", "show", package)
120
+ Licensed::Shell.execute(*pip_command, "--disable-pip-version-check", "show", "--verbose", package)
121
+ end
122
+
123
+ # Returns the package homepage from pip package metadata
124
+ def homepage(package)
125
+ home_page = package["Home-page"]
126
+ return home_page unless home_page.to_s.empty?
127
+
128
+ homepage_from_project_urls(package["Project-URL"] || package["Project-URLs"]) || home_page
129
+ end
130
+
131
+ # Returns best-effort homepage URL extracted from Project-URL(s) metadata
132
+ # With priority given to Home > Repository > Source, otherwise the first URL
133
+ def homepage_from_project_urls(project_urls)
134
+ return if project_urls.to_s.empty?
135
+
136
+ entries = project_urls
137
+ .to_s
138
+ .split("\n")
139
+ .map(&:strip)
140
+ .reject(&:empty?)
141
+
142
+ candidates = entries.filter_map do |entry|
143
+ label, url = entry.split(",", 2).map { |value| value&.strip }
144
+ next unless url&.match?(%r{^https?://})
145
+
146
+ [label.to_s, url]
147
+ end
148
+
149
+ preferred = candidates.find { |label, _| label.match?(/home/i) } ||
150
+ candidates.find { |label, _| label.match?(/repo/i) } ||
151
+ candidates.find { |label, _| label.match?(/source/i) }
152
+ preferred&.last || candidates.first&.last
96
153
  end
97
154
 
98
155
  def virtual_env_dir
@@ -1,6 +1,56 @@
1
1
  # frozen_string_literal: true
2
+ require "open3"
3
+
2
4
  module Licensed
3
- VERSION = "5.0.4".freeze
5
+ VERSION = begin
6
+ root = File.expand_path("../..", __dir__)
7
+ loaded_spec = Gem.loaded_specs["licensed"]
8
+ loaded_from = loaded_spec&.loaded_from && File.expand_path(loaded_spec.loaded_from)
9
+
10
+ # Published gems should report the version stored in gem metadata. Source
11
+ # checkouts need to ignore Bundler's path gemspec so development builds can
12
+ # infer the next release version from git tags.
13
+ if loaded_spec&.version && loaded_from != File.join(root, "licensed.gemspec")
14
+ loaded_spec.version.to_s
15
+ else
16
+ git_error = nil
17
+
18
+ begin
19
+ output, status = Open3.capture2e(
20
+ "git",
21
+ "describe",
22
+ "--tags",
23
+ chdir: root
24
+ )
25
+ rescue SystemCallError => e
26
+ git_error = e.message
27
+ end
28
+
29
+ if status&.success?
30
+ described_version = output.strip.delete_prefix("v")
31
+
32
+ # Exact tags build that tag's version. Commits after a tag build the
33
+ # next patch version Homebrew and the release workflow should expect.
34
+ if (match = described_version.match(/\A(.+)-\d+-g[0-9a-f]+(?:-dirty)?\z/))
35
+ match[1].sub(/\d+\z/) { |segment| (segment.to_i + 1).to_s.rjust(segment.length, "0") }
36
+ else
37
+ described_version
38
+ end
39
+ elsif File.exist?(lockfile = File.join(root, "Gemfile.lock"))
40
+ # Shallow CI checkouts do not fetch tags in the broad test matrix. The
41
+ # lockfile keeps Bundler setup fast and deterministic there.
42
+ lockfile_version = File.read(lockfile)[/^ licensed \(([^)]+)\)$/, 1]
43
+ raise "Unable to determine licensed version from Gemfile.lock" unless lockfile_version
44
+
45
+ lockfile_version
46
+ else
47
+ error_output = output.to_s.strip
48
+ raise "Unable to determine licensed version" if git_error.to_s.empty? && error_output.empty?
49
+
50
+ raise "Unable to determine licensed version: #{git_error || error_output}"
51
+ end
52
+ end
53
+ end.freeze
4
54
 
5
55
  def self.previous_major_versions
6
56
  major_version = Gem::Version.new(Licensed::VERSION).segments.first
data/licensed.gemspec CHANGED
@@ -32,11 +32,12 @@ Gem::Specification.new do |spec|
32
32
  spec.add_dependency "parallel", "~> 1.22"
33
33
  spec.add_dependency "reverse_markdown", ">= 2.1", "< 4.0"
34
34
  spec.add_dependency "json", "~> 2.6"
35
+ spec.add_dependency "ostruct", "~> 0.6.3"
35
36
 
36
37
  spec.add_development_dependency "rake", "~> 13.0"
37
38
  spec.add_development_dependency "minitest", "~> 5.17"
38
39
  spec.add_development_dependency "minitest-hooks", "~> 1.5"
39
- spec.add_development_dependency "mocha", "~> 2.0"
40
+ spec.add_development_dependency "mocha", "~> 3.0"
40
41
  spec.add_development_dependency "rubocop-github", "~> 0.20"
41
42
  spec.add_development_dependency "byebug", "~> 12.0"
42
43
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: licensed
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.4
4
+ version: 5.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2025-05-06 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: csv
@@ -142,6 +141,20 @@ dependencies:
142
141
  - - "~>"
143
142
  - !ruby/object:Gem::Version
144
143
  version: '2.6'
144
+ - !ruby/object:Gem::Dependency
145
+ name: ostruct
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: 0.6.3
151
+ type: :runtime
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: 0.6.3
145
158
  - !ruby/object:Gem::Dependency
146
159
  name: rake
147
160
  requirement: !ruby/object:Gem::Requirement
@@ -190,14 +203,14 @@ dependencies:
190
203
  requirements:
191
204
  - - "~>"
192
205
  - !ruby/object:Gem::Version
193
- version: '2.0'
206
+ version: '3.0'
194
207
  type: :development
195
208
  prerelease: false
196
209
  version_requirements: !ruby/object:Gem::Requirement
197
210
  requirements:
198
211
  - - "~>"
199
212
  - !ruby/object:Gem::Version
200
- version: '2.0'
213
+ version: '3.0'
201
214
  - !ruby/object:Gem::Dependency
202
215
  name: rubocop-github
203
216
  requirement: !ruby/object:Gem::Requirement
@@ -348,7 +361,6 @@ homepage: https://github.com/github/licensed
348
361
  licenses:
349
362
  - MIT
350
363
  metadata: {}
351
- post_install_message:
352
364
  rdoc_options: []
353
365
  require_paths:
354
366
  - lib
@@ -363,8 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
363
375
  - !ruby/object:Gem::Version
364
376
  version: '0'
365
377
  requirements: []
366
- rubygems_version: 3.3.27
367
- signing_key:
378
+ rubygems_version: 4.0.6
368
379
  specification_version: 4
369
380
  summary: Extract and validate the licenses of dependencies.
370
381
  test_files: []