mutant 0.11.23 → 0.11.25

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa07ddf4b4373385631a41ea909149b416a97eaeaa51c0f259d846fbf5488c24
4
- data.tar.gz: ef900eed75c28e9ad08e21e2ed026dd4184808125ed5338c36e421659c388ff1
3
+ metadata.gz: 582339f240c2c234a6130ff32d7c998318b9b82670321483d5b66351524acfb9
4
+ data.tar.gz: 1f027e4239fc3bb5b518e796249ab4ac9cf2902d938995adfbd276af2fb69951
5
5
  SHA512:
6
- metadata.gz: e5a6f9a778791413e93f0b9d427d3636e4cbfba89581f1b196a03fa2bd528935550405da4a02e281a72476fac6dbd8a5a11ad101e484989051de36305fea3a63
7
- data.tar.gz: 256ba65540c021c9855248dfe4aeff4a230e2cd4119119b4e46ff5f82c1c1eac540d8a4e2f9b1345be9f2b81d171ecfbae5a11ae03d1139643522dd190c0e77c
6
+ metadata.gz: 823420ff1abcf0b8ac2e8c79012962a355f85324195cefc4d1daf9a60537f5773d2d125ec76881462b6f59d61081a2875c9f5c168ede8cbab190f7cc45a9a665
7
+ data.tar.gz: 1ebafd946b6b3404835653a3a024e655b9961d418247201ba14080fb772df20cab6295609acaee00d41bd9820f8fdb492b8b0606791435be395f863588cde104
@@ -391,6 +391,16 @@ module Mutant
391
391
  fixed: EMPTY_ARRAY,
392
392
  variable: nil
393
393
  ),
