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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9129e55c5e5e6f4f62fc0d8912eca9310eff036e1c0095d24cae07367947054c
4
- data.tar.gz: 1265f2f6c1b68bb6d76634f7bd636ed920b1095fd3bfd5ab6702525d994bf295
3
+ metadata.gz: bae9be2599dca47133561cc9f50d02118d633e973f973619bf642a890d266d7d
4
+ data.tar.gz: 032a19fb8edf3b11740dd487415a98f14522daac3ae4966302376b902c787e01
5
5
  SHA512:
6
- metadata.gz: 407e55c907f990f0492898e636525c8238221167fabf6d0b4bccef0c9eb163f0d75b5bb3b05b58130be46bb823b809a524490f762cbd5b3c56143e2abf9fd7c4
7
- data.tar.gz: e7300d3adbaa6b75d43cafe1faae5eccfc212f558ce7d38889438d3ceaac99becc55242d2a10f2ec3eba759d2038649fe2b80585e97cba4e58ebd215b4767594
6
+ metadata.gz: f66705c5adbda9f69f8ab99b8c02ad8b16dafcf4760b0918f63191874066691c1c46211588a197629206f6e53f72b1893748bcac04594db44afeaa1f3a40706a
7
+ data.tar.gz: f901d249a7b112efb537e88387aa6833759f2ec6f801277d4970a0830d7761abfe64e8a4163337ce252e2b9beb4e46410757832ecc300f649d8e21a5a6381669
data/.rubocop.yml CHANGED
@@ -1,18 +1,27 @@
1
- inherit_mode:
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
- inherit_gem:
13
- standard: config/base.yml
14
- standard-performance: config/base.yml
15
- standard-custom: config/base.yml
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
- inherit_from:
18
- - .rubocop/custom.yml
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 "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  # Specify your gem's dependencies in globus_client.gemspec
6
6
  gemspec
7
7
 
8
- gem "byebug"
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.13.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.8)
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.3)
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.3)
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.4.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.11)
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 "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
- require "rubocop/rake_task"
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 "benchmark"
5
- require "bundler/setup"
6
- require "globus_client"
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("Configure:") do
11
+ benchmark.report('Configure:') do
12
12
  GlobusClient.configure(
13
- client_id: ENV["GLOBUS_CLIENT_ID"],
14
- client_secret: ENV["GLOBUS_CLIENT_SECRET"],
15
- uploads_directory: ENV["GLOBUS_UPLOADS_DIRECTORY"],
16
- transfer_endpoint_id: ENV["GLOBUS_ENDPOINT"]
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("mkdir:") do
20
+ benchmark.report('mkdir:') do
21
21
  GlobusClient.mkdir(user_id:, path:)
22
22
  end
23
23
 
24
- benchmark.report("user_valid?:") do
24
+ benchmark.report('user_valid?:') do
25
25
  @user_exists = GlobusClient.user_valid?(user_id)
26
26
  end
27
27
 
28
- benchmark.report("before_perms:") do
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:, path:).send(:access_rule)["permissions"]
30
+ @before_permissions = GlobusClient::Endpoint.new(GlobusClient.instance, user_id:,
31
+ path:).send(:access_rule)['permissions']
31
32
  end
32
33
 
33
- benchmark.report("has_files?:") do
34
+ benchmark.report('has_files?:') do
34
35
  @has_files = GlobusClient.has_files?(user_id:, path:)
35
36
  end
36
37
 
37
- benchmark.report("list_files:") do
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("disallow_writes:") do
46
+ benchmark.report('disallow_writes:') do
46
47
  GlobusClient.disallow_writes(user_id:, path:)
47
48
  end
48
49
 
49
- benchmark.report("after_perms:") do
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:, path:).send(:access_rule)["permissions"]
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}"
@@ -1,24 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path("lib", __dir__)
3
+ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "globus_client/version"
5
+ require 'globus_client/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = "globus_client"
8
+ spec.name = 'globus_client'
9
9
  spec.version = GlobusClient::VERSION
10
- spec.authors = ["Aaron Collier", "Laura Wrubel", "Mike Giarlo"]
11
- spec.email = ["aaron.collier@stanford.edu", "lwrubel@stanford.edu", "mjgiarlo@stanford.edu"]
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 = "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 = ">= 2.6.0"
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["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"
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 = "exe"
30
+ spec.bindir = 'exe'
31
31
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
32
- spec.require_paths = ["lib"]
32
+ spec.require_paths = ['lib']
33
33
 
34
- spec.add_dependency "activesupport", ">= 4.2", "< 8"
35
- spec.add_dependency "faraday"
36
- spec.add_dependency "faraday-retry"
37
- spec.add_dependency "zeitwerk"
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("/v2/oauth2/token", form_data)
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)["access_token"]
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: "form",
38
- grant_type: "client_credentials",
39
- scope: "urn:globus:auth:scope:transfer.api.globus.org:all"
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
- def initialize(client, path:, user_id:)
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: "mkdir", path:},
37
- expected_response: ->(resp) { resp.status == 502 && JSON.parse(resp.body)["code"] == "ExternalError.MkdirFailed.Exists" }
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: "rw")
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: "r")
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}") if !access_rule_id
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["DATA"]
105
- .select { |object| object["type"] == "file" }
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["name"]}", file["size"])
113
+ files << FileInfo.new("#{filepath}#{file['name']}", file['size'])
110
114
  end
111
115
 
112
- response["DATA"]
113
- .select { |object| object["type"] == "dir" }
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["name"]}/", files, return_presence:) == true
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}") if !access_rule_id
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: "access",
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: "application/json"
167
+ content_type: 'application/json'
163
168
  )
164
169
 
165
- response.fetch("DATA").find { |acl| acl["path"] == full_path }
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("id")
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: "/v2/api/identities",
16
- params: {usernames: user_id}
15
+ path: '/v2/api/identities',
16
+ params: { usernames: user_id }
17
17
  )
18
18
 
19
- response["identities"].find { |id| id["username"] == user_id }
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
- ["used", "private", "unused"].include?(get_identity(user_id)["status"])
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)["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, "The service is down for maintenance."
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class GlobusClient
4
- VERSION = "0.13.0"
4
+ VERSION = '0.14.0'
5
5
  end
data/lib/globus_client.rb CHANGED
@@ -1,18 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
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 "ostruct"
8
- require "singleton"
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
- def configure(client_id:, client_secret:, uploads_directory:, transfer_endpoint_id:, transfer_url: default_transfer_url, auth_url: default_auth_url)
26
- instance.config = OpenStruct.new(
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: "a temporary dummy token to avoid hitting the API before it is needed",
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
- :user_valid?, :get_filenames, :has_files?, :delete, :get, :post, :put, to: :instance
52
+ :user_valid?, :get_filenames, :has_files?, :delete, :get, :post, :put, to: :instance
51
53
 
52
54
  def default_transfer_url
53
- "https://transfer.api.globusonline.org"
55
+ 'https://transfer.api.globusonline.org'
54
56
  end
55
57
 
56
58
  def default_auth_url
57
- "https://auth.globus.org"
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["Authorization"] = "Bearer #{config.token}"
71
- request.headers["Content-Type"] = content_type if content_type
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: ->(resp) { false })
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["Authorization"] = "Bearer #{config.token}"
91
- request.headers["Content-Type"] = "application/json"
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["Authorization"] = "Bearer #{config.token}"
111
- request.headers["Content-Type"] = "application/json"
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["Authorization"] = "Bearer #{config.token}"
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, &block)
164
+ def list_files(**keywords, &)
163
165
  Endpoint
164
166
  .new(self, **keywords)
165
- .list_files(&block)
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.13.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-09-27 00:00:00.000000000 Z
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
- - ".rubocop/custom.yml"
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: 2.6.0
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.19
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.
@@ -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