coconductor 0.9.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/funding.yml +1 -0
  3. data/.rubocop.yml +10 -1
  4. data/.rubocop_todo.yml +91 -0
  5. data/Gemfile +2 -0
  6. data/Rakefile +2 -0
  7. data/bin/coconductor +2 -1
  8. data/coconductor.gemspec +5 -1
  9. data/docs/SECURITY.md +3 -0
  10. data/lib/coconductor.rb +4 -2
  11. data/lib/coconductor/code_of_conduct.rb +15 -10
  12. data/lib/coconductor/commands/detect.rb +3 -1
  13. data/lib/coconductor/commands/diff.rb +5 -5
  14. data/lib/coconductor/commands/version.rb +2 -0
  15. data/lib/coconductor/field.rb +6 -6
  16. data/lib/coconductor/matchers.rb +2 -0
  17. data/lib/coconductor/matchers/dice.rb +2 -0
  18. data/lib/coconductor/matchers/exact.rb +2 -0
  19. data/lib/coconductor/matchers/field_aware.rb +4 -2
  20. data/lib/coconductor/matchers/matcher.rb +2 -0
  21. data/lib/coconductor/project_files.rb +2 -0
  22. data/lib/coconductor/project_files/code_of_conduct_file.rb +7 -5
  23. data/lib/coconductor/project_files/project_file.rb +2 -0
  24. data/lib/coconductor/projects.rb +2 -0
  25. data/lib/coconductor/projects/fs_project.rb +2 -0
  26. data/lib/coconductor/projects/git_project.rb +2 -0
  27. data/lib/coconductor/projects/github_project.rb +2 -0
  28. data/lib/coconductor/projects/project.rb +3 -1
  29. data/lib/coconductor/vendorer.rb +5 -3
  30. data/lib/coconductor/version.rb +3 -1
  31. data/script/console +1 -0
  32. data/script/vendor-codes-of-conduct +4 -3
  33. data/vendor/contributor-covenant/version/1/4/code-of-conduct.ar.md +4 -4
  34. data/vendor/contributor-covenant/version/1/4/code-of-conduct.de.md +2 -2
  35. data/vendor/contributor-covenant/version/1/4/code-of-conduct.gu.md +76 -0
  36. data/vendor/contributor-covenant/version/1/4/code-of-conduct.hi.md +2 -2
  37. data/vendor/contributor-covenant/version/1/4/code-of-conduct.hu.md +53 -0
  38. data/vendor/contributor-covenant/version/1/4/code-of-conduct.id.md +18 -20
  39. data/vendor/contributor-covenant/version/1/4/code-of-conduct.md +7 -7
  40. data/vendor/contributor-covenant/version/1/4/code-of-conduct.mr.md +78 -0
  41. data/vendor/contributor-covenant/version/1/4/code-of-conduct.pl.md +14 -15
  42. data/vendor/contributor-covenant/version/1/4/code-of-conduct.zh-cn.md +27 -27
  43. data/vendor/contributor-covenant/version/2/0/code_of_conduct.ca.md +84 -0
  44. data/vendor/contributor-covenant/version/2/0/code_of_conduct.es.md +89 -0
  45. data/vendor/contributor-covenant/version/2/0/code_of_conduct.id.md +136 -0
  46. data/vendor/contributor-covenant/version/2/0/code_of_conduct.it.md +127 -0
  47. data/vendor/contributor-covenant/version/2/0/code_of_conduct.ja.md +91 -0
  48. data/vendor/contributor-covenant/version/2/0/code_of_conduct.md +133 -0
  49. data/vendor/contributor-covenant/version/2/0/code_of_conduct.ru.md +124 -0
  50. data/vendor/contributor-covenant/version/2/0/code_of_conduct.tr.md +85 -0
  51. data/vendor/go/version/1/0/CODE_OF_CONDUCT.md +2 -2
  52. metadata +57 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b71c775a757f82264c097801280f182591524317178c4e3116d6b6c4f123d086
4
- data.tar.gz: 2e3cde6e96c80a419e43f0bafaca5ecb2f263b8d58a93b688d746cdedccac3d6
3
+ metadata.gz: 03e268467a41069c7e787e1ea18aa23a58f3cf8d438b79defb9d95e416095f8b
4
+ data.tar.gz: a3730a78e0c79cc1e8b4d2d4bb7b6b636c7d77153e0dfc9d7658d384bddd77b1
5
5
  SHA512:
