commons-integrity 0.1
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 +7 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +6 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +97 -0
- data/README.md +56 -0
- data/Rakefile +18 -0
- data/commons-integrity.gemspec +32 -0
- data/lib/commons/integrity.rb +13 -0
- data/lib/commons/integrity/check/area_positions_known.rb +80 -0
- data/lib/commons/integrity/check/base.rb +46 -0
- data/lib/commons/integrity/check/wikidata_identifiers.rb +72 -0
- data/lib/commons/integrity/config.rb +44 -0
- data/lib/commons/integrity/report.rb +40 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b9e522abef1caaeb6fd5b7fa1839bb8428c404d5
|
4
|
+
data.tar.gz: 3f90f3f405be99d6469f1833fccc2e4adaa1117d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1c7cd33fe3d7844c6e90e5a28085cfcdb5cff2526a62a4be27e16a15b076e21dc8a355eb77e363b3fd4f4179be95012b31e10ea51822567754d01f1a061365a4
|
7
|
+
data.tar.gz: d154d5216ab6ce881ee07b42b27d6baaa0c00a3fb00d7d145433bc1a9e752b24a0474e485f6b73461925f501005349510c0408d38aa29fbee520db360abc34e5
|
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
commons-integrity (0.1)
|
5
|
+
activesupport
|
6
|
+
json
|
7
|
+
require_all
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activesupport (5.2.0)
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
+
i18n (>= 0.7, < 2)
|
15
|
+
minitest (~> 5.1)
|
16
|
+
tzinfo (~> 1.1)
|
17
|
+
addressable (2.5.2)
|
18
|
+
public_suffix (>= 2.0.2, < 4.0)
|
19
|
+
ast (2.4.0)
|
20
|
+
axiom-types (0.1.1)
|
21
|
+
descendants_tracker (~> 0.0.4)
|
22
|
+
ice_nine (~> 0.11.0)
|
23
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
24
|
+
codeclimate-engine-rb (0.4.1)
|
25
|
+
virtus (~> 1.0)
|
26
|
+
coderay (1.1.2)
|
27
|
+
coercible (1.0.0)
|
28
|
+
descendants_tracker (~> 0.0.1)
|
29
|
+
concurrent-ruby (1.0.5)
|
30
|
+
crack (0.4.3)
|
31
|
+
safe_yaml (~> 1.0.0)
|
32
|
+
descendants_tracker (0.0.4)
|
33
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
34
|
+
equalizer (0.0.11)
|
35
|
+
hashdiff (0.3.7)
|
36
|
+
i18n (1.0.1)
|
37
|
+
concurrent-ruby (~> 1.0)
|
38
|
+
ice_nine (0.11.2)
|
39
|
+
json (2.1.0)
|
40
|
+
method_source (0.9.0)
|
41
|
+
minitest (5.11.3)
|
42
|
+
parallel (1.12.1)
|
43
|
+
parser (2.5.1.0)
|
44
|
+
ast (~> 2.4.0)
|
45
|
+
powerpack (0.1.1)
|
46
|
+
pry (0.11.3)
|
47
|
+
coderay (~> 1.1.0)
|
48
|
+
method_source (~> 0.9.0)
|
49
|
+
public_suffix (3.0.2)
|
50
|
+
rainbow (3.0.0)
|
51
|
+
rake (10.5.0)
|
52
|
+
reek (4.8.0)
|
53
|
+
codeclimate-engine-rb (~> 0.4.0)
|
54
|
+
parser (>= 2.5.0.0, < 2.6)
|
55
|
+
rainbow (~> 3.0)
|
56
|
+
require_all (2.0.0)
|
57
|
+
rubocop (0.55.0)
|
58
|
+
parallel (~> 1.10)
|
59
|
+
parser (>= 2.5)
|
60
|
+
powerpack (~> 0.1)
|
61
|
+
rainbow (>= 2.2.2, < 4.0)
|
62
|
+
ruby-progressbar (~> 1.7)
|
63
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
64
|
+
ruby-progressbar (1.9.0)
|
65
|
+
safe_yaml (1.0.4)
|
66
|
+
thread_safe (0.3.6)
|
67
|
+
tzinfo (1.2.5)
|
68
|
+
thread_safe (~> 0.1)
|
69
|
+
unicode-display_width (1.3.2)
|
70
|
+
virtus (1.0.5)
|
71
|
+
axiom-types (~> 0.1)
|
72
|
+
coercible (~> 1.0)
|
73
|
+
descendants_tracker (~> 0.0, >= 0.0.3)
|
74
|
+
equalizer (~> 0.0, >= 0.0.9)
|
75
|
+
webmock (2.3.2)
|
76
|
+
addressable (>= 2.3.6)
|
77
|
+
crack (>= 0.3.2)
|
78
|
+
hashdiff
|
79
|
+
|
80
|
+
PLATFORMS
|
81
|
+
ruby
|
82
|
+
|
83
|
+
DEPENDENCIES
|
84
|
+
bundler (~> 1.16)
|
85
|
+
commons-integrity!
|
86
|
+
minitest (~> 5.0)
|
87
|
+
pry
|
88
|
+
rake (~> 10.0)
|
89
|
+
reek
|
90
|
+
rubocop
|
91
|
+
webmock (~> 2.0)
|
92
|
+
|
93
|
+
RUBY VERSION
|
94
|
+
ruby 2.4.1p111
|
95
|
+
|
96
|
+
BUNDLED WITH
|
97
|
+
1.16.1
|
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# commons-integrity
|
2
|
+
|
3
|
+
[](https://travis-ci.org/everypolitician/commons-integrity)
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
### Installation
|
8
|
+
|
9
|
+
Add to the `Gemfile` dependencies for a proto-commons- repository:
|
10
|
+
|
11
|
+
gem 'commons-integrity', :github => 'everypolitician/commons-integrity'
|
12
|
+
|
13
|
+
### Configuration
|
14
|
+
|
15
|
+
Each check you wish to run within your project should be listed in a
|
16
|
+
configuration file (by default `.integrity.yml` in the project's root
|
17
|
+
directory, though this can also be specified separately.)
|
18
|
+
|
19
|
+
This will usually specify which file(s) to run against, and any options
|
20
|
+
specific to that individual check.
|
21
|
+
|
22
|
+
For example:
|
23
|
+
|
24
|
+
```yaml
|
25
|
+
WikidataIdentifiers:
|
26
|
+
AppliesTo: 'boundaries/**/*.csv'
|
27
|
+
column_name: 'WIKIDATA'
|
28
|
+
column_case: 'fixed'
|
29
|
+
```
|
30
|
+
|
31
|
+
## Orchestration
|
32
|
+
|
33
|
+
Currently you need to create your own script to run this, and choose how
|
34
|
+
to display the errors. We plan to make both of these much simpler.
|
35
|
+
|
36
|
+
An example `bin/check` could do something like:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'commons/integrity'
|
40
|
+
|
41
|
+
root = Pathname.new(ARGV.first || '.')
|
42
|
+
files = Pathname.glob(root + '**/*')
|
43
|
+
errors = files.map { |file| Commons::Integrity::Report.new(file: file).errors }
|
44
|
+
puts errors
|
45
|
+
```
|
46
|
+
|
47
|
+
## Creating new Checks
|
48
|
+
|
49
|
+
Add new checks in `lib/commons/integrity/check/` such that they look
|
50
|
+
like existing checks.
|
51
|
+
|
52
|
+
Each should inherit from `Commons::Integrity::Check::Base` and supply
|
53
|
+
its own `errors` method.
|
54
|
+
|
55
|
+
Documentation for the Check should be added in [YARD](https://yardoc.org/)
|
56
|
+
format.
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'reek/rake/task'
|
5
|
+
require 'rubocop/rake_task'
|
6
|
+
|
7
|
+
Rake::TestTask.new do |t|
|
8
|
+
t.libs << 'test'
|
9
|
+
t.libs << 'lib'
|
10
|
+
t.warning = true
|
11
|
+
t.verbose = true
|
12
|
+
t.test_files = FileList['test/**/*.rb']
|
13
|
+
end
|
14
|
+
|
15
|
+
RuboCop::RakeTask.new
|
16
|
+
Reek::Rake::Task.new
|
17
|
+
|
18
|
+
task default: %w[test rubocop reek]
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'commons-integrity'
|
5
|
+
spec.version = '0.1'
|
6
|
+
spec.authors = ['Tony Bowden', 'Alex Dutton']
|
7
|
+
spec.email = ['parliaments@mysociety.org']
|
8
|
+
|
9
|
+
spec.summary = 'Check the integrity of Democratic Commons data'
|
10
|
+
spec.homepage = 'https://github.com/everypolitician/commons-integrity'
|
11
|
+
spec.license = 'MIT'
|
12
|
+
|
13
|
+
spec.required_ruby_version = '~> 2.4.0'
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
16
|
+
f.match(%r{^(test|spec|features)/})
|
17
|
+
end
|
18
|
+
spec.bindir = 'bin'
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_dependency 'activesupport'
|
22
|
+
spec.add_dependency 'json'
|
23
|
+
spec.add_dependency 'require_all'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
26
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
27
|
+
spec.add_development_dependency 'pry'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
29
|
+
spec.add_development_dependency 'reek'
|
30
|
+
spec.add_development_dependency 'rubocop'
|
31
|
+
spec.add_development_dependency 'webmock', '~> 2.0'
|
32
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'require_all'
|
4
|
+
|
5
|
+
require_rel 'integrity/check'
|
6
|
+
require_rel 'integrity/report'
|
7
|
+
|
8
|
+
module Commons
|
9
|
+
# This module contains all the library code for checking the
|
10
|
+
# integrity of data.
|
11
|
+
module Integrity
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require 'csv'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
module Commons
|
8
|
+
module Integrity
|
9
|
+
class Check
|
10
|
+
# Ensure we have rich position data for positions associated with boundaries
|
11
|
+
#
|
12
|
+
# This check should be applied to a
|
13
|
+
# boundaries/build/position-data.json file. It'll check
|
14
|
+
# that that file has data for every position mentioned in
|
15
|
+
# the index.json file in the same directory.
|
16
|
+
#
|
17
|
+
# == Configuration Options
|
18
|
+
class AreaPositionsKnown < Base
|
19
|
+
# @return [Array<Error>]
|
20
|
+
# Errors will be in the category `:position_id_message`
|
21
|
+
def errors
|
22
|
+
positions_missing_role_data.map do |position|
|
23
|
+
error(
|
24
|
+
position_id_message: "#{position} was found in #{boundaries_index_pathname} but not in #{pathname}"
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def positions_missing_role_data
|
32
|
+
(position_items_from_index - positions_with_role_data).sort
|
33
|
+
end
|
34
|
+
|
35
|
+
def boundaries_index_pathname
|
36
|
+
pathname.dirname.join('index.json')
|
37
|
+
end
|
38
|
+
|
39
|
+
def boundaries_index_data
|
40
|
+
@boundaries_index_data ||= JSON.parse(
|
41
|
+
boundaries_index_pathname.read,
|
42
|
+
symbolize_names: true
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
def position_items_from_index
|
47
|
+
Set.new(
|
48
|
+
boundaries_index_data.flat_map do |entry|
|
49
|
+
BoundaryIndexEntry.new(entry).associated_positions
|
50
|
+
end
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def positions_with_role_data
|
55
|
+
Set.new(
|
56
|
+
JSON.parse(pathname.read, symbolize_names: true).map do |role|
|
57
|
+
role[:role_id]
|
58
|
+
end
|
59
|
+
)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# This encapsulates a top-level entry in the JSON file which
|
65
|
+
# acts as an index of the boundary data directories
|
66
|
+
class BoundaryIndexEntry
|
67
|
+
def initialize(entry_data)
|
68
|
+
@entry_data = entry_data
|
69
|
+
end
|
70
|
+
|
71
|
+
def associated_positions
|
72
|
+
entry_data[:associations].map { |association| association[:position_item_id] }
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
attr_reader :entry_data
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Commons
|
4
|
+
module Integrity
|
5
|
+
class Check
|
6
|
+
# All other checks should inherit from here, and override `errors`
|
7
|
+
class Base
|
8
|
+
def initialize(filename, config: nil)
|
9
|
+
@filename = filename
|
10
|
+
@given_config = config
|
11
|
+
end
|
12
|
+
|
13
|
+
def errors
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.moniker
|
18
|
+
name.sub('Commons::Integrity::Check::', '')
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :filename, :given_config
|
24
|
+
|
25
|
+
# Simple struct to represent any errors raised
|
26
|
+
Error = Struct.new(:category, :message, :filename)
|
27
|
+
|
28
|
+
def error(pair)
|
29
|
+
Error.new(*pair.first, filename)
|
30
|
+
end
|
31
|
+
|
32
|
+
def config
|
33
|
+
@config ||= @given_config || Config.new
|
34
|
+
end
|
35
|
+
|
36
|
+
def pathname
|
37
|
+
@pathname ||= Pathname.new(filename)
|
38
|
+
end
|
39
|
+
|
40
|
+
def my_config
|
41
|
+
config.for(self.class.moniker)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require 'csv'
|
5
|
+
|
6
|
+
module Commons
|
7
|
+
module Integrity
|
8
|
+
class Check
|
9
|
+
# Check that any values in a "wikidata" column look like valid IDs
|
10
|
+
#
|
11
|
+
# Given a CSV file with a column of Wikidata identifiers, this
|
12
|
+
# Check will ensure that all the values in that column look like
|
13
|
+
# valid identifiers (i.e. are Q-numbers). It does *not* check that
|
14
|
+
# they are _actually_ valid IDs: only that they are of the correct
|
15
|
+
# form.
|
16
|
+
#
|
17
|
+
# == Configuration Options
|
18
|
+
# * column_name: the column containing the IDs (default: "wikidata")
|
19
|
+
# * column_case: "fixed" if the column_name must be exactly as specified (default: "any")
|
20
|
+
class WikidataIdentifiers < Base
|
21
|
+
# @return [Array<Error>]
|
22
|
+
# Errors will be in the category `:wikidata_id_format`
|
23
|
+
def errors
|
24
|
+
problematic_values.map { |val| error(wikidata_id_format: "Invalid wikidata ID: #{val}") }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
DEFAULT_COLUMN_NAME = 'wikidata'
|
30
|
+
DEFAULT_COLUMN_CASE = 'any'
|
31
|
+
|
32
|
+
def csv
|
33
|
+
@csv ||= CSV.read(pathname, headers: true)
|
34
|
+
end
|
35
|
+
|
36
|
+
def headers
|
37
|
+
csv.headers
|
38
|
+
end
|
39
|
+
|
40
|
+
def column_name
|
41
|
+
my_config.to_h['column_name'] || DEFAULT_COLUMN_NAME
|
42
|
+
end
|
43
|
+
|
44
|
+
def comparison_type
|
45
|
+
my_config.to_h['column_case'] || DEFAULT_COLUMN_CASE
|
46
|
+
end
|
47
|
+
|
48
|
+
def comparison_conversion
|
49
|
+
return :to_s if comparison_type == 'fixed'
|
50
|
+
:downcase
|
51
|
+
end
|
52
|
+
|
53
|
+
def wikidata_column
|
54
|
+
headers.find { |header| header.send(comparison_conversion) == column_name.send(comparison_conversion) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def wikidata_column?
|
58
|
+
wikidata_column
|
59
|
+
end
|
60
|
+
|
61
|
+
def wikidata_values
|
62
|
+
return [] unless wikidata_column?
|
63
|
+
csv.map { |row| row[wikidata_column] }
|
64
|
+
end
|
65
|
+
|
66
|
+
def problematic_values
|
67
|
+
wikidata_values.reject { |value| value =~ /^Q[1-9][0-9]*$/ }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Commons
|
6
|
+
module Integrity
|
7
|
+
# This represents the configuration. For now we only have a single
|
8
|
+
# config file, but I expect this will become more complex later, and
|
9
|
+
# will likely need split into an abstract `Config` combining
|
10
|
+
# multiple `Config::File` objects.
|
11
|
+
class Config
|
12
|
+
def initialize(supplied_location = nil)
|
13
|
+
@supplied_location = supplied_location
|
14
|
+
end
|
15
|
+
|
16
|
+
def for(check)
|
17
|
+
yaml[check]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :supplied_location
|
23
|
+
|
24
|
+
DEFAULT_LOCATION = Pathname.pwd + '.integrity.yml'
|
25
|
+
|
26
|
+
def yaml
|
27
|
+
return {} unless config_exists?
|
28
|
+
@yaml ||= YAML.load_file(pathname)
|
29
|
+
end
|
30
|
+
|
31
|
+
def possible_file_locations
|
32
|
+
[supplied_location, DEFAULT_LOCATION]
|
33
|
+
end
|
34
|
+
|
35
|
+
def pathname
|
36
|
+
possible_file_locations.compact.find { |file| Pathname.new(file).exist? }
|
37
|
+
end
|
38
|
+
|
39
|
+
def config_exists?
|
40
|
+
pathname
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/core_ext/class/subclasses'
|
4
|
+
require 'require_all'
|
5
|
+
|
6
|
+
require_relative 'config'
|
7
|
+
require_rel 'check'
|
8
|
+
|
9
|
+
module Commons
|
10
|
+
module Integrity
|
11
|
+
# Collate the errors from all reports applying to a file
|
12
|
+
class Report
|
13
|
+
def initialize(file:, config: nil)
|
14
|
+
@file = Pathname.new(file)
|
15
|
+
@config = config
|
16
|
+
end
|
17
|
+
|
18
|
+
def errors
|
19
|
+
relevant_checks.flat_map { |check| check.new(file).errors }
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :file, :config
|
25
|
+
|
26
|
+
ALL_CHECKS = Commons::Integrity::Check::Base.descendants
|
27
|
+
|
28
|
+
def relevant_checks
|
29
|
+
return [] unless config
|
30
|
+
ALL_CHECKS.select do |check|
|
31
|
+
check_config = config.for(check.moniker)
|
32
|
+
if check_config
|
33
|
+
pattern = check_config.dig('AppliesTo')
|
34
|
+
file.fnmatch pattern if pattern
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: commons-integrity
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tony Bowden
|
8
|
+
- Alex Dutton
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2018-06-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: json
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: require_all
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :runtime
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: bundler
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.16'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.16'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: minitest
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '5.0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '5.0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: pry
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
96
|
+
- !ruby/object:Gem::Version
|
97
|
+
version: '0'
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: rake
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - "~>"
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '10.0'
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - "~>"
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '10.0'
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: reek
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rubocop
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: webmock
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - "~>"
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '2.0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '2.0'
|
154
|
+
description:
|
155
|
+
email:
|
156
|
+
- parliaments@mysociety.org
|
157
|
+
executables: []
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- ".rubocop.yml"
|
162
|
+
- ".travis.yml"
|
163
|
+
- Gemfile
|
164
|
+
- Gemfile.lock
|
165
|
+
- README.md
|
166
|
+
- Rakefile
|
167
|
+
- commons-integrity.gemspec
|
168
|
+
- lib/commons/integrity.rb
|
169
|
+
- lib/commons/integrity/check/area_positions_known.rb
|
170
|
+
- lib/commons/integrity/check/base.rb
|
171
|
+
- lib/commons/integrity/check/wikidata_identifiers.rb
|
172
|
+
- lib/commons/integrity/config.rb
|
173
|
+
- lib/commons/integrity/report.rb
|
174
|
+
homepage: https://github.com/everypolitician/commons-integrity
|
175
|
+
licenses:
|
176
|
+
- MIT
|
177
|
+
metadata: {}
|
178
|
+
post_install_message:
|
179
|
+
rdoc_options: []
|
180
|
+
require_paths:
|
181
|
+
- lib
|
182
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - "~>"
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: 2.4.0
|
187
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: '0'
|
192
|
+
requirements: []
|
193
|
+
rubyforge_project:
|
194
|
+
rubygems_version: 2.6.14.1
|
195
|
+
signing_key:
|
196
|
+
specification_version: 4
|
197
|
+
summary: Check the integrity of Democratic Commons data
|
198
|
+
test_files: []
|