globus_client 0.13.0 → 0.14.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 +4 -4
- data/.rubocop.yml +21 -12
- data/.rubocop_todo.yml +33 -0
- data/Gemfile +10 -2
- data/Gemfile.lock +17 -20
- data/Rakefile +3 -3
- data/api_test.rb +20 -18
- data/globus_client.gemspec +19 -26
- data/lib/globus_client/authenticator.rb +5 -5
- data/lib/globus_client/endpoint.rb +34 -29
- data/lib/globus_client/identity.rb +5 -5
- data/lib/globus_client/unexpected_response.rb +1 -1
- data/lib/globus_client/version.rb +1 -1
- data/lib/globus_client.rb +28 -24
- metadata +5 -91
- data/.autoupdate/postupdate +0 -19
- data/.rubocop/custom.yml +0 -80
- data/.standard.yml +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bae9be2599dca47133561cc9f50d02118d633e973f973619bf642a890d266d7d
|
|
4
|
+
data.tar.gz: 032a19fb8edf3b11740dd487415a98f14522daac3ae4966302376b902c787e01
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f66705c5adbda9f69f8ab99b8c02ad8b16dafcf4760b0918f63191874066691c1c46211588a197629206f6e53f72b1893748bcac04594db44afeaa1f3a40706a
|
|
7
|
+
data.tar.gz: f901d249a7b112efb537e88387aa6833759f2ec6f801277d4970a0830d7761abfe64e8a4163337ce252e2b9beb4e46410757832ecc300f649d8e21a5a6381669
|
data/.rubocop.yml
CHANGED
|
@@ -1,18 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
merge:
|
|
3
|
-
- Exclude
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
|
4
2
|
|
|
5
3
|
require:
|
|
6
|
-
- standard
|
|
7
|
-
- standard-custom
|
|
8
|
-
- standard-performance
|
|
9
4
|
- rubocop-performance
|
|
10
5
|
- rubocop-rspec
|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
7
|
+
AllCops:
|
|
8
|
+
TargetRubyVersion: 3.1
|
|
9
|
+
DisplayCopNames: true
|
|
10
|
+
SuggestExtensions: false
|
|
11
|
+
NewCops: disable
|
|
12
|
+
Exclude:
|
|
13
|
+
- bin/**
|
|
14
|
+
- vendor/bundle/**/*
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
# Per team developer playbook
|
|
17
|
+
RSpec/MultipleMemoizedHelpers:
|
|
18
|
+
Enabled: false
|
|
19
|
+
|
|
20
|
+
# Layout
|
|
21
|
+
Layout/LineLength:
|
|
22
|
+
Max: 150
|
|
23
|
+
|
|
24
|
+
# Naming
|
|
25
|
+
Naming/PredicateName:
|
|
26
|
+
NamePrefix:
|
|
27
|
+
- has
|
data/.rubocop_todo.yml
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This configuration was generated by
|
|
2
|
+
# `rubocop --auto-gen-config --auto-gen-only-exclude`
|
|
3
|
+
# on 2023-09-29 23:59:42 UTC using RuboCop version 1.56.3.
|
|
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
|
+
Lint/StructNewOverride:
|
|
11
|
+
Exclude:
|
|
12
|
+
- 'lib/globus_client/endpoint.rb'
|
|
13
|
+
|
|
14
|
+
# Offense count: 4
|
|
15
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
|
|
16
|
+
Metrics/AbcSize:
|
|
17
|
+
Exclude:
|
|
18
|
+
- 'lib/globus_client.rb'
|
|
19
|
+
- 'lib/globus_client/endpoint.rb'
|
|
20
|
+
- 'lib/globus_client/unexpected_response.rb'
|
|
21
|
+
|
|
22
|
+
# Offense count: 1
|
|
23
|
+
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
|
|
24
|
+
Metrics/CyclomaticComplexity:
|
|
25
|
+
Exclude:
|
|
26
|
+
- 'lib/globus_client/endpoint.rb'
|
|
27
|
+
|
|
28
|
+
# Offense count: 3
|
|
29
|
+
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
|
|
30
|
+
Metrics/MethodLength:
|
|
31
|
+
Exclude:
|
|
32
|
+
- 'lib/globus_client/endpoint.rb'
|
|
33
|
+
- 'lib/globus_client/unexpected_response.rb'
|
data/Gemfile
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in globus_client.gemspec
|
|
6
6
|
gemspec
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
group :deployment do
|
|
9
|
+
gem 'byebug'
|
|
10
|
+
gem 'rake', '~> 13.0'
|
|
11
|
+
gem 'rspec', '~> 3.0'
|
|
12
|
+
gem 'rubocop-performance'
|
|
13
|
+
gem 'rubocop-rspec'
|
|
14
|
+
gem 'simplecov'
|
|
15
|
+
gem 'webmock'
|
|
16
|
+
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
globus_client (0.
|
|
4
|
+
globus_client (0.14.0)
|
|
5
5
|
activesupport (>= 4.2, < 8)
|
|
6
6
|
faraday
|
|
7
7
|
faraday-retry
|
|
@@ -10,21 +10,30 @@ PATH
|
|
|
10
10
|
GEM
|
|
11
11
|
remote: https://rubygems.org/
|
|
12
12
|
specs:
|
|
13
|
-
activesupport (7.0
|
|
13
|
+
activesupport (7.1.0)
|
|
14
|
+
base64
|
|
15
|
+
bigdecimal
|
|
14
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
17
|
+
connection_pool (>= 2.2.5)
|
|
18
|
+
drb
|
|
15
19
|
i18n (>= 1.6, < 2)
|
|
16
20
|
minitest (>= 5.1)
|
|
21
|
+
mutex_m
|
|
17
22
|
tzinfo (~> 2.0)
|
|
18
23
|
addressable (2.8.5)
|
|
19
24
|
public_suffix (>= 2.0.2, < 6.0)
|
|
20
25
|
ast (2.4.2)
|
|
21
26
|
base64 (0.1.1)
|
|
27
|
+
bigdecimal (3.1.4)
|
|
22
28
|
byebug (11.1.3)
|
|
23
29
|
concurrent-ruby (1.2.2)
|
|
30
|
+
connection_pool (2.4.1)
|
|
24
31
|
crack (0.4.5)
|
|
25
32
|
rexml
|
|
26
33
|
diff-lcs (1.5.0)
|
|
27
34
|
docile (1.4.0)
|
|
35
|
+
drb (2.1.1)
|
|
36
|
+
ruby2_keywords
|
|
28
37
|
faraday (2.7.11)
|
|
29
38
|
base64
|
|
30
39
|
faraday-net_http (>= 2.0, < 3.1)
|
|
@@ -37,10 +46,10 @@ GEM
|
|
|
37
46
|
concurrent-ruby (~> 1.0)
|
|
38
47
|
json (2.6.3)
|
|
39
48
|
language_server-protocol (3.17.0.3)
|
|
40
|
-
lint_roller (1.1.0)
|
|
41
49
|
minitest (5.20.0)
|
|
50
|
+
mutex_m (0.1.2)
|
|
42
51
|
parallel (1.23.0)
|
|
43
|
-
parser (3.2.2.
|
|
52
|
+
parser (3.2.2.4)
|
|
44
53
|
ast (~> 2.4.1)
|
|
45
54
|
racc
|
|
46
55
|
public_suffix (5.0.3)
|
|
@@ -62,7 +71,7 @@ GEM
|
|
|
62
71
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
63
72
|
rspec-support (~> 3.12.0)
|
|
64
73
|
rspec-support (3.12.1)
|
|
65
|
-
rubocop (1.56.
|
|
74
|
+
rubocop (1.56.4)
|
|
66
75
|
base64 (~> 0.1.1)
|
|
67
76
|
json (~> 2.3)
|
|
68
77
|
language_server-protocol (>= 3.17.0)
|
|
@@ -95,26 +104,14 @@ GEM
|
|
|
95
104
|
simplecov_json_formatter (~> 0.1)
|
|
96
105
|
simplecov-html (0.12.3)
|
|
97
106
|
simplecov_json_formatter (0.1.4)
|
|
98
|
-
standard (1.31.1)
|
|
99
|
-
language_server-protocol (~> 3.17.0.2)
|
|
100
|
-
lint_roller (~> 1.0)
|
|
101
|
-
rubocop (~> 1.56.2)
|
|
102
|
-
standard-custom (~> 1.0.0)
|
|
103
|
-
standard-performance (~> 1.2)
|
|
104
|
-
standard-custom (1.0.2)
|
|
105
|
-
lint_roller (~> 1.0)
|
|
106
|
-
rubocop (~> 1.50)
|
|
107
|
-
standard-performance (1.2.0)
|
|
108
|
-
lint_roller (~> 1.1)
|
|
109
|
-
rubocop-performance (~> 1.19.0)
|
|
110
107
|
tzinfo (2.0.6)
|
|
111
108
|
concurrent-ruby (~> 1.0)
|
|
112
|
-
unicode-display_width (2.
|
|
109
|
+
unicode-display_width (2.5.0)
|
|
113
110
|
webmock (3.19.1)
|
|
114
111
|
addressable (>= 2.8.0)
|
|
115
112
|
crack (>= 0.3.2)
|
|
116
113
|
hashdiff (>= 0.4.0, < 2.0.0)
|
|
117
|
-
zeitwerk (2.6.
|
|
114
|
+
zeitwerk (2.6.12)
|
|
118
115
|
|
|
119
116
|
PLATFORMS
|
|
120
117
|
x86_64-darwin-19
|
|
@@ -128,9 +125,9 @@ DEPENDENCIES
|
|
|
128
125
|
globus_client!
|
|
129
126
|
rake (~> 13.0)
|
|
130
127
|
rspec (~> 3.0)
|
|
128
|
+
rubocop-performance
|
|
131
129
|
rubocop-rspec
|
|
132
130
|
simplecov
|
|
133
|
-
standard
|
|
134
131
|
webmock
|
|
135
132
|
|
|
136
133
|
BUNDLED WITH
|
data/Rakefile
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
require 'rubocop/rake_task'
|
|
6
6
|
|
|
7
7
|
RSpec::Core::RakeTask.new(:spec)
|
|
8
8
|
RuboCop::RakeTask.new
|
data/api_test.rb
CHANGED
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
4
|
+
require 'benchmark'
|
|
5
|
+
require 'bundler/setup'
|
|
6
|
+
require 'globus_client'
|
|
7
7
|
|
|
8
|
-
Benchmark.bm(20) do |benchmark|
|
|
8
|
+
Benchmark.bm(20) do |benchmark| # rubocop:disable Metrics/BlockLength
|
|
9
9
|
user_id, path = *ARGV
|
|
10
10
|
|
|
11
|
-
benchmark.report(
|
|
11
|
+
benchmark.report('Configure:') do
|
|
12
12
|
GlobusClient.configure(
|
|
13
|
-
client_id: ENV
|
|
14
|
-
client_secret: ENV
|
|
15
|
-
uploads_directory: ENV
|
|
16
|
-
transfer_endpoint_id: ENV
|
|
13
|
+
client_id: ENV.fetch('GLOBUS_CLIENT_ID', nil),
|
|
14
|
+
client_secret: ENV.fetch('GLOBUS_CLIENT_SECRET', nil),
|
|
15
|
+
uploads_directory: ENV.fetch('GLOBUS_UPLOADS_DIRECTORY', nil),
|
|
16
|
+
transfer_endpoint_id: ENV.fetch('GLOBUS_ENDPOINT', nil)
|
|
17
17
|
)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
benchmark.report(
|
|
20
|
+
benchmark.report('mkdir:') do
|
|
21
21
|
GlobusClient.mkdir(user_id:, path:)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
benchmark.report(
|
|
24
|
+
benchmark.report('user_valid?:') do
|
|
25
25
|
@user_exists = GlobusClient.user_valid?(user_id)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
benchmark.report(
|
|
28
|
+
benchmark.report('before_perms:') do
|
|
29
29
|
# Not part of the public API but this allows us to test access changes
|
|
30
|
-
@before_permissions = GlobusClient::Endpoint.new(GlobusClient.instance, user_id:,
|
|
30
|
+
@before_permissions = GlobusClient::Endpoint.new(GlobusClient.instance, user_id:,
|
|
31
|
+
path:).send(:access_rule)['permissions']
|
|
31
32
|
end
|
|
32
33
|
|
|
33
|
-
benchmark.report(
|
|
34
|
+
benchmark.report('has_files?:') do
|
|
34
35
|
@has_files = GlobusClient.has_files?(user_id:, path:)
|
|
35
36
|
end
|
|
36
37
|
|
|
37
|
-
benchmark.report(
|
|
38
|
+
benchmark.report('list_files:') do
|
|
38
39
|
GlobusClient.list_files(user_id:, path:) do |files|
|
|
39
40
|
@files_count = files.count
|
|
40
41
|
@total_size = files.sum(&:size)
|
|
@@ -42,13 +43,14 @@ Benchmark.bm(20) do |benchmark|
|
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
|
|
45
|
-
benchmark.report(
|
|
46
|
+
benchmark.report('disallow_writes:') do
|
|
46
47
|
GlobusClient.disallow_writes(user_id:, path:)
|
|
47
48
|
end
|
|
48
49
|
|
|
49
|
-
benchmark.report(
|
|
50
|
+
benchmark.report('after_perms:') do
|
|
50
51
|
# Not part of the public API but this allows us to test access changes
|
|
51
|
-
@after_permissions = GlobusClient::Endpoint.new(GlobusClient.instance, user_id:,
|
|
52
|
+
@after_permissions = GlobusClient::Endpoint.new(GlobusClient.instance, user_id:,
|
|
53
|
+
path:).send(:access_rule)['permissions']
|
|
52
54
|
end
|
|
53
55
|
|
|
54
56
|
puts "User #{user_id} exists: #{@user_exists}"
|
data/globus_client.gemspec
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
lib = File.expand_path(
|
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
|
-
require
|
|
5
|
+
require 'globus_client/version'
|
|
6
6
|
|
|
7
7
|
Gem::Specification.new do |spec|
|
|
8
|
-
spec.name =
|
|
8
|
+
spec.name = 'globus_client'
|
|
9
9
|
spec.version = GlobusClient::VERSION
|
|
10
|
-
spec.authors = [
|
|
11
|
-
spec.email = [
|
|
10
|
+
spec.authors = ['Aaron Collier', 'Laura Wrubel', 'Mike Giarlo']
|
|
11
|
+
spec.email = ['aaron.collier@stanford.edu', 'lwrubel@stanford.edu', 'mjgiarlo@stanford.edu']
|
|
12
12
|
|
|
13
|
-
spec.summary =
|
|
14
|
-
spec.description =
|
|
15
|
-
spec.homepage =
|
|
16
|
-
spec.required_ruby_version =
|
|
13
|
+
spec.summary = 'Interface for interacting with the Globus API.'
|
|
14
|
+
spec.description = 'This provides API interaction with the Globus API'
|
|
15
|
+
spec.homepage = 'https://github.com/sul-dlss/globus_client'
|
|
16
|
+
spec.required_ruby_version = '>= 3.1.0'
|
|
17
17
|
|
|
18
|
-
spec.metadata[
|
|
19
|
-
spec.metadata[
|
|
20
|
-
spec.metadata[
|
|
21
|
-
spec.metadata[
|
|
18
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
|
19
|
+
spec.metadata['source_code_uri'] = 'https://github.com/sul-dlss/globus_client'
|
|
20
|
+
spec.metadata['changelog_uri'] = 'https://github.com/sul-dlss/globus_client/releases'
|
|
21
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
22
22
|
|
|
23
23
|
# Specify which files should be added to the gem when it is released.
|
|
24
24
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
@@ -27,19 +27,12 @@ Gem::Specification.new do |spec|
|
|
|
27
27
|
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
|
-
spec.bindir =
|
|
30
|
+
spec.bindir = 'exe'
|
|
31
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
32
|
-
spec.require_paths = [
|
|
32
|
+
spec.require_paths = ['lib']
|
|
33
33
|
|
|
34
|
-
spec.add_dependency
|
|
35
|
-
spec.add_dependency
|
|
36
|
-
spec.add_dependency
|
|
37
|
-
spec.add_dependency
|
|
38
|
-
|
|
39
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
|
40
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
|
41
|
-
spec.add_development_dependency "standard"
|
|
42
|
-
spec.add_development_dependency "rubocop-rspec"
|
|
43
|
-
spec.add_development_dependency "simplecov"
|
|
44
|
-
spec.add_development_dependency "webmock"
|
|
34
|
+
spec.add_dependency 'activesupport', '>= 4.2', '< 8'
|
|
35
|
+
spec.add_dependency 'faraday'
|
|
36
|
+
spec.add_dependency 'faraday-retry'
|
|
37
|
+
spec.add_dependency 'zeitwerk'
|
|
45
38
|
end
|
|
@@ -15,11 +15,11 @@ class GlobusClient
|
|
|
15
15
|
|
|
16
16
|
# Request an access_token
|
|
17
17
|
def token
|
|
18
|
-
response = connection.post(
|
|
18
|
+
response = connection.post('/v2/oauth2/token', form_data)
|
|
19
19
|
|
|
20
20
|
UnexpectedResponse.call(response) unless response.success?
|
|
21
21
|
|
|
22
|
-
JSON.parse(response.body)[
|
|
22
|
+
JSON.parse(response.body)['access_token']
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
private
|
|
@@ -34,9 +34,9 @@ class GlobusClient
|
|
|
34
34
|
{
|
|
35
35
|
client_id:,
|
|
36
36
|
client_secret:,
|
|
37
|
-
encoding:
|
|
38
|
-
grant_type:
|
|
39
|
-
scope:
|
|
37
|
+
encoding: 'form',
|
|
38
|
+
grant_type: 'client_credentials',
|
|
39
|
+
scope: 'urn:globus:auth:scope:transfer.api.globus.org:all'
|
|
40
40
|
}
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -2,18 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
class GlobusClient
|
|
4
4
|
# The namespace for endpoint API operations
|
|
5
|
-
class Endpoint
|
|
6
|
-
PATH_SEPARATOR =
|
|
5
|
+
class Endpoint # rubocop:disable Metrics/ClassLength
|
|
6
|
+
PATH_SEPARATOR = '/'
|
|
7
7
|
|
|
8
8
|
FileInfo = Struct.new(:name, :size)
|
|
9
9
|
|
|
10
10
|
# @param client [GlobusClient] a configured instance of the GlobusClient
|
|
11
11
|
# @param path [String] the path to operate on
|
|
12
12
|
# @param user_id [String] a Globus user ID (e.g., a @stanford.edu email address)
|
|
13
|
-
|
|
13
|
+
# @param notify_email [Boolean] indicates if we should ask Globus to send emails on access change (default: true)
|
|
14
|
+
def initialize(client, path:, user_id:, notify_email: true)
|
|
14
15
|
@client = client
|
|
15
16
|
@user_id = user_id
|
|
16
17
|
@path = path
|
|
18
|
+
@notify_email = notify_email
|
|
17
19
|
end
|
|
18
20
|
|
|
19
21
|
def has_files?
|
|
@@ -33,25 +35,27 @@ class GlobusClient
|
|
|
33
35
|
client.post(
|
|
34
36
|
base_url: client.config.transfer_url,
|
|
35
37
|
path: "#{transfer_path}/mkdir",
|
|
36
|
-
body: {DATA_TYPE:
|
|
37
|
-
expected_response:
|
|
38
|
+
body: { DATA_TYPE: 'mkdir', path: },
|
|
39
|
+
expected_response: lambda { |resp|
|
|
40
|
+
resp.status == 502 && JSON.parse(resp.body)['code'] == 'ExternalError.MkdirFailed.Exists'
|
|
41
|
+
}
|
|
38
42
|
)
|
|
39
43
|
end
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
# Assign a user read/write permissions for a directory https://docs.globus.org/api/transfer/acl/#rest_access_create
|
|
43
47
|
def allow_writes
|
|
44
|
-
access_request(permissions:
|
|
48
|
+
access_request(permissions: 'rw')
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
# Assign a user read-only permissions for a directory https://docs.globus.org/api/transfer/acl/#rest_access_create
|
|
48
52
|
def disallow_writes
|
|
49
|
-
update_access_request(permissions:
|
|
53
|
+
update_access_request(permissions: 'r')
|
|
50
54
|
end
|
|
51
55
|
|
|
52
56
|
# Delete the access rule https://docs.globus.org/api/transfer/acl/#delete_access_rule
|
|
53
57
|
def delete_access_rule
|
|
54
|
-
raise(StandardError, "Access rule not found for #{path}")
|
|
58
|
+
raise(StandardError, "Access rule not found for #{path}") unless access_rule_id
|
|
55
59
|
|
|
56
60
|
client.delete(
|
|
57
61
|
base_url: client.config.transfer_url,
|
|
@@ -61,7 +65,7 @@ class GlobusClient
|
|
|
61
65
|
|
|
62
66
|
private
|
|
63
67
|
|
|
64
|
-
attr_reader :client, :path, :user_id
|
|
68
|
+
attr_reader :client, :path, :user_id, :notify_email
|
|
65
69
|
|
|
66
70
|
def globus_identity_id
|
|
67
71
|
Identity.new(client).get_identity_id(user_id)
|
|
@@ -98,24 +102,24 @@ class GlobusClient
|
|
|
98
102
|
response = client.get(
|
|
99
103
|
base_url: client.config.transfer_url,
|
|
100
104
|
path: "#{transfer_path}/ls",
|
|
101
|
-
params: {path: filepath}
|
|
105
|
+
params: { path: filepath }
|
|
102
106
|
)
|
|
103
107
|
|
|
104
|
-
response[
|
|
105
|
-
.select { |object| object[
|
|
108
|
+
response['DATA']
|
|
109
|
+
.select { |object| object['type'] == 'file' }
|
|
106
110
|
.each do |file|
|
|
107
111
|
return true if return_presence
|
|
108
112
|
|
|
109
|
-
files << FileInfo.new("#{filepath}#{file[
|
|
113
|
+
files << FileInfo.new("#{filepath}#{file['name']}", file['size'])
|
|
110
114
|
end
|
|
111
115
|
|
|
112
|
-
response[
|
|
113
|
-
.select { |object| object[
|
|
116
|
+
response['DATA']
|
|
117
|
+
.select { |object| object['type'] == 'dir' }
|
|
114
118
|
.each do |dir|
|
|
115
119
|
# NOTE: This allows the recursive method to short-circuit iff ls_path
|
|
116
120
|
# returns true, which only happens when return_presence is true
|
|
117
121
|
# and the first file is found in the ls operation.
|
|
118
|
-
return true if ls_path("#{filepath}#{dir[
|
|
122
|
+
return true if ls_path("#{filepath}#{dir['name']}/", files, return_presence:) == true
|
|
119
123
|
end
|
|
120
124
|
|
|
121
125
|
return false if return_presence
|
|
@@ -127,29 +131,30 @@ class GlobusClient
|
|
|
127
131
|
if access_rule_id
|
|
128
132
|
update_access_request(permissions:)
|
|
129
133
|
else
|
|
134
|
+
body = {
|
|
135
|
+
DATA_TYPE: 'access',
|
|
136
|
+
principal_type: 'identity',
|
|
137
|
+
principal: globus_identity_id,
|
|
138
|
+
path: full_path,
|
|
139
|
+
permissions:
|
|
140
|
+
}
|
|
141
|
+
body[:notify_email] = user_id if notify_email
|
|
130
142
|
client.post(
|
|
131
143
|
base_url: client.config.transfer_url,
|
|
132
144
|
path: access_path,
|
|
133
|
-
body:
|
|
134
|
-
DATA_TYPE: "access",
|
|
135
|
-
principal_type: "identity",
|
|
136
|
-
principal: globus_identity_id,
|
|
137
|
-
path: full_path,
|
|
138
|
-
permissions:,
|
|
139
|
-
notify_email: user_id
|
|
140
|
-
}
|
|
145
|
+
body:
|
|
141
146
|
)
|
|
142
147
|
end
|
|
143
148
|
end
|
|
144
149
|
|
|
145
150
|
def update_access_request(permissions:)
|
|
146
|
-
raise(StandardError, "Access rule not found for #{path}")
|
|
151
|
+
raise(StandardError, "Access rule not found for #{path}") unless access_rule_id
|
|
147
152
|
|
|
148
153
|
client.put(
|
|
149
154
|
base_url: client.config.transfer_url,
|
|
150
155
|
path: "#{access_path}/#{access_rule_id}",
|
|
151
156
|
body: {
|
|
152
|
-
DATA_TYPE:
|
|
157
|
+
DATA_TYPE: 'access',
|
|
153
158
|
permissions:
|
|
154
159
|
}
|
|
155
160
|
)
|
|
@@ -159,14 +164,14 @@ class GlobusClient
|
|
|
159
164
|
response = client.get(
|
|
160
165
|
base_url: client.config.transfer_url,
|
|
161
166
|
path: access_list_path,
|
|
162
|
-
content_type:
|
|
167
|
+
content_type: 'application/json'
|
|
163
168
|
)
|
|
164
169
|
|
|
165
|
-
response.fetch(
|
|
170
|
+
response.fetch('DATA').find { |acl| acl['path'] == full_path }
|
|
166
171
|
end
|
|
167
172
|
|
|
168
173
|
def access_rule_id
|
|
169
|
-
access_rule&.fetch(
|
|
174
|
+
access_rule&.fetch('id')
|
|
170
175
|
end
|
|
171
176
|
|
|
172
177
|
def transfer_path
|
|
@@ -12,23 +12,23 @@ class GlobusClient
|
|
|
12
12
|
def get_identity(user_id)
|
|
13
13
|
response = client.get(
|
|
14
14
|
base_url: client.config.auth_url,
|
|
15
|
-
path:
|
|
16
|
-
params: {usernames: user_id}
|
|
15
|
+
path: '/v2/api/identities',
|
|
16
|
+
params: { usernames: user_id }
|
|
17
17
|
)
|
|
18
18
|
|
|
19
|
-
response[
|
|
19
|
+
response['identities'].find { |id| id['username'] == user_id }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# @param user_id [String] the username in the form of an email addresss
|
|
23
23
|
# @return [Boolean] whether the account has a valid status
|
|
24
24
|
def valid?(user_id)
|
|
25
|
-
[
|
|
25
|
+
%w[used private unused].include?(get_identity(user_id)['status'])
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# @param user_id [String] the username in the form of an email addresss
|
|
29
29
|
# @return [String] UUID for Globus identity
|
|
30
30
|
def get_identity_id(user_id)
|
|
31
|
-
get_identity(user_id)[
|
|
31
|
+
get_identity(user_id)['id']
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
private
|
|
@@ -39,7 +39,7 @@ class GlobusClient
|
|
|
39
39
|
when 502
|
|
40
40
|
raise EndpointError, "Other error with endpoint: #{response.status} #{response.body}."
|
|
41
41
|
when 503
|
|
42
|
-
raise ServiceUnavailable,
|
|
42
|
+
raise ServiceUnavailable, 'The service is down for maintenance.'
|
|
43
43
|
else
|
|
44
44
|
raise StandardError, "Unexpected response: #{response.status} #{response.body}."
|
|
45
45
|
end
|
data/lib/globus_client.rb
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
7
|
-
require
|
|
8
|
-
require
|
|
9
|
-
require "zeitwerk"
|
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
|
4
|
+
require 'active_support/core_ext/object/blank'
|
|
5
|
+
require 'faraday'
|
|
6
|
+
require 'faraday/retry'
|
|
7
|
+
require 'singleton'
|
|
8
|
+
require 'zeitwerk'
|
|
10
9
|
|
|
11
10
|
# Load the gem's internal dependencies: use Zeitwerk instead of needing to manually require classes
|
|
12
11
|
Zeitwerk::Loader.for_gem.setup
|
|
13
12
|
|
|
14
13
|
# Client for interacting with the Globus API
|
|
15
|
-
class GlobusClient
|
|
14
|
+
class GlobusClient # rubocop:disable Metrics/ClassLength
|
|
16
15
|
include Singleton
|
|
17
16
|
|
|
18
17
|
class << self
|
|
@@ -22,8 +21,10 @@ class GlobusClient
|
|
|
22
21
|
# @param transfer_endpoint_id [String] the transfer API endpoint ID supplied by Globus
|
|
23
22
|
# @param transfer_url [String] the transfer API URL
|
|
24
23
|
# @param auth_url [String] the authentication API URL
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
# rubocop:disable Metrics/ParameterLists
|
|
25
|
+
def configure(client_id:, client_secret:, uploads_directory:, transfer_endpoint_id:,
|
|
26
|
+
transfer_url: default_transfer_url, auth_url: default_auth_url)
|
|
27
|
+
instance.config = Config.new(
|
|
27
28
|
# For the initial token, use a dummy value to avoid hitting any APIs
|
|
28
29
|
# during configuration, allowing `with_token_refresh_when_unauthorized` to handle
|
|
29
30
|
# auto-magic token refreshing. Why not immediately get a valid token? Our apps
|
|
@@ -34,7 +35,7 @@ class GlobusClient
|
|
|
34
35
|
# NOTE: `nil` and blank string cannot be used as dummy values here as
|
|
35
36
|
# they lead to a malformed request to be sent, which triggers an
|
|
36
37
|
# exception not rescued by `with_token_refresh_when_unauthorized`
|
|
37
|
-
token:
|
|
38
|
+
token: 'a temporary dummy token to avoid hitting the API before it is needed',
|
|
38
39
|
client_id:,
|
|
39
40
|
client_secret:,
|
|
40
41
|
uploads_directory:,
|
|
@@ -45,16 +46,17 @@ class GlobusClient
|
|
|
45
46
|
|
|
46
47
|
self
|
|
47
48
|
end
|
|
49
|
+
# rubocop:enable Metrics/ParameterLists
|
|
48
50
|
|
|
49
51
|
delegate :config, :disallow_writes, :delete_access_rule, :file_count, :list_files, :mkdir, :total_size,
|
|
50
|
-
|
|
52
|
+
:user_valid?, :get_filenames, :has_files?, :delete, :get, :post, :put, to: :instance
|
|
51
53
|
|
|
52
54
|
def default_transfer_url
|
|
53
|
-
|
|
55
|
+
'https://transfer.api.globusonline.org'
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
def default_auth_url
|
|
57
|
-
|
|
59
|
+
'https://auth.globus.org'
|
|
58
60
|
end
|
|
59
61
|
end
|
|
60
62
|
|
|
@@ -67,8 +69,8 @@ class GlobusClient
|
|
|
67
69
|
def get(base_url:, path:, params: {}, content_type: nil)
|
|
68
70
|
response = with_token_refresh_when_unauthorized do
|
|
69
71
|
connection(base_url).get(path, params) do |request|
|
|
70
|
-
request.headers[
|
|
71
|
-
request.headers[
|
|
72
|
+
request.headers['Authorization'] = "Bearer #{config.token}"
|
|
73
|
+
request.headers['Content-Type'] = content_type if content_type
|
|
72
74
|
end
|
|
73
75
|
end
|
|
74
76
|
|
|
@@ -84,11 +86,11 @@ class GlobusClient
|
|
|
84
86
|
# @param path [String] the path to the Globus API request
|
|
85
87
|
# @param body [String] the body of the Globus API request
|
|
86
88
|
# @param expected_response [#call] an expected response handler to allow short-circuiting the unexpected response
|
|
87
|
-
def post(base_url:, path:, body:, expected_response: ->(
|
|
89
|
+
def post(base_url:, path:, body:, expected_response: ->(_resp) { false })
|
|
88
90
|
response = with_token_refresh_when_unauthorized do
|
|
89
91
|
connection(base_url).post(path) do |request|
|
|
90
|
-
request.headers[
|
|
91
|
-
request.headers[
|
|
92
|
+
request.headers['Authorization'] = "Bearer #{config.token}"
|
|
93
|
+
request.headers['Content-Type'] = 'application/json'
|
|
92
94
|
request.body = body.to_json
|
|
93
95
|
end
|
|
94
96
|
end
|
|
@@ -107,8 +109,8 @@ class GlobusClient
|
|
|
107
109
|
def put(base_url:, path:, body:)
|
|
108
110
|
response = with_token_refresh_when_unauthorized do
|
|
109
111
|
connection(base_url).put(path) do |request|
|
|
110
|
-
request.headers[
|
|
111
|
-
request.headers[
|
|
112
|
+
request.headers['Authorization'] = "Bearer #{config.token}"
|
|
113
|
+
request.headers['Content-Type'] = 'application/json'
|
|
112
114
|
request.body = body.to_json
|
|
113
115
|
end
|
|
114
116
|
end
|
|
@@ -126,7 +128,7 @@ class GlobusClient
|
|
|
126
128
|
def delete(base_url:, path:)
|
|
127
129
|
response = with_token_refresh_when_unauthorized do
|
|
128
130
|
connection(base_url).delete(path) do |request|
|
|
129
|
-
request.headers[
|
|
131
|
+
request.headers['Authorization'] = "Bearer #{config.token}"
|
|
130
132
|
end
|
|
131
133
|
end
|
|
132
134
|
|
|
@@ -159,10 +161,10 @@ class GlobusClient
|
|
|
159
161
|
# NOTE: Can't use the `...` (argument forwarding) operator here because we
|
|
160
162
|
# want to route the keyword args to `Endpoint#new` and the block arg to
|
|
161
163
|
# `Endpoint#list_files`
|
|
162
|
-
def list_files(**keywords, &
|
|
164
|
+
def list_files(**keywords, &)
|
|
163
165
|
Endpoint
|
|
164
166
|
.new(self, **keywords)
|
|
165
|
-
.list_files(&
|
|
167
|
+
.list_files(&)
|
|
166
168
|
end
|
|
167
169
|
|
|
168
170
|
def file_count(...)
|
|
@@ -197,6 +199,8 @@ class GlobusClient
|
|
|
197
199
|
|
|
198
200
|
private
|
|
199
201
|
|
|
202
|
+
Config = Struct.new(:client_id, :auth_url, :client_secret, :transfer_endpoint_id, :transfer_url, :uploads_directory, :token, keyword_init: true)
|
|
203
|
+
|
|
200
204
|
def connection(base_url)
|
|
201
205
|
Faraday.new(url: base_url) do |conn|
|
|
202
206
|
conn.request :retry, {
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: globus_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.14.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aaron Collier
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: exe
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2023-
|
|
13
|
+
date: 2023-10-11 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: activesupport
|
|
@@ -74,90 +74,6 @@ dependencies:
|
|
|
74
74
|
- - ">="
|
|
75
75
|
- !ruby/object:Gem::Version
|
|
76
76
|
version: '0'
|
|
77
|
-
- !ruby/object:Gem::Dependency
|
|
78
|
-
name: rake
|
|
79
|
-
requirement: !ruby/object:Gem::Requirement
|
|
80
|
-
requirements:
|
|
81
|
-
- - "~>"
|
|
82
|
-
- !ruby/object:Gem::Version
|
|
83
|
-
version: '13.0'
|
|
84
|
-
type: :development
|
|
85
|
-
prerelease: false
|
|
86
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
87
|
-
requirements:
|
|
88
|
-
- - "~>"
|
|
89
|
-
- !ruby/object:Gem::Version
|
|
90
|
-
version: '13.0'
|
|
91
|
-
- !ruby/object:Gem::Dependency
|
|
92
|
-
name: rspec
|
|
93
|
-
requirement: !ruby/object:Gem::Requirement
|
|
94
|
-
requirements:
|
|
95
|
-
- - "~>"
|
|
96
|
-
- !ruby/object:Gem::Version
|
|
97
|
-
version: '3.0'
|
|
98
|
-
type: :development
|
|
99
|
-
prerelease: false
|
|
100
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
101
|
-
requirements:
|
|
102
|
-
- - "~>"
|
|
103
|
-
- !ruby/object:Gem::Version
|
|
104
|
-
version: '3.0'
|
|
105
|
-
- !ruby/object:Gem::Dependency
|
|
106
|
-
name: standard
|
|
107
|
-
requirement: !ruby/object:Gem::Requirement
|
|
108
|
-
requirements:
|
|
109
|
-
- - ">="
|
|
110
|
-
- !ruby/object:Gem::Version
|
|
111
|
-
version: '0'
|
|
112
|
-
type: :development
|
|
113
|
-
prerelease: false
|
|
114
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
115
|
-
requirements:
|
|
116
|
-
- - ">="
|
|
117
|
-
- !ruby/object:Gem::Version
|
|
118
|
-
version: '0'
|
|
119
|
-
- !ruby/object:Gem::Dependency
|
|
120
|
-
name: rubocop-rspec
|
|
121
|
-
requirement: !ruby/object:Gem::Requirement
|
|
122
|
-
requirements:
|
|
123
|
-
- - ">="
|
|
124
|
-
- !ruby/object:Gem::Version
|
|
125
|
-
version: '0'
|
|
126
|
-
type: :development
|
|
127
|
-
prerelease: false
|
|
128
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
129
|
-
requirements:
|
|
130
|
-
- - ">="
|
|
131
|
-
- !ruby/object:Gem::Version
|
|
132
|
-
version: '0'
|
|
133
|
-
- !ruby/object:Gem::Dependency
|
|
134
|
-
name: simplecov
|
|
135
|
-
requirement: !ruby/object:Gem::Requirement
|
|
136
|
-
requirements:
|
|
137
|
-
- - ">="
|
|
138
|
-
- !ruby/object:Gem::Version
|
|
139
|
-
version: '0'
|
|
140
|
-
type: :development
|
|
141
|
-
prerelease: false
|
|
142
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
143
|
-
requirements:
|
|
144
|
-
- - ">="
|
|
145
|
-
- !ruby/object:Gem::Version
|
|
146
|
-
version: '0'
|
|
147
|
-
- !ruby/object:Gem::Dependency
|
|
148
|
-
name: webmock
|
|
149
|
-
requirement: !ruby/object:Gem::Requirement
|
|
150
|
-
requirements:
|
|
151
|
-
- - ">="
|
|
152
|
-
- !ruby/object:Gem::Version
|
|
153
|
-
version: '0'
|
|
154
|
-
type: :development
|
|
155
|
-
prerelease: false
|
|
156
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
157
|
-
requirements:
|
|
158
|
-
- - ">="
|
|
159
|
-
- !ruby/object:Gem::Version
|
|
160
|
-
version: '0'
|
|
161
77
|
description: This provides API interaction with the Globus API
|
|
162
78
|
email:
|
|
163
79
|
- aaron.collier@stanford.edu
|
|
@@ -167,11 +83,9 @@ executables: []
|
|
|
167
83
|
extensions: []
|
|
168
84
|
extra_rdoc_files: []
|
|
169
85
|
files:
|
|
170
|
-
- ".autoupdate/postupdate"
|
|
171
86
|
- ".rspec"
|
|
172
87
|
- ".rubocop.yml"
|
|
173
|
-
- ".
|
|
174
|
-
- ".standard.yml"
|
|
88
|
+
- ".rubocop_todo.yml"
|
|
175
89
|
- Gemfile
|
|
176
90
|
- Gemfile.lock
|
|
177
91
|
- LICENSE
|
|
@@ -200,14 +114,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
200
114
|
requirements:
|
|
201
115
|
- - ">="
|
|
202
116
|
- !ruby/object:Gem::Version
|
|
203
|
-
version:
|
|
117
|
+
version: 3.1.0
|
|
204
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
119
|
requirements:
|
|
206
120
|
- - ">="
|
|
207
121
|
- !ruby/object:Gem::Version
|
|
208
122
|
version: '0'
|
|
209
123
|
requirements: []
|
|
210
|
-
rubygems_version: 3.4.
|
|
124
|
+
rubygems_version: 3.4.13
|
|
211
125
|
signing_key:
|
|
212
126
|
specification_version: 4
|
|
213
127
|
summary: Interface for interacting with the Globus API.
|
data/.autoupdate/postupdate
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/bin/bash --login
|
|
2
|
-
|
|
3
|
-
# This script is called by our weekly dependency update job in Jenkins after updating Ruby and other deps
|
|
4
|
-
|
|
5
|
-
# Switch to Ruby 3.1 for GlobusClient (3.0 is default in Jenkinsfile)
|
|
6
|
-
rvm use 3.1.2@globus_client --create &&
|
|
7
|
-
gem install bundler &&
|
|
8
|
-
bundle install --gemfile Gemfile
|
|
9
|
-
|
|
10
|
-
standardrb --fix > globus_client_standard.txt
|
|
11
|
-
|
|
12
|
-
retVal=$?
|
|
13
|
-
|
|
14
|
-
git commit -am "Update to latest standard style guide"
|
|
15
|
-
|
|
16
|
-
if [ $retVal -ne 0 ]; then
|
|
17
|
-
echo "ERROR UPDATING RUBY TO STANDARD STYLE (globus_client)"
|
|
18
|
-
cat globus_client_standard.txt
|
|
19
|
-
fi
|
data/.rubocop/custom.yml
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
AllCops:
|
|
2
|
-
TargetRubyVersion: 3.1
|
|
3
|
-
DisplayCopNames: true
|
|
4
|
-
SuggestExtensions: false
|
|
5
|
-
Exclude:
|
|
6
|
-
- bin/**
|
|
7
|
-
- vendor/bundle/**/*
|
|
8
|
-
|
|
9
|
-
# Per team developer playbook
|
|
10
|
-
RSpec/MultipleMemoizedHelpers:
|
|
11
|
-
Enabled: false
|
|
12
|
-
|
|
13
|
-
RSpec/BeEq: # new in 2.9.0
|
|
14
|
-
Enabled: true
|
|
15
|
-
RSpec/BeNil: # new in 2.9.0
|
|
16
|
-
Enabled: true
|
|
17
|
-
RSpec/ChangeByZero: # new in 2.11
|
|
18
|
-
Enabled: true
|
|
19
|
-
RSpec/ClassCheck: # new in 2.13
|
|
20
|
-
Enabled: true
|
|
21
|
-
RSpec/ExcessiveDocstringSpacing: # new in 2.5
|
|
22
|
-
Enabled: true
|
|
23
|
-
RSpec/IdenticalEqualityAssertion: # new in 2.4
|
|
24
|
-
Enabled: true
|
|
25
|
-
RSpec/NoExpectationExample: # new in 2.13
|
|
26
|
-
Enabled: true
|
|
27
|
-
RSpec/SortMetadata: # new in 2.14
|
|
28
|
-
Enabled: true
|
|
29
|
-
RSpec/SubjectDeclaration: # new in 2.5
|
|
30
|
-
Enabled: true
|
|
31
|
-
RSpec/VerifiedDoubleReference: # new in 2.10.0
|
|
32
|
-
Enabled: true
|
|
33
|
-
Capybara/NegationMatcher: # new in 2.14
|
|
34
|
-
Enabled: true
|
|
35
|
-
Capybara/SpecificActions: # new in 2.14
|
|
36
|
-
Enabled: true
|
|
37
|
-
Capybara/SpecificFinders: # new in 2.13
|
|
38
|
-
Enabled: true
|
|
39
|
-
Capybara/SpecificMatcher: # new in 2.12
|
|
40
|
-
Enabled: true
|
|
41
|
-
FactoryBot/ConsistentParenthesesStyle: # new in 2.14
|
|
42
|
-
Enabled: true
|
|
43
|
-
FactoryBot/SyntaxMethods: # new in 2.7
|
|
44
|
-
Enabled: true
|
|
45
|
-
RSpec/Rails/AvoidSetupHook: # new in 2.4
|
|
46
|
-
Enabled: true
|
|
47
|
-
RSpec/Rails/HaveHttpStatus: # new in 2.12
|
|
48
|
-
Enabled: true
|
|
49
|
-
RSpec/Rails/InferredSpecType: # new in 2.14
|
|
50
|
-
Enabled: true
|
|
51
|
-
Capybara/MatchStyle: # new in 2.17
|
|
52
|
-
Enabled: true
|
|
53
|
-
FactoryBot/AssociationStyle: # new in 2.23
|
|
54
|
-
Enabled: true
|
|
55
|
-
FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
|
|
56
|
-
Enabled: true
|
|
57
|
-
FactoryBot/FactoryNameStyle: # new in 2.16
|
|
58
|
-
Enabled: true
|
|
59
|
-
FactoryBot/RedundantFactoryOption: # new in 2.23
|
|
60
|
-
Enabled: true
|
|
61
|
-
RSpec/BeEmpty: # new in 2.20
|
|
62
|
-
Enabled: true
|
|
63
|
-
RSpec/ContainExactly: # new in 2.19
|
|
64
|
-
Enabled: true
|
|
65
|
-
RSpec/DuplicatedMetadata: # new in 2.16
|
|
66
|
-
Enabled: true
|
|
67
|
-
RSpec/IndexedLet: # new in 2.20
|
|
68
|
-
Enabled: false # Sometimes indices *are* meaningful
|
|
69
|
-
RSpec/MatchArray: # new in 2.19
|
|
70
|
-
Enabled: true
|
|
71
|
-
RSpec/PendingWithoutReason: # new in 2.16
|
|
72
|
-
Enabled: true
|
|
73
|
-
RSpec/RedundantAround: # new in 2.19
|
|
74
|
-
Enabled: true
|
|
75
|
-
RSpec/SkipBlockInsideExample: # new in 2.19
|
|
76
|
-
Enabled: true
|
|
77
|
-
RSpec/Rails/MinitestAssertions: # new in 2.17
|
|
78
|
-
Enabled: true
|
|
79
|
-
RSpec/Rails/TravelAround: # new in 2.19
|
|
80
|
-
Enabled: true
|
data/.standard.yml
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
parallel: true
|