394
+ Node.new(
395
+ type: :forwarded_kwrestarg,
396
+ fixed: EMPTY_ARRAY,
397
+ variable: nil
398
+ ),
399
+ Node.new(
400
+ type: :forwarded_restarg,
401
+ fixed: EMPTY_ARRAY,
402
+ variable: nil
403
+ ),
394
404
  Node.new(
395
405
  type: :for,
396
406
  fixed: Node.fixed(
@@ -4,50 +4,84 @@ module Mutant
4
4
  module License
5
5
  class Subscription
6
6
  class Commercial < self
7
- class Author
8
- include Anima.new(:email)
9
-
10
- alias_method :to_s, :email
11
- public :to_s
12
- end
7
+ include AbstractType
13
8
 
14
9
  def self.from_json(value)
15
- new(licensed: value.fetch('authors').to_set { |email| Author.new(email: email) })
10
+ {
11
+ 'individual' => Individual,
12
+ 'organization' => Organization
13
+ }.fetch(value.fetch('type', 'individual')).from_json(value)
16
14
  end
17
15
 
18
- def call(world)
19
- candidates = candidates(world)
16
+ class Organization < self
17
+ SUBSCRIPTION_NAME = 'commercial organization'
20
18
 
21
- if (licensed & candidates).any?
22
- success
23
- else
24
- failure(licensed, candidates)
19
+ def self.from_json(value)
20
+ new(licensed: value.fetch('repositories').map(&Repository.public_method(:parse)).to_set)
25
21
  end
26
- end
27
22
 
28
- private
23
+ def call(world)
24
+ Repository.load_from_git(world).bind(&method(:check_subscription))
25
+ end
29
26
 
30
- def candidates(world)
31
- git_author(world).merge(commit_author(world))
32
- end
27
+ private
33
28
 
34
- def git_author(world)
35
- capture(world, %w[git config --get user.email])
29
+ def check_subscription(actual)
30
+ if licensed.any? { |repository| actual.any? { |other| repository.allow?(other) } }
31
+ success
32
+ else
33
+ failure(licensed, actual)
34
+ end
35
+ end
36
36
  end
37
37
 
38
- def commit_author(world)
39
- capture(world, %w[git show --quiet --pretty=format:%ae])
40
- end
38
+ class Individual < self
39
+ SUBSCRIPTION_NAME = 'commercial individual'
41
40
 
42
- def capture(world, command)
43
- world
44
- .capture_stdout(command)
45
- .fmap(&:chomp)
46
- .fmap { |email| Author.new(email: email) }
47
- .fmap { |value| Set.new([value]) }
48
- .from_right { Set.new }
49
- end
41
+ class Author
42
+ include Anima.new(:email)
43
+
44
+ alias_method :to_s, :email
45
+ public :to_s
46
+ end
47
+
48
+ def self.from_json(value)
49
+ new(licensed: value.fetch('authors').to_set { |email| Author.new(email: email) })
50
+ end
50
51
 
52
+ def call(world)
53
+ candidates = candidates(world)
54
+
55
+ if (licensed & candidates).any?
56
+ success
57
+ else
58
+ failure(licensed, candidates)
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def candidates(world)
65
+ git_author(world).merge(commit_author(world))
66
+ end
67
+
68
+ def git_author(world)
69
+ capture(world, %w[git config --get user.email])
70
+ end
71
+
72
+ def commit_author(world)
73
+ capture(world, %w[git show --quiet --pretty=format:%ae])
74
+ end
75
+
76
+ def capture(world, command)
77
+ world
78
+ .capture_stdout(command)
79
+ .fmap(&:chomp)
80
+ .fmap { |email| Author.new(email: email) }
81
+ .fmap { |value| Set.new([value]) }
82
+ .from_right { Set.new }
83
+ end
84
+ end # Individual
51
85
  end # Commercial
52
86
  end # Subscription
53
87
  end # License
@@ -4,63 +4,14 @@ module Mutant
4
4
  module License
5
5
  class Subscription
6
6
  class Opensource < self
7
- class Repository
8
- include Anima.new(:host, :path)
9
-
10
- REMOTE_REGEXP = /\A[^\t]+\t(?<url>[^ ]+) \((?:fetch|push)\)\n\z/.freeze
11
- GIT_SSH_REGEXP = %r{\A[^@]+@(?<host>[^:/]+)[:/](?<path>.+?)(?:\.git)?\z}.freeze
12
- GIT_HTTPS_REGEXP = %r{\Ahttps://(?<host>[^/]+)/(?<path>.+?)(?:\.git)?\z}.freeze
13
-
14
- private_constant(*constants(false))
15
-
16
- def to_s
17
- [host, path].join('/')
18
- end
19
-
20
- def self.parse(input)
21
- host, path = *input.split('/', 2).map(&:downcase)
22
- new(host: host, path: path)
23
- end
24
-
25
- def self.parse_remote(input)
26
- match = REMOTE_REGEXP.match(input) or
27
- fail "Unmatched remote line: #{input.inspect}"
28
-
29
- parse_url(match[:url])
30
- end
31
- private_class_method :parse_remote
32
-
33
- def self.parse_url(input)
34
- match = GIT_SSH_REGEXP.match(input) || GIT_HTTPS_REGEXP.match(input)
35
-
36
- unless match
37
- fail "Unmatched git remote URL: #{input.inspect}"
38
- end
39
-
40
- new(host: match[:host], path: match[:path].downcase)
41
- end
42
- private_class_method :parse_url
43
-
44
- def allow?(other)
45
- other.host.eql?(host) && path_match?(other.path)
46
- end
47
-
48
- private
49
-
50
- def path_match?(other_path)
51
- path.eql?(other_path) || (path.end_with?('/*') && other_path.start_with?(path[..-2]))
52
- end
53
- end # Opensource
7
+ SUBSCRIPTION_NAME = 'opensource repository'
54
8
 
55
9
  def self.from_json(value)
56
10
  new(licensed: value.fetch('repositories').map(&Repository.public_method(:parse)).to_set)
57
11
  end
58
12
 
59
13
  def call(world)
60
- world
61
- .capture_stdout(%w[git remote --verbose])
62
- .fmap(&method(:parse_remotes))
63
- .bind(&method(:check_subscription))
14
+ Repository.load_from_git(world).bind(&method(:check_subscription))
64
15
  end
65
16
 
66
17
  private
@@ -73,10 +24,6 @@ module Mutant
73
24
  end
74
25
  end
75
26
 
76
- def parse_remotes(input)
77
- input.lines.map(&Repository.method(:parse_remote)).to_set
78
- end
79
-
80
27
  end # Opensource
81
28
  end # Subscription
82
29
  end # License
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mutant
4
+ module License
5
+ class Subscription
6
+ class Repository
7
+ include Anima.new(:host, :path)
8
+
9
+ REMOTE_REGEXP = /\A[^\t]+\t(?<url>[^ ]+) \((?:fetch|push)\)\n\z/.freeze
10
+ GIT_SSH_REGEXP = %r{\A[^@]+@(?<host>[^:/]+)[:/](?<path>.+?)(?:\.git)?\z}.freeze
11
+ GIT_HTTPS_REGEXP = %r{\Ahttps://(?<host>[^/]+)/(?<path>.+?)(?:\.git)?\z}.freeze
12
+ WILDCARD = '/*'
13
+ WILDCARD_RANGE = (..-WILDCARD.length).freeze
14
+
15
+ private_constant(*constants(false))
16
+
17
+ def to_s
18
+ [host, path].join('/')
19
+ end
20
+
21
+ def self.load_from_git(world)
22
+ world
23
+ .capture_stdout(%w[git remote --verbose])
24
+ .fmap(&method(:parse_remotes))
25
+ end
26
+
27
+ def self.parse_remotes(input)
28
+ input.lines.map(&method(:parse_remote)).to_set
29
+ end
30
+ private_class_method :parse_remotes
31
+
32
+ def self.parse(input)
33
+ host, path = *input.split('/', 2).map(&:downcase)
34
+ new(host: host, path: path)
35
+ end
36
+
37
+ def self.parse_remote(input)
38
+ match = REMOTE_REGEXP.match(input) or
39
+ fail "Unmatched remote line: #{input.inspect}"
40
+
41
+ parse_url(match[:url])
42
+ end
43
+ private_class_method :parse_remote
44
+
45
+ def self.parse_url(input)
46
+ match = GIT_SSH_REGEXP.match(input) || GIT_HTTPS_REGEXP.match(input)
47
+
48
+ unless match
49
+ fail "Unmatched git remote URL: #{input.inspect}"
50
+ end
51
+
52
+ new(host: match[:host], path: match[:path].downcase)
53
+ end
54
+ private_class_method :parse_url
55
+
56
+ def allow?(other)
57
+ other.host.eql?(host) && path_match?(other.path)
58
+ end
59
+
60
+ private
61
+
62
+ def path_match?(other_path)
63
+ path.eql?(other_path) || wildcard_match?(path, other_path) || wildcard_match?(other_path, path)
64
+ end
65
+
66
+ def wildcard_match?(left, right)
67
+ left.end_with?(WILDCARD) && right.start_with?(left[WILDCARD_RANGE])
68
+ end
69
+ end # Repository
70
+ end # Subscription
71
+ end # License
72
+ end # Mutant
@@ -54,7 +54,7 @@ module Mutant
54
54
  end
55
55
 
56
56
  def subscription_name
57
- self.class.name.split('::').last.downcase
57
+ self.class::SUBSCRIPTION_NAME
58
58
  end
59
59
 
60
60
  def failure_message(expected, actual)
@@ -103,7 +103,7 @@ module Mutant
103
103
  end
104
104
 
105
105
  def emit_replacement
106
- new_text = MAP[input.quantifier.text]
106
+ new_text = MAP[input.quantifier.text] or return
107
107
 
108
108
  emit(mk_dup.tap { |new| new.quantifier.text = new_text })
109
109
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Mutant
4
4
  # Current mutant version
5
- VERSION = '0.11.23'
5
+ VERSION = '0.11.25'
6
6
  end # Mutant
data/lib/mutant.rb CHANGED
@@ -251,8 +251,9 @@ module Mutant
251
251
  require 'mutant/range'
252
252
  require 'mutant/license'
253
253
  require 'mutant/license/subscription'
254
- require 'mutant/license/subscription/opensource'
255
254
  require 'mutant/license/subscription/commercial'
255
+ require 'mutant/license/subscription/opensource'
256
+ require 'mutant/license/subscription/repository'
256
257
  require 'mutant/segment'
257
258
  require 'mutant/segment/recorder'
258
259
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mutant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.23
4
+ version: 0.11.25
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-08 00:00:00.000000000 Z
11
+ date: 2023-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: 2.6.1
53
+ version: 2.8.2
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: 2.6.1
60
+ version: 2.8.2
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: sorbet-runtime
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -220,6 +220,7 @@ files:
220
220
  - lib/mutant/license/subscription.rb
221
221
  - lib/mutant/license/subscription/commercial.rb
222
222
  - lib/mutant/license/subscription/opensource.rb
223
+ - lib/mutant/license/subscription/repository.rb
223
224
  - lib/mutant/loader.rb
224
225
  - lib/mutant/matcher.rb
225
226
  - lib/mutant/matcher/chain.rb