archivesspace-client 0.1.8 → 0.1.12

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: 6ea50bb167b4debf8781434efa1ff7b06d077a8ab869f02c30ea8d1cd66de3c9
4
- data.tar.gz: 83f63ad1f11fc35ca89cdabe871a1e1fa91f935e2e6e284f038b6db2c0257065
3
+ metadata.gz: c009f995726401b9fd781b18796903276b19c2aabb3d6ec8722d60a36ea86600
4
+ data.tar.gz: 3985545e091850851567ebc1706252da34922120222dd491ca7ae58928e30b19
5
5
  SHA512:
6
- metadata.gz: faa0086ae6ecd33700e3cf16c41b7457ebf094eb4a5e79109c3999ce0e916f8924450cb6ef8bcb4a761f0d6ed3a1c12a457dec4cd5738429a8f80fb249303fbe
7
- data.tar.gz: '09a6fca39d7846875715216e8b10d5d29b776b433c37abef3490b5964e62deca9de5f01e69f868a476cceb11c7ceaa43032cfb906f9fff35da10b43e0b3582e7'
6
+ metadata.gz: ef5a03e03271cb24133b3f82e2304162a5ede929453bb4af99edc8f011f260f204b390960b30ed691bd569af15813f0a0ee9e8063d4599d78e69eb833aad5b17
7
+ data.tar.gz: ef541e1ebd699335e4333d195a7ac3e5a554b96543c2f1432e26c056751d584b7a7f1db0c4c0369cbc881e9c6b626286414103b728f778b69a81af1511678eb9
@@ -0,0 +1,22 @@
1
+ name: CI
2
+ on: [pull_request]
3
+
4
+ # TODO: add linters (rubocop)
5
+
6
+ jobs:
7
+ tests:
8
+ name: Tests
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Checkout code
12
+ uses: actions/checkout@v3
13
+
14
+ - name: Setup Ruby and install gems
15
+ uses: ruby/setup-ruby@v1
16
+ with:
17
+ bundler-cache: true
18
+ ruby-version: 2.7
19
+
20
+ - name: Run tests
21
+ run: |
22
+ bundle exec rake
@@ -0,0 +1,42 @@
1
+ name: Publish Gem
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - master
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write
13
+
14
+ steps:
15
+ - uses: actions/checkout@v3
16
+
17
+ - name: Setup Ruby and install gems
18
+ uses: ruby/setup-ruby@v1
19
+ with:
20
+ bundler-cache: true
21
+ ruby-version: 2.7
22
+ rubygems: latest
23
+
24
+ - name: Release Gem
25
+ run: |
26
+ VERSION=$(ruby -e "puts eval(File.read('$GEM_NAME.gemspec')).version")
27
+ GEM_VERSION=$(gem list --exact --remote $GEM_NAME)
28
+
29
+ # Publish to RubyGems.org
30
+ if [ "${GEM_VERSION}" != "$GEM_NAME (${VERSION})" ]; then
31
+ gem build $GEM_NAME.gemspec
32
+ gem push "$GEM_NAME-${VERSION}.gem"
33
+ fi
34
+
35
+ # Create a release tag
36
+ if ! git ls-remote --tags --exit-code origin v${VERSION}; then
37
+ git tag v${VERSION}
38
+ git push --tags
39
+ fi
40
+ env:
41
+ GEM_HOST_API_KEY: "${{ secrets.RUBYGEMS_AUTH_TOKEN }}"
42
+ GEM_NAME: archivesspace-client
data/README.md CHANGED
@@ -77,14 +77,16 @@ See `helpers.rb` for more convenience methods such as `client.digital_objects` e
77
77
 
78
78
  **Setting a repository context**
79
79
 
80
- Update the `base_repo` configuration value to add a repository scope to requests (this is optional).
80
+ Use the `repository` method to add a repository scope to requests (this is optional).
81
81
 
82
82
  ```ruby
83
- client.config.base_repo = "repositories/2"
84
- client.get('digital_objects') # instead of "repositories/2/digital_objects" etc.
83
+ client.repository(2)
84
+ client.get('digital_objects', query: {page: 1}) # instead of "repositories/2/digital_objects" etc.
85
85
 
86
86
  # to reset
87
- client.config.base_repo = ""
87
+ client.repository(nil)
88
+ # or
89
+ client.use_global_repository
88
90
  ```
89
91
 
90
92
  ## Templates
@@ -116,6 +118,29 @@ response = client.post('/repositories/with_agent', json)
116
118
  puts response.result.success? ? '=)' : '=('
117
119
  ```
118
120
 
121
+ ## CLI
122
+
123
+ Create an `~/.asclientrc` file with a json version of the client configuration:
124
+
125
+ ```json
126
+ {
127
+ "base_uri": "https://archives.university.edu/api",
128
+ "base_repo": "",
129
+ "username": "admin",
130
+ "password": "123456",
131
+ "page_size": 50,
132
+ "throttle": 0,
133
+ "verify_ssl": false
134
+ }
135
+ ```
136
+
137
+ Run commands:
138
+
139
+ ```bash
140
+ # when using locally via the repo prefix commands with ./exe/ i.e. ./exe/asclient -v
141
+ asclient -v
142
+ ```
143
+
119
144
  ## Development
120
145
 
121
146
  To run the examples start a local instance of ArchivesSpace then:
@@ -136,17 +161,8 @@ bundle exec rake
136
161
 
137
162
  ## Publishing
138
163
 
139
- Bump version in `lib/archivesspace/client/version.rb` then:
140
-
141
- ```bash
142
- VERSION=0.1.8
143
- gem build archivesspace-client
144
- git add . && git commit -m "Bump to $VERSION"
145
- git tag v$VERSION
146
- git push origin master
147
- git push --tags
148
- gem push archivesspace-client-$VERSION.gem
149
- ```
164
+ When an updated version (`lib/archivesspace/client/version.rb`) is merged into the
165
+ main/master branch a new release will be built and published.
150
166
 
151
167
  ## Contributing
152
168
 
data/Rakefile CHANGED
@@ -1,8 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/gem_tasks'
4
- require 'rspec/core/rake_task'
5
4
 
5
+ require 'rspec/core/rake_task'
6
6
  RSpec::Core::RakeTask.new(:spec)
7
7
 
8
- task default: :spec
8
+ # require 'rubocop/rake_task'
9
+ # RuboCop::RakeTask.new
10
+
11
+ require 'cucumber/rake/task'
12
+ Cucumber::Rake::Task.new
13
+
14
+ task default: %i[spec cucumber]
15
+
16
+ task :version do
17
+ puts ArchivesSpace::Client::VERSION
18
+ end
@@ -19,13 +19,19 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ['lib']
21
21
 
22
+ spec.add_development_dependency 'aruba'
22
23
  spec.add_development_dependency 'awesome_print', '~> 1.8.0'
23
24
  spec.add_development_dependency 'bundler'
25
+ spec.add_development_dependency 'capybara_discoball'
26
+ spec.add_development_dependency 'cucumber'
27
+ spec.add_development_dependency 'json_spec'
24
28
  spec.add_development_dependency 'rake', '~> 10.0'
25
29
  spec.add_development_dependency 'rspec', '3.6.0'
30
+ spec.add_development_dependency 'rubocop'
26
31
  spec.add_development_dependency 'vcr', '3.0.3'
27
32
  spec.add_development_dependency 'webmock', '3.0.1'
28
33
 
34
+ spec.add_dependency 'dry-cli', '~> 0.7'
29
35
  spec.add_dependency 'httparty', '~> 0.14'
30
36
  spec.add_dependency 'json', '~> 2.0'
31
37
  spec.add_dependency 'nokogiri', '~> 1.10'
@@ -36,7 +36,7 @@ users_with_roles = {
36
36
  }
37
37
 
38
38
  begin
39
- client.config.base_repo = "repositories/2"
39
+ client.config.base_repo = 'repositories/2'
40
40
  results = client.group_user_assignment users_with_roles
41
41
  ap results.map(&:parsed)
42
42
  rescue ArchivesSpace::RequestError => e
data/exe/asclient ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'archivesspace/client'
6
+
7
+ Dry::CLI.new(ArchivesSpace::Client::CLI).call
@@ -0,0 +1,4 @@
1
+ Feature: Exec
2
+ Scenario: With an invalid request type
3
+ When I run `asclient exec all`
4
+ Then the output should match /asclient exec TYPE PATH/
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'aruba/cucumber'
4
+ require 'json_spec/cucumber'
5
+ require 'capybara_discoball'
6
+
7
+ def last_json
8
+ last_command_started.output
9
+ end
@@ -0,0 +1,12 @@
1
+ Feature: Version
2
+ Scenario: Output with 'v'
3
+ When I run `asclient v`
4
+ Then the output should match /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
5
+
6
+ Scenario: Output with -v
7
+ When I run `asclient -v`
8
+ Then the output should match /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
9
+
10
+ Scenario: Output with --version
11
+ When I run `asclient --version`
12
+ Then the output should match /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArchivesSpace
4
+ class Client
5
+ module CLI
6
+ # ArchivesSpace::Client::CLI::Exec executes an API request
7
+ class Exec < Dry::CLI::Command
8
+ desc 'Execute an API request'
9
+
10
+ argument :type, required: true, values: %i[get post put delete], desc: 'API request type'
11
+ argument :path, required: true, desc: 'API request path'
12
+
13
+ option :rid, type: :integer, default: nil, desc: 'Repository id'
14
+ option :payload, type: :string, default: '{}', desc: 'Data payload (json)'
15
+ option :params, type: :string, default: '{}', desc: 'Params (json)'
16
+
17
+ example [
18
+ 'exec get --rid 2 "resources/1"',
19
+ 'exec get users --params \'{"query": {"page": 1}}\''
20
+ ]
21
+
22
+ def call(type:, path:, rid: nil, payload: '{}', params: '{}', **)
23
+ client = ArchivesSpace::Client::CLI.client
24
+ client.repository(rid) if rid
25
+ type = type.to_sym
26
+ payload = JSON.parse(payload, symbolize_names: true)
27
+ params = JSON.parse(params, symbolize_names: true)
28
+
29
+ response = case type
30
+ when :get
31
+ client.get(path, params)
32
+ when :post
33
+ client.post(path, payload, params)
34
+ when :put
35
+ client.put(path, payload, params)
36
+ when :delete
37
+ client.delete(path)
38
+ end
39
+ puts JSON.generate(response.parsed)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArchivesSpace
4
+ class Client
5
+ module CLI
6
+ # ArchivesSpace::Client::CLI::Version prints version
7
+ class Version < Dry::CLI::Command
8
+ desc 'Print ArchivesSpace Client version'
9
+
10
+ def call(*)
11
+ puts ArchivesSpace::Client::VERSION
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArchivesSpace
4
+ class Client
5
+ module CLI
6
+ extend Dry::CLI::Registry
7
+
8
+ def self.client
9
+ cfg = ArchivesSpace::Configuration.new(ArchivesSpace::Client::CLI.find_config)
10
+ ArchivesSpace::Client.new(cfg).login
11
+ end
12
+
13
+ def self.find_config
14
+ config = ENV.fetch('ASCLIENT_CFG', File.join(ENV['HOME'], '.asclientrc'))
15
+ raise "Unable to find asclient configuration file at: #{config}" unless File.file?(config)
16
+
17
+ JSON.parse(File.read(config), symbolize_names: true)
18
+ end
19
+
20
+ register 'exec', Exec, aliases: ['e', '-e']
21
+ register 'version', Version, aliases: ['v', '-v', '--version']
22
+ end
23
+ end
24
+ end
@@ -2,7 +2,8 @@
2
2
 
3
3
  module ArchivesSpace
4
4
  class Client
5
- include Helpers
5
+ include Pagination
6
+ include Task
6
7
  attr_accessor :token
7
8
  attr_reader :config
8
9
 
@@ -13,6 +14,10 @@ module ArchivesSpace
13
14
  @token = nil
14
15
  end
15
16
 
17
+ def backend_version
18
+ get 'version'
19
+ end
20
+
16
21
  def get(path, options = {})
17
22
  request 'GET', path, options
18
23
  end
@@ -29,6 +34,26 @@ module ArchivesSpace
29
34
  request 'DELETE', path
30
35
  end
31
36
 
37
+ # Scoping requests
38
+ def repository(id)
39
+ if id.nil?
40
+ use_global_repository
41
+ return
42
+ end
43
+
44
+ begin
45
+ Integer(id)
46
+ rescue StandardError
47
+ raise RepositoryIdError, "Invalid Repository id: #{id}"
48
+ end
49
+
50
+ @config.base_repo = "repositories/#{id}"
51
+ end
52
+
53
+ def use_global_repository
54
+ @config.base_repo = ''
55
+ end
56
+
32
57
  private
33
58
 
34
59
  def request(method, path, options = {})
@@ -6,6 +6,7 @@ module ArchivesSpace
6
6
  {
7
7
  base_uri: 'http://localhost:8089',
8
8
  base_repo: '',
9
+ debug: false,
9
10
  username: 'admin',
10
11
  password: 'admin',
11
12
  page_size: 50,
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArchivesSpace
4
+ # Handle API Pagination using enumerator
5
+ module Pagination
6
+ # TODO: get via lookup of endpoints that support pagination? (nice-to-have)
7
+ ENDPOINTS = %w[
8
+ accessions
9
+ agents/corporate_entities
10
+ agents/families
11
+ agents/people
12
+ agents/software
13
+ archival_objects
14
+ digital_objects
15
+ groups
16
+ repositories
17
+ resources
18
+ subjects
19
+ users
20
+ ]
21
+
22
+ ENDPOINTS.each do |endpoint|
23
+ method_name = endpoint.split('/').last # remove prefix
24
+ define_method(method_name) do |options = {}|
25
+ all(endpoint, options)
26
+ end
27
+ end
28
+
29
+ def all(path, options = {})
30
+ Enumerator.new do |yielder|
31
+ page = 1
32
+ unlimited_listing = false
33
+ loop do
34
+ options[:query] ||= {}
35
+ options[:query][:page] = page
36
+ result = get(path, options)
37
+ results = []
38
+
39
+ if result.parsed.respond_to?(:key) && result.parsed.key?('results')
40
+ results = result.parsed['results']
41
+ else
42
+ results = result.parsed
43
+ unlimited_listing = true
44
+ end
45
+
46
+ if results.any?
47
+ results.each do |i|
48
+ yielder << i
49
+ end
50
+ raise StopIteration if unlimited_listing
51
+
52
+ page += 1
53
+ else
54
+ raise StopIteration
55
+ end
56
+ end
57
+ end.lazy
58
+ end
59
+ end
60
+ end
@@ -26,12 +26,14 @@ module ArchivesSpace
26
26
  @method = method.downcase.to_sym
27
27
  @path = path.gsub(%r{^/+}, '')
28
28
  @options = options
29
- @options[:headers] = options[:headers] ? default_headers(@method).merge(options[:headers]) : default_headers(@method)
29
+ @options[:headers] =
30
+ options[:headers] ? default_headers(@method).merge(options[:headers]) : default_headers(@method)
30
31
  @options[:verify] = config.verify_ssl
31
32
  @options[:query] = {} unless options.key? :query
32
33
 
33
- base_uri = config.base_repo&.length&.positive? ? File.join(config.base_uri, config.base_repo) : config.base_uri
34
+ self.class.debug_output($stdout) if @config.debug
34
35
 
36
+ base_uri = config.base_repo&.length&.positive? ? File.join(config.base_uri, config.base_repo) : config.base_uri
35
37
  self.class.base_uri base_uri
36
38
  end
37
39
 
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ArchivesSpace
4
+ # Perform specific API tasks
5
+ module Task
6
+ # def batch_import(payload, params = {})
7
+ # # TODO: create "batch_import", payload, params
8
+ # end
9
+
10
+ def group_user_assignment(users_with_roles)
11
+ updated = []
12
+ groups.each do |group|
13
+ group = get("groups/#{uri_to_id(group['uri'])}").parsed
14
+ update = false
15
+
16
+ users_with_roles.each do |user, roles|
17
+ # should the user still belong to this group?
18
+ if group['member_usernames'].include?(user)
19
+ unless roles.include? group['group_code']
20
+ group['member_usernames'].delete user
21
+ update = true
22
+ end
23
+ # should the user be added to this group?
24
+ elsif roles.include? group['group_code']
25
+ group['member_usernames'] << user
26
+ update = true
27
+ end
28
+ end
29
+
30
+ next unless update
31
+
32
+ response = post("/groups/#{uri_to_id(group['uri'])}", group.to_json)
33
+ updated << response
34
+ end
35
+ updated
36
+ end
37
+
38
+ def login
39
+ username = config.username
40
+ password = config.password
41
+ base_repo = config.base_repo
42
+ use_global_repository # ensure we're in the global scope to login
43
+ result = request('POST', "/users/#{username}/login", { query: { password: password } })
44
+ unless result.parsed['session']
45
+ raise ConnectionError, "API client login failed as user [#{username}], check username and password are correct"
46
+ end
47
+
48
+ config.base_repo = base_repo # reset repo as set by the cfg
49
+ @token = result.parsed['session']
50
+ self
51
+ end
52
+
53
+ def password_reset(username, password)
54
+ user = all('users').find { |u| u['username'] == username }
55
+ raise RequestError, user.status unless user
56
+
57
+ post(user['uri'], user.to_json, { password: password })
58
+ end
59
+
60
+ # def search(params)
61
+ # # TODO: get "search", params
62
+ # end
63
+
64
+ private
65
+
66
+ def uri_to_id(uri)
67
+ uri.split('/').last
68
+ end
69
+ end
70
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ArchivesSpace
4
4
  class Client
5
- VERSION = '0.1.8'
5
+ VERSION = '0.1.12'
6
6
  end
7
7
  end
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'dry/cli'
3
4
  require 'httparty'
4
5
  require 'json'
5
6
  require 'nokogiri'
6
7
 
7
8
  # mixins required first
8
- require 'archivesspace/client/helpers'
9
+ require 'archivesspace/client/pagination'
10
+ require 'archivesspace/client/task'
9
11
 
10
12
  require 'archivesspace/client/client'
11
13
  require 'archivesspace/client/configuration'
@@ -14,9 +16,19 @@ require 'archivesspace/client/response'
14
16
  require 'archivesspace/client/template'
15
17
  require 'archivesspace/client/version'
16
18
 
19
+ # cli
20
+ require 'archivesspace/client/cli/exec'
21
+ require 'archivesspace/client/cli/version'
22
+ require 'archivesspace/client/cli' # load the registry last
23
+
17
24
  module ArchivesSpace
18
25
  class ConnectionError < RuntimeError; end
26
+
19
27
  class ContextError < RuntimeError; end
28
+
29
+ class RepositoryIdError < RuntimeError; end
30
+
20
31
  class ParamsError < RuntimeError; end
32
+
21
33
  class RequestError < RuntimeError; end
22
34
  end
@@ -22,6 +22,57 @@ describe ArchivesSpace::Client do
22
22
  end
23
23
  end
24
24
 
25
+ describe 'Repository scoping' do
26
+ it 'will set the repository with an integer id' do
27
+ client = ArchivesSpace::Client.new
28
+ client.repository 2
29
+ expect(client.config.base_repo).to eq 'repositories/2'
30
+ end
31
+
32
+ it 'will set the repository with a string id cast to integer' do
33
+ client = ArchivesSpace::Client.new
34
+ client.repository '2'
35
+ expect(client.config.base_repo).to eq 'repositories/2'
36
+ end
37
+
38
+ it 'will fail if the id cannot be cast to integer' do
39
+ client = ArchivesSpace::Client.new
40
+ expect { client.repository('xyz') }.to raise_error(
41
+ ArchivesSpace::RepositoryIdError
42
+ )
43
+ end
44
+
45
+ it 'will use the global repo if repository is passed nil' do
46
+ client = ArchivesSpace::Client.new
47
+ client.repository 2
48
+ client.repository nil
49
+ expect(client.config.base_repo).to eq ''
50
+ end
51
+
52
+ it 'will use the global repo when the method is called' do
53
+ client = ArchivesSpace::Client.new
54
+ client.repository 2
55
+ client.use_global_repository
56
+ expect(client.config.base_repo).to eq ''
57
+ end
58
+ end
59
+
60
+ describe 'Pagination' do
61
+ it 'will have a method for defined paginated record types' do
62
+ client = ArchivesSpace::Client.new
63
+ ArchivesSpace::Pagination::ENDPOINTS.each do |e|
64
+ next if e.match?('/')
65
+
66
+ expect(client.respond_to?(e.to_sym)).to be true
67
+ end
68
+ end
69
+
70
+ it 'will have a method for defined paginated record types with multipart path' do
71
+ client = ArchivesSpace::Client.new
72
+ expect(client.respond_to?(:people)).to be true
73
+ end
74
+ end
75
+
25
76
  describe 'Version information' do
26
77
  it 'has a version number' do
27
78
  expect(ArchivesSpace::Client::VERSION).not_to be nil
@@ -23,4 +23,4 @@ describe ArchivesSpace::Template do
23
23
  json = JSON.parse(ArchivesSpace::Template.process(:repository_with_agent, data))
24
24
  expect(json['repository']['repo_code']).to eq data[:repo_code]
25
25
  end
26
- end
26
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: archivesspace-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark Cooper
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-21 00:00:00.000000000 Z
11
+ date: 2022-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aruba
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: awesome_print
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,48 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: capybara_discoball
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: cucumber
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: json_spec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
41
97
  - !ruby/object:Gem::Dependency
42
98
  name: rake
43
99
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +122,20 @@ dependencies:
66
122
  - - '='
67
123
  - !ruby/object:Gem::Version
68
124
  version: 3.6.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
69
139
  - !ruby/object:Gem::Dependency
70
140
  name: vcr
71
141
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +164,20 @@ dependencies:
94
164
  - - '='
95
165
  - !ruby/object:Gem::Version
96
166
  version: 3.0.1
167
+ - !ruby/object:Gem::Dependency
168
+ name: dry-cli
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.7'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.7'
97
181
  - !ruby/object:Gem::Dependency
98
182
  name: httparty
99
183
  requirement: !ruby/object:Gem::Requirement
@@ -143,6 +227,8 @@ executables: []
143
227
  extensions: []
144
228
  extra_rdoc_files: []
145
229
  files:
230
+ - ".github/workflows/ci.yml"
231
+ - ".github/workflows/publish.yml"
146
232
  - ".gitignore"
147
233
  - ".rspec"
148
234
  - ".travis.yml"
@@ -156,12 +242,20 @@ files:
156
242
  - examples/repo_and_user.rb
157
243
  - examples/test_connection.rb
158
244
  - examples/user_groups.rb
245
+ - exe/asclient
246
+ - features/exec.feature
247
+ - features/support/setup.rb
248
+ - features/version.feature
159
249
  - lib/archivesspace/client.rb
250
+ - lib/archivesspace/client/cli.rb
251
+ - lib/archivesspace/client/cli/exec.rb
252
+ - lib/archivesspace/client/cli/version.rb
160
253
  - lib/archivesspace/client/client.rb
161
254
  - lib/archivesspace/client/configuration.rb
162
- - lib/archivesspace/client/helpers.rb
255
+ - lib/archivesspace/client/pagination.rb
163
256
  - lib/archivesspace/client/request.rb
164
257
  - lib/archivesspace/client/response.rb
258
+ - lib/archivesspace/client/task.rb
165
259
  - lib/archivesspace/client/template.rb
166
260
  - lib/archivesspace/client/templates/digital_object.json.erb
167
261
  - lib/archivesspace/client/templates/repository.json.erb
@@ -192,11 +286,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
192
286
  - !ruby/object:Gem::Version
193
287
  version: '0'
194
288
  requirements: []
195
- rubygems_version: 3.1.6
289
+ rubygems_version: 3.3.16
196
290
  signing_key:
197
291
  specification_version: 4
198
292
  summary: Interact with ArchivesSpace via the API.
199
293
  test_files:
294
+ - features/exec.feature
295
+ - features/support/setup.rb
296
+ - features/version.feature
200
297
  - spec/archivesspace/client_spec.rb
201
298
  - spec/archivesspace/configuration_spec.rb
202
299
  - spec/archivesspace/templates_spec.rb
@@ -1,133 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # needed for roundtrip hash merging
4
- class ::Hash
5
- def deep_merge(second)
6
- merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
7
- merge(second, &merger)
8
- end
9
- end
10
-
11
- module ArchivesSpace
12
- module Helpers
13
- def accessions(options = {})
14
- all('accessions', options)
15
- end
16
-
17
- def all(path, options = {})
18
- Enumerator.new do |yielder|
19
- page = 1
20
- unlimited_listing = false
21
- loop do
22
- options[:query] ||= {}
23
- options[:query][:page] = page
24
- result = get(path, options)
25
- results = []
26
-
27
- if result.parsed.respond_to?(:key) && result.parsed.key?('results')
28
- results = result.parsed['results']
29
- else
30
- results = result.parsed
31
- unlimited_listing = true
32
- end
33
-
34
- if results.any?
35
- results.each do |i|
36
- yielder << i
37
- end
38
- raise StopIteration if unlimited_listing
39
-
40
- page += 1
41
- else
42
- raise StopIteration
43
- end
44
- end
45
- end.lazy
46
- end
47
-
48
- def backend_version
49
- get 'version'
50
- end
51
-
52
- # def batch_import(payload, params = {})
53
- # # TODO: create "batch_import", payload, params
54
- # end
55
-
56
- def digital_objects(options = {})
57
- all('digital_objects', options)
58
- end
59
-
60
- def groups(options = {})
61
- all('groups', options)
62
- end
63
-
64
- def group_user_assignment(users_with_roles)
65
- updated = []
66
- groups.each do |group|
67
- group = get("groups/#{uri_to_id(group['uri'])}").parsed
68
- update = false
69
-
70
- users_with_roles.each do |user, roles|
71
- # should the user still belong to this group?
72
- if group['member_usernames'].include?(user)
73
- unless roles.include? group['group_code']
74
- group['member_usernames'].delete user
75
- update = true
76
- end
77
- # should the user be added to this group?
78
- elsif roles.include? group['group_code']
79
- group['member_usernames'] << user
80
- update = true
81
- end
82
- end
83
-
84
- next unless update
85
-
86
- response = post("/groups/#{uri_to_id(group['uri'])}", group.to_json)
87
- updated << response
88
- end
89
- updated
90
- end
91
-
92
- def login
93
- username = config.username
94
- password = config.password
95
- result = request('POST', "/users/#{username}/login", { query: { password: password } })
96
- unless result.parsed['session']
97
- raise ConnectionError, "Failed to connect to ArchivesSpace backend as #{username} #{password}"
98
- end
99
-
100
- @token = result.parsed['session']
101
- self
102
- end
103
-
104
- def password_reset(username, password)
105
- user = all('users').find { |u| u['username'] == username }
106
- raise RequestError, user.status unless user
107
-
108
- post(user['uri'], user.to_json, { password: password })
109
- end
110
-
111
- def repositories(options = {})
112
- all('repositories', options)
113
- end
114
-
115
- def repositories_with_agent; end
116
-
117
- def resources(options = {})
118
- all('resources', options)
119
- end
120
-
121
- # def search(params)
122
- # # TODO: get "search", params
123
- # end
124
-
125
- def uri_to_id(uri)
126
- uri.split('/').last
127
- end
128
-
129
- def users(options = {})
130
- all('users', options)
131
- end
132
- end
133
- end