archivesspace-client 0.1.8 → 0.1.12

Sign up to get free protection for your applications and to get access to all the features.
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