6
- metadata.gz: 0c452909e461a7311b4d9022c427319a025a7b9788e0a8d3883e93b530e82ed0ccf5ee90218c49731ac8699e7b3a97e2806a7f881b60bc43ffe31bba9e8d64d7
7
- data.tar.gz: 337bc8152131a12b6686640560f5695569bfd0d3a2aa83a30ee59f31eb4a7babe67e0752793ca756366210e37d030a7b4794addf3ed2e86f9a096edd7e100464
6
+ metadata.gz: 80ece2e69625918a459678cf3fc27df8695a33039b68a5bc077e03570ab5ec85501cf8f2b840659d913356aa38fdb56565446a7dedef5df4e2709c46c5ef6876
7
+ data.tar.gz: ce605883c10f7179ad46f52f34b359d8f3b1d106a4016faf56ec56b5455ea911ce9c60b542bd660b4e7cbff5d53122dd09908eecc6054221d65070b1964d2767
@@ -0,0 +1 @@
1
+ patreon: benbalter
@@ -1,3 +1,12 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ require:
4
+ - rubocop-performance
5
+ - rubocop-rspec
6
+
7
+ AllCops:
8
+ NewCops: enable
9
+
1
10
  Style/Documentation:
2
11
  Enabled: false
3
12
 
@@ -6,7 +15,7 @@ Metrics/BlockLength:
6
15
  - spec/**/*
7
16
  - coconductor.gemspec
8
17
 
9
- Metrics/LineLength:
18
+ Layout/LineLength:
10
19
  Exclude:
11
20
  - lib/coconductor/project_files.rb
12
21
  - lib/coconductor/commands/*
@@ -0,0 +1,91 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2020-09-01 14:38:06 UTC using RuboCop version 0.90.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'coconductor.gemspec'
15
+
16
+ # Offense count: 1
17
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods.
18
+ Metrics/MethodLength:
19
+ Max: 11
20
+
21
+ # Offense count: 21
22
+ # Configuration parameters: Prefixes.
23
+ # Prefixes: when, with, without
24
+ RSpec/ContextWording:
25
+ Exclude:
26
+ - 'spec/coconductor/code_of_conduct_spec.rb'
27
+ - 'spec/coconductor/field_spec.rb'
28
+ - 'spec/coconductor/matchers/dice_spec.rb'
29
+ - 'spec/coconductor/matchers/field_aware_spec.rb'
30
+ - 'spec/coconductor/project_files/code_of_conduct_file_spec.rb'
31
+ - 'spec/coconductor/project_files/project_file_spec.rb'
32
+ - 'spec/coconductor/project_spec.rb'
33
+ - 'spec/coconductor_spec.rb'
34
+ - 'spec/integration_spec.rb'
35
+
36
+ # Offense count: 3
37
+ RSpec/DescribeClass:
38
+ Exclude:
39
+ - 'spec/coconductor/bin_spec.rb'
40
+ - 'spec/integration_spec.rb'
41
+ - 'spec/vendored_coc_spec.rb'
42
+
43
+ # Offense count: 3
44
+ # Configuration parameters: Max.
45
+ RSpec/ExampleLength:
46
+ Exclude:
47
+ - 'spec/coconductor/code_of_conduct_spec.rb'
48
+
49
+ # Offense count: 19
50
+ RSpec/MultipleExpectations:
51
+ Max: 4
52
+
53
+ # Offense count: 10
54
+ # Configuration parameters: AllowSubject.
55
+ RSpec/MultipleMemoizedHelpers:
56
+ Max: 8
57
+
58
+ # Offense count: 71
59
+ # Configuration parameters: IgnoreSharedExamples.
60
+ RSpec/NamedSubject:
61
+ Exclude:
62
+ - 'spec/coconductor/code_of_conduct_spec.rb'
63
+ - 'spec/coconductor/field_spec.rb'
64
+ - 'spec/coconductor/matchers/dice_spec.rb'
65
+ - 'spec/coconductor/matchers/exact_spec.rb'
66
+ - 'spec/coconductor/matchers/matcher_spec.rb'
67
+ - 'spec/coconductor/project_files/project_file_spec.rb'
68
+ - 'spec/coconductor/project_spec.rb'
69
+ - 'spec/coconductor_spec.rb'
70
+ - 'spec/integration_spec.rb'
71
+
72
+ # Offense count: 7
73
+ RSpec/NestedGroups:
74
+ Max: 4
75
+
76
+ # Offense count: 2
77
+ RSpec/RepeatedDescription:
78
+ Exclude:
79
+ - 'spec/coconductor/code_of_conduct_spec.rb'
80
+
81
+ # Offense count: 9
82
+ RSpec/ScatteredSetup:
83
+ Exclude:
84
+ - 'spec/coconductor/project_files/project_file_spec.rb'
85
+ - 'spec/coconductor/project_spec.rb'
86
+ - 'spec/integration_spec.rb'
87
+
88
+ # Offense count: 5
89
+ RSpec/SubjectStub:
90
+ Exclude:
91
+ - 'spec/coconductor/project_files/project_file_spec.rb'
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rspec/core/rake_task'
3
5
 
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require_relative '../lib/coconductor'
4
5
  require 'thor'
@@ -38,6 +39,6 @@ class CoconductorCLI < Thor
38
39
  end
39
40
 
40
41
  commands_dir = File.expand_path '../lib/coconductor/commands/', __dir__
41
- Dir["#{commands_dir}/*.rb"].each { |c| require(c) }
42
+ Dir["#{commands_dir}/*.rb"].sort.each { |c| require(c) }
42
43
 
43
44
  CoconductorCLI.start(ARGV)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'coconductor/version'
@@ -24,7 +26,7 @@ Gem::Specification.new do |spec|
24
26
  spec.require_paths = ['lib']
25
27
 
26
28
  spec.add_dependency 'licensee', '~> 9.9', '>= 9.9.4'
27
- spec.add_dependency 'thor', '~> 0.18'
29
+ spec.add_dependency 'thor', '>= 0.18', '< 2.0'
28
30
  spec.add_dependency 'toml', '~> 0.2'
29
31
 
30
32
  spec.add_development_dependency 'bundler', '~> 1.16'
@@ -32,6 +34,8 @@ Gem::Specification.new do |spec|
32
34
  spec.add_development_dependency 'reverse_markdown', '~> 1.1'
33
35
  spec.add_development_dependency 'rspec', '~> 3.0'
34
36
  spec.add_development_dependency 'rubocop', '~> 0.50'
37
+ spec.add_development_dependency('rubocop-performance', '~> 1.5')
38
+ spec.add_development_dependency('rubocop-rspec', '~> 1.36')
35
39
  spec.add_development_dependency 'twitter-text', '< 2.0'
36
40
  spec.add_development_dependency 'webmock', '~> 3.1'
37
41
  spec.add_development_dependency 'wikicloth', '~> 0.8'
@@ -0,0 +1,3 @@
1
+ # Security Policy
2
+
3
+ To report a security vulnerability, please email [ben@balter.com](mailto:ben@balter.com).
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative './coconductor/version'
2
4
  require 'licensee'
3
5
 
@@ -9,7 +11,7 @@ module Coconductor
9
11
  autoload :ProjectFiles, 'coconductor/project_files'
10
12
  autoload :Vendorer, 'coconductor/vendorer'
11
13
 
12
- CONFIDENCE_THRESHOLD = 90
14
+ CONFIDENCE_THRESHOLD = 85
13
15
 
14
16
  class << self
15
17
  attr_writer :confidence_threshold
@@ -23,7 +25,7 @@ module Coconductor
23
25
  end
24
26
 
25
27
  def project(path, **args)
26
- if path =~ %r{\Ahttps://github.com}
28
+ if %r{\Ahttps://github.com}.match?(path)
27
29
  Coconductor::Projects::GitHubProject.new(path, args)
28
30
  else
29
31
  Coconductor::Projects::GitProject.new(path, args)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'toml'
2
4
 
3
5
  module Coconductor
@@ -37,7 +39,7 @@ module Coconductor
37
39
  [
38
40
  matches['family'], 'version', matches['version'], matches['lang']
39
41
  ].compact.join('/')
40
- end.compact
42
+ end.compact.sort
41
43
  end
42
44
 
43
45
  def latest_in_family(family, language: DEFAULT_LANGUAGE)
@@ -50,7 +52,7 @@ module Coconductor
50
52
  def families
51
53
  @families ||= begin
52
54
  families = Dir["#{vendor_dir}/*"].map { |dir| File.basename(dir) }
53
- families - ['bundle']
55
+ (families - ['bundle']).sort
54
56
  end
55
57
  end
56
58
 
@@ -70,17 +72,18 @@ module Coconductor
70
72
  /version
71
73
  /(?<version>(?<major>\d)/(?<minor>\d)(/(?<patch>\d))?|(longer|shorter))
72
74
  /#{Coconductor::ProjectFiles::CodeOfConductFile::FILENAME_REGEX}
73
- }ix
74
- DEFAULT_LANGUAGE = 'en'.freeze
75
+ }ix.freeze
76
+ DEFAULT_LANGUAGE = 'en'
75
77
 
76
78
  attr_reader :key
77
79
  attr_writer :content
80
+
78
81
  include Licensee::ContentHelper
79
82
 
80
83
  # Define dynamic predicate helpers to determine if a code of conduct is a
81
84
  # member of a given family, e.g., code_of_conduct.contributor_covenant?
82
85
  CodeOfConduct.families.each do |f|
83
- define_method(f.tr('-', '_') + '?') { family == f }
86
+ define_method("#{f.tr('-', '_')}?") { family == f }
84
87
  end
85
88
 
86
89
  def initialize(key)
@@ -96,7 +99,7 @@ module Coconductor
96
99
  parts = key.split('/')
97
100
  if pseudo?
98
101
  nil
99
- elsif parts.last =~ /^[a-z-]{2,5}$/
102
+ elsif /^[a-z-]{2,5}$/.match?(parts.last)
100
103
  parts.last
101
104
  else
102
105
  DEFAULT_LANGUAGE
@@ -130,7 +133,7 @@ module Coconductor
130
133
  alias body content
131
134
 
132
135
  def inspect
133
- "#<Licensee::CodeOfConduct key=#{key}>"
136
+ "#<Coconductor::CodeOfConduct key=#{key}>"
134
137
  end
135
138
 
136
139
  def family
@@ -177,16 +180,18 @@ module Coconductor
177
180
  private
178
181
 
179
182
  def filename
180
- filename = if contributor_covenant?
183
+ filename = if contributor_covenant? && key.include?('/version/1/')
181
184
  'code-of-conduct'
185
+ elsif contributor_covenant? && key.include?('/version/2/')
186
+ 'code_of_conduct'
182
187
  elsif citizen_code_of_conduct?
183
188
  'citizen_code_of_conduct'
184
189
  else
185
190
  'CODE_OF_CONDUCT'
186
191
  end
187
192
 
188
- filename << '.' + language unless default_language?
189
- filename << '.md'
193
+ filename += ".#{language}" unless default_language?
194
+ "#{filename}.md"
190
195
  end
191
196
 
192
197
  def filepath
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CoconductorCLI < Thor
2
4
  desc 'detect [PATH]', 'Detect the code of conduct of the given project', default: Dir.pwd
3
5
  option :confidence, type: :numeric, default: Coconductor.confidence_threshold, desc: 'Confidence threshold'
@@ -57,7 +59,7 @@ class CoconductorCLI < Thor
57
59
  when :confidence
58
60
  Licensee::ContentHelper.format_percent(value)
59
61
  when :method
60
- value.to_s.tr('_', ' ').capitalize + ':'
62
+ "#{value.to_s.tr('_', ' ').capitalize}:"
61
63
  else
62
64
  value
63
65
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'tmpdir'
2
4
 
3
5
  class CoconductorCLI < Thor
@@ -39,20 +41,18 @@ class CoconductorCLI < Thor
39
41
  private
40
42
 
41
43
  def code_of_conduct_to_diff
42
- if options[:code_of_conduct_to_diff]
43
- return options[:code_of_conduct_to_diff]
44
- end
44
+ return options[:code_of_conduct_to_diff] if options[:code_of_conduct_to_diff]
45
45
 
46
46
  return project.code_of_conduct_file if remote?
47
47
 
48
48
  @code_of_conduct_to_diff ||= begin
49
- if STDIN.tty?
49
+ if $stdin.tty?
50
50
  error 'You must pipe the file contents to the command via STDIN'
51
51
  exit 1
52
52
  end
53
53
 
54
54
  filename = 'CODE_OF_CONDUCT.txt'
55
- Coconductor::ProjectFiles::CodeOfConductFile.new(STDIN.read, filename)
55
+ Coconductor::ProjectFiles::CodeOfConductFile.new($stdin.read, filename)
56
56
  end
57
57
  end
58
58
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CoconductorCLI < Thor
2
4
  desc 'version', 'Return the Coconductor version'
3
5
  def version
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  # Represents a fillable field in a code of conduct
3
5
  class Field
4
- REGEX = /\[(?<name>[A-Z_ ]{2,})[\s:-]*(?<description>.*?)\]/
6
+ REGEX = /\[(?<name>[A-Z_ ]{2,})[\s:-]*(?<description>.*?)\]/.freeze
5
7
 
6
8
  # the matchable raw text within the code of conduct including brackets
7
9
  attr_reader :raw_text
@@ -18,7 +20,7 @@ module Coconductor
18
20
  # Returns an array of Fields for the given code of conduct
19
21
  def from_code_of_conduct(code_of_conduct)
20
22
  matches = []
21
- return [] unless code_of_conduct && code_of_conduct.content
23
+ return [] unless code_of_conduct&.content
22
24
 
23
25
  code_of_conduct.content.scan(REGEX) do |_m|
24
26
  matches << Regexp.last_match
@@ -40,7 +42,7 @@ module Coconductor
40
42
  def initialize(raw_text, name: nil, description: nil)
41
43
  @raw_text = raw_text
42
44
  @name = name
43
- @description = description if description && description != ''
45
+ @description = description.capitalize if description && description != ''
44
46
  end
45
47
 
46
48
  # The unformatted field name as found in the code of conduct text
@@ -60,9 +62,7 @@ module Coconductor
60
62
 
61
63
  def description
62
64
  @description ||= begin
63
- if parts && parts[:description] && parts[:description] != ''
64
- return parts[:description]
65
- end
65
+ return parts[:description].capitalize if parts && parts[:description] && parts[:description] != ''
66
66
 
67
67
  DESCRIPTIONS[key]
68
68
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  module Matchers
3
5
  autoload :Dice, 'coconductor/matchers/dice'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  module Matchers
3
5
  class Dice < Licensee::Matchers::Dice
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  module Matchers
3
5
  class Exact < Licensee::Matchers::Exact
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  module Matchers
3
5
  class FieldAware < Licensee::Matchers::Exact
@@ -17,8 +19,8 @@ module Coconductor
17
19
 
18
20
  private
19
21
 
20
- FIELD_PLACEHOLDER = 'COCONDUCTOR_FIELD_COCONDUCTOR'.freeze
21
- FIELD_PLACEHOLDER_REGEX = /coconductor\\ field\\ coconductor/
22
+ FIELD_PLACEHOLDER = 'COCONDUCTOR_FIELD_COCONDUCTOR'
23
+ FIELD_PLACEHOLDER_REGEX = /coconductor\\ field\\ coconductor/.freeze
22
24
 
23
25
  def regex_for(code_of_conduct)
24
26
  coc = code_of_conduct.dup
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  module Matchers
3
5
  module Matcher
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  module ProjectFiles
3
5
  autoload :ProjectFile, 'coconductor/project_files/project_file'
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Coconductor
2
4
  module ProjectFiles
3
5
  class CodeOfConductFile < Coconductor::ProjectFiles::ProjectFile
4
6
  include Licensee::ContentHelper
5
7
 
6
8
  EXTENSIONS = %w[md markdown txt].freeze
7
- EXT_REGEX = /\.#{Regexp.union(EXTENSIONS)}/i
8
- BASENAME_REGEX = /(citizen[_-])?code[_-]of[_-]conduct/i
9
+ EXT_REGEX = /\.#{Regexp.union(EXTENSIONS)}/i.freeze
10
+ BASENAME_REGEX = /(citizen[_-])?code[_-]of[_-]conduct/i.freeze
9
11
  # LANG_REGEX must contain extension to avoid matching .md as the lang
10
- LANG_REGEX = /(\.(?<lang>[a-z]{2}(-[a-z]{2})?)#{EXT_REGEX})?/i
11
- FILENAME_REGEX = /#{BASENAME_REGEX}#{LANG_REGEX}#{EXT_REGEX}?/i
12
+ LANG_REGEX = /(\.(?<lang>[a-z]{2}(-[a-z]{2})?)#{EXT_REGEX})?/i.freeze
13
+ FILENAME_REGEX = /#{BASENAME_REGEX}#{LANG_REGEX}#{EXT_REGEX}?/i.freeze
12
14
 
13
15
  def self.name_score(filename)
14
- filename =~ /\A#{FILENAME_REGEX}/ ? 1.0 : 0.0
16
+ /\A#{FILENAME_REGEX}/.match?(filename) ? 1.0 : 0.0
15
17
  end
16
18
 
17
19
  def possible_matchers