commons-integrity 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/everypolitician/commons-integrity.svg?branch=master)](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: []
|