berkeley_library-util 0.1.9 → 0.3.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/.github/workflows/build.yml +3 -3
- data/.github/workflows/gem-push.yml +33 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +138 -0
- data/.ruby-version +1 -1
- data/CHANGES.md +12 -0
- data/Dockerfile +58 -0
- data/berkeley_library-util.gemspec +10 -9
- data/docker-compose.yml +10 -0
- data/lib/berkeley_library/util/arrays.rb +5 -5
- data/lib/berkeley_library/util/module_info.rb +3 -3
- data/lib/berkeley_library/util/strings.rb +1 -1
- data/lib/berkeley_library/util/uris/head_check.rb +27 -0
- data/lib/berkeley_library/util/uris/requester/class_methods.rb +20 -11
- data/lib/berkeley_library/util/uris/requester.rb +10 -4
- data/lib/berkeley_library/util/uris.rb +13 -15
- data/lib/berkeley_library/util.rb +1 -1
- data/rakelib/.rubocop.yml +1 -1
- data/spec/.rubocop.yml +5 -4
- data/spec/berkeley_library/util/arrays_spec.rb +16 -18
- data/spec/berkeley_library/util/files_spec.rb +20 -20
- data/spec/berkeley_library/util/strings_spec.rb +3 -3
- data/spec/berkeley_library/util/uris/head_check_spec.rb +61 -0
- data/spec/berkeley_library/util/uris/requester_spec.rb +14 -0
- metadata +50 -26
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 95474321e18bf12390800d829d0fd62e043e5d5e3a17a75df968944698a10328
|
|
4
|
+
data.tar.gz: 98d7b23d5be9bb910b707f53bafa517b51994f9e2fab5b963342027f54c26e84
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 835494737587ecf7b19aa9b88d1ba500f3919c830f6b3dbae1a45d10c42e0cc5520c6f401bcc678cdc2feae4e747caedaf8960804bbc98ecd2981b7157cc0ec1
|
|
7
|
+
data.tar.gz: 770fb93344dc72807d6bfed3d8d1c70e811546bd8698b4bb627dba0206a763b17f0d34f44bf30368837d4a2b7daf64e598d7917b626ee70f978f5095cb8afcdd
|
data/.github/workflows/build.yml
CHANGED
|
@@ -6,7 +6,7 @@ jobs:
|
|
|
6
6
|
fail-fast: false
|
|
7
7
|
matrix:
|
|
8
8
|
os: [ ubuntu-latest, macos-latest ]
|
|
9
|
-
ruby: [ '
|
|
9
|
+
ruby: [ '3.3', '3.4' ]
|
|
10
10
|
runs-on: ${{ matrix.os }}
|
|
11
11
|
|
|
12
12
|
steps:
|
|
@@ -24,7 +24,7 @@ jobs:
|
|
|
24
24
|
|
|
25
25
|
- name: Upload artifacts
|
|
26
26
|
if: ${{ always() }}
|
|
27
|
-
uses: actions/upload-artifact@
|
|
27
|
+
uses: actions/upload-artifact@v4
|
|
28
28
|
with:
|
|
29
|
-
name: artifacts
|
|
29
|
+
name: artifacts-${{ matrix.ruby }}-${{ matrix.os }}
|
|
30
30
|
path: artifacts/**
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Ruby Gem
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
build:
|
|
9
|
+
name: Build + Publish
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
packages: write
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v3
|
|
17
|
+
|
|
18
|
+
- name: Set up Ruby
|
|
19
|
+
uses: ruby/setup-ruby@v1
|
|
20
|
+
with:
|
|
21
|
+
ruby-version: '3.3'
|
|
22
|
+
bundler-cache: true
|
|
23
|
+
|
|
24
|
+
- name: Publish to RubyGems
|
|
25
|
+
run: |
|
|
26
|
+
mkdir -p $HOME/.gem
|
|
27
|
+
touch $HOME/.gem/credentials
|
|
28
|
+
chmod 0600 $HOME/.gem/credentials
|
|
29
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
|
30
|
+
gem build *.gemspec
|
|
31
|
+
gem push *.gem
|
|
32
|
+
env:
|
|
33
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/.gitignore
CHANGED
|
@@ -35,6 +35,7 @@ Gemfile.lock
|
|
|
35
35
|
/test/tmp/
|
|
36
36
|
/test/version_tmp/
|
|
37
37
|
/tmp/
|
|
38
|
+
/vendor
|
|
38
39
|
|
|
39
40
|
# Used by dotenv library to load environment variables.
|
|
40
41
|
# .env
|
|
@@ -218,7 +219,8 @@ flycheck_*.el
|
|
|
218
219
|
.LSOverride
|
|
219
220
|
|
|
220
221
|
# Icon must end with two \r
|
|
221
|
-
Icon
|
|
222
|
+
Icon
|
|
223
|
+
|
|
222
224
|
|
|
223
225
|
# Thumbnails
|
|
224
226
|
._*
|
data/.rubocop.yml
CHANGED
|
@@ -491,3 +491,141 @@ Style/RedundantStringEscape: # (new in 1.37)
|
|
|
491
491
|
Style/RedundantEach: # (new in 1.38)
|
|
492
492
|
Enabled: true
|
|
493
493
|
|
|
494
|
+
Gemspec/AddRuntimeDependency: # new in 1.65
|
|
495
|
+
Enabled: true
|
|
496
|
+
Gemspec/AttributeAssignment: # new in 1.77
|
|
497
|
+
Enabled: true
|
|
498
|
+
Gemspec/DevelopmentDependencies: # new in 1.44
|
|
499
|
+
Enabled: false
|
|
500
|
+
Lint/ArrayLiteralInRegexp: # new in 1.71
|
|
501
|
+
Enabled: true
|
|
502
|
+
Lint/ConstantReassignment: # new in 1.70
|
|
503
|
+
Enabled: true
|
|
504
|
+
Lint/CopDirectiveSyntax: # new in 1.72
|
|
505
|
+
Enabled: true
|
|
506
|
+
Lint/DuplicateMatchPattern: # new in 1.50
|
|
507
|
+
Enabled: true
|
|
508
|
+
Lint/DuplicateSetElement: # new in 1.67
|
|
509
|
+
Enabled: true
|
|
510
|
+
Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
|
|
511
|
+
Enabled: true
|
|
512
|
+
Lint/ItWithoutArgumentsInBlock: # new in 1.59
|
|
513
|
+
Enabled: true
|
|
514
|
+
Lint/LiteralAssignmentInCondition: # new in 1.58
|
|
515
|
+
Enabled: true
|
|
516
|
+
Lint/MixedCaseRange: # new in 1.53
|
|
517
|
+
Enabled: true
|
|
518
|
+
Lint/NumericOperationWithConstantResult: # new in 1.69
|
|
519
|
+
Enabled: true
|
|
520
|
+
Lint/RedundantRegexpQuantifiers: # new in 1.53
|
|
521
|
+
Enabled: true
|
|
522
|
+
Lint/RedundantTypeConversion: # new in 1.72
|
|
523
|
+
Enabled: true
|
|
524
|
+
Lint/SharedMutableDefault: # new in 1.70
|
|
525
|
+
Enabled: true
|
|
526
|
+
Lint/SuppressedExceptionInNumberConversion: # new in 1.72
|
|
527
|
+
Enabled: true
|
|
528
|
+
Lint/UnescapedBracketInRegexp: # new in 1.68
|
|
529
|
+
Enabled: true
|
|
530
|
+
Lint/UselessConstantScoping: # new in 1.72
|
|
531
|
+
Enabled: true
|
|
532
|
+
Lint/UselessDefaultValueArgument: # new in 1.76
|
|
533
|
+
Enabled: true
|
|
534
|
+
Lint/UselessDefined: # new in 1.69
|
|
535
|
+
Enabled: true
|
|
536
|
+
Lint/UselessNumericOperation: # new in 1.66
|
|
537
|
+
Enabled: true
|
|
538
|
+
Lint/UselessOr: # new in 1.76
|
|
539
|
+
Enabled: true
|
|
540
|
+
Lint/UselessRescue: # new in 1.43
|
|
541
|
+
Enabled: true
|
|
542
|
+
Metrics/CollectionLiteralLength: # new in 1.47
|
|
543
|
+
Enabled: true
|
|
544
|
+
Naming/PredicateMethod: # new in 1.76
|
|
545
|
+
Enabled: true
|
|
546
|
+
Style/AmbiguousEndlessMethodDefinition: # new in 1.68
|
|
547
|
+
Enabled: true
|
|
548
|
+
Style/ArrayIntersect: # new in 1.40
|
|
549
|
+
Enabled: true
|
|
550
|
+
Style/BitwisePredicate: # new in 1.68
|
|
551
|
+
Enabled: true
|
|
552
|
+
Style/CollectionQuerying: # new in 1.77
|
|
553
|
+
Enabled: true
|
|
554
|
+
Style/CombinableDefined: # new in 1.68
|
|
555
|
+
Enabled: true
|
|
556
|
+
Style/ComparableBetween: # new in 1.74
|
|
557
|
+
Enabled: true
|
|
558
|
+
Style/ComparableClamp: # new in 1.44
|
|
559
|
+
Enabled: true
|
|
560
|
+
Style/ConcatArrayLiterals: # new in 1.41
|
|
561
|
+
Enabled: true
|
|
562
|
+
Style/DataInheritance: # new in 1.49
|
|
563
|
+
Enabled: true
|
|
564
|
+
Style/DigChain: # new in 1.69
|
|
565
|
+
Enabled: true
|
|
566
|
+
Style/DirEmpty: # new in 1.48
|
|
567
|
+
Enabled: true
|
|
568
|
+
Style/EmptyStringInsideInterpolation: # new in 1.76
|
|
569
|
+
Enabled: true
|
|
570
|
+
Style/ExactRegexpMatch: # new in 1.51
|
|
571
|
+
Enabled: true
|
|
572
|
+
Style/FileEmpty: # new in 1.48
|
|
573
|
+
Enabled: true
|
|
574
|
+
Style/FileNull: # new in 1.69
|
|
575
|
+
Enabled: true
|
|
576
|
+
Style/FileTouch: # new in 1.69
|
|
577
|
+
Enabled: true
|
|
578
|
+
Style/HashFetchChain: # new in 1.75
|
|
579
|
+
Enabled: true
|
|
580
|
+
Style/HashSlice: # new in 1.71
|
|
581
|
+
Enabled: true
|
|
582
|
+
Style/ItAssignment: # new in 1.70
|
|
583
|
+
Enabled: true
|
|
584
|
+
Style/ItBlockParameter: # new in 1.75
|
|
585
|
+
Enabled: true
|
|
586
|
+
Style/KeywordArgumentsMerging: # new in 1.68
|
|
587
|
+
Enabled: true
|
|
588
|
+
Style/MapIntoArray: # new in 1.63
|
|
589
|
+
Enabled: true
|
|
590
|
+
Style/MapToSet: # new in 1.42
|
|
591
|
+
Enabled: true
|
|
592
|
+
Style/MinMaxComparison: # new in 1.42
|
|
593
|
+
Enabled: true
|
|
594
|
+
Style/RedundantArrayConstructor: # new in 1.52
|
|
595
|
+
Enabled: true
|
|
596
|
+
Style/RedundantArrayFlatten: # new in 1.76
|
|
597
|
+
Enabled: true
|
|
598
|
+
Style/RedundantConstantBase: # new in 1.40
|
|
599
|
+
Enabled: true
|
|
600
|
+
Style/RedundantCurrentDirectoryInPath: # new in 1.53
|
|
601
|
+
Enabled: true
|
|
602
|
+
Style/RedundantDoubleSplatHashBraces: # new in 1.41
|
|
603
|
+
Enabled: true
|
|
604
|
+
Style/RedundantFilterChain: # new in 1.52
|
|
605
|
+
Enabled: true
|
|
606
|
+
Style/RedundantFormat: # new in 1.72
|
|
607
|
+
Enabled: true
|
|
608
|
+
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
|
|
609
|
+
Enabled: true
|
|
610
|
+
Style/RedundantInterpolationUnfreeze: # new in 1.66
|
|
611
|
+
Enabled: true
|
|
612
|
+
Style/RedundantLineContinuation: # new in 1.49
|
|
613
|
+
Enabled: true
|
|
614
|
+
Style/RedundantRegexpArgument: # new in 1.53
|
|
615
|
+
Enabled: true
|
|
616
|
+
Style/RedundantRegexpConstructor: # new in 1.52
|
|
617
|
+
Enabled: true
|
|
618
|
+
Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
|
|
619
|
+
Enabled: true
|
|
620
|
+
Style/SafeNavigationChainLength: # new in 1.68
|
|
621
|
+
Enabled: true
|
|
622
|
+
Style/SendWithLiteralMethodName: # new in 1.64
|
|
623
|
+
Enabled: true
|
|
624
|
+
Style/SingleLineDoEndBlock: # new in 1.57
|
|
625
|
+
Enabled: true
|
|
626
|
+
Style/SuperArguments: # new in 1.64
|
|
627
|
+
Enabled: true
|
|
628
|
+
Style/SuperWithArgsParentheses: # new in 1.58
|
|
629
|
+
Enabled: true
|
|
630
|
+
Style/YAMLFileRead: # new in 1.53
|
|
631
|
+
Enabled: true
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
3.3
|
data/CHANGES.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
# 0.3.0 (2026-02-04)
|
|
2
|
+
|
|
3
|
+
- Add `URIs::HeadCheck`, an OkComputer check that performs a HEAD request
|
|
4
|
+
to verify the availability of a URL, with optional basic authentication.
|
|
5
|
+
- updates Requester to support timeouts values passed to RestClient
|
|
6
|
+
- Bumping to 0.3.0 to reflect changes to `Requester` and the addition of `URIs::HeadCheck`.
|
|
7
|
+
|
|
8
|
+
# 0.2.0 (2025-07-24)
|
|
9
|
+
|
|
10
|
+
- Update to support Ruby 3.3+.
|
|
11
|
+
- Update Rubocop & style changes.
|
|
12
|
+
|
|
1
13
|
# 0.1.9 (2023-06-01)
|
|
2
14
|
|
|
3
15
|
- `URIs#path_escape` now attempts to convert non-UTF-8 strings to UTF-8 rather than immediately
|
data/Dockerfile
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# Target: base
|
|
3
|
+
|
|
4
|
+
FROM ruby:3.3-alpine AS base
|
|
5
|
+
|
|
6
|
+
RUN apk --no-cache --update upgrade && \
|
|
7
|
+
apk --no-cache add \
|
|
8
|
+
bash \
|
|
9
|
+
ca-certificates \
|
|
10
|
+
git \
|
|
11
|
+
libc6-compat \
|
|
12
|
+
openssl \
|
|
13
|
+
tzdata \
|
|
14
|
+
xz-libs \
|
|
15
|
+
yaml-dev \
|
|
16
|
+
&& rm -rf /var/cache/apk/*
|
|
17
|
+
|
|
18
|
+
WORKDIR /opt/app
|
|
19
|
+
|
|
20
|
+
# =============================================================================
|
|
21
|
+
# Target: development
|
|
22
|
+
#
|
|
23
|
+
|
|
24
|
+
FROM base AS development
|
|
25
|
+
|
|
26
|
+
# Install system packages needed to build gems with C extensions.
|
|
27
|
+
RUN apk --update --no-cache add \
|
|
28
|
+
build-base \
|
|
29
|
+
coreutils \
|
|
30
|
+
git \
|
|
31
|
+
&& rm -rf /var/cache/apk/*
|
|
32
|
+
|
|
33
|
+
# The base image ships an older bundler, but we want something more recent
|
|
34
|
+
RUN gem install bundler -v 2.5.22
|
|
35
|
+
|
|
36
|
+
# Copy codebase to WORKDIR. Unlike application projects, for a gem project
|
|
37
|
+
# we need to do this before running `bundle install`, in order for the gem
|
|
38
|
+
# we're building to be able to "install" itself.
|
|
39
|
+
COPY . .
|
|
40
|
+
|
|
41
|
+
# Install gems.
|
|
42
|
+
RUN bundle install --path=/usr/local/bundle
|
|
43
|
+
|
|
44
|
+
# =============================================================================
|
|
45
|
+
# Target: production
|
|
46
|
+
|
|
47
|
+
FROM base AS production
|
|
48
|
+
|
|
49
|
+
# Copy the built codebase from the dev stage
|
|
50
|
+
COPY --from=development /opt/app /opt/app
|
|
51
|
+
COPY --from=development /usr/local/bundle /usr/local/bundle
|
|
52
|
+
|
|
53
|
+
# Sanity-check that everything was installed correctly and still runs in the
|
|
54
|
+
# slimmed-down production image.
|
|
55
|
+
RUN bundle config set deployment 'true'
|
|
56
|
+
RUN bundle install --local --path=/usr/local/bundle
|
|
57
|
+
|
|
58
|
+
CMD ["bundle", "exec", "rake"]
|
|
@@ -2,14 +2,14 @@ File.expand_path('lib', __dir__).tap do |lib|
|
|
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
3
|
end
|
|
4
4
|
|
|
5
|
-
ruby_version = '
|
|
5
|
+
ruby_version = '~> 3.3'
|
|
6
6
|
|
|
7
7
|
require 'berkeley_library/util/module_info'
|
|
8
8
|
|
|
9
9
|
Gem::Specification.new do |spec|
|
|
10
10
|
spec.name = BerkeleyLibrary::Util::ModuleInfo::NAME
|
|
11
|
-
spec.author = BerkeleyLibrary::Util::ModuleInfo::
|
|
12
|
-
spec.email = BerkeleyLibrary::Util::ModuleInfo::
|
|
11
|
+
spec.author = BerkeleyLibrary::Util::ModuleInfo::AUTHORS
|
|
12
|
+
spec.email = BerkeleyLibrary::Util::ModuleInfo::AUTHOR_EMAILS
|
|
13
13
|
spec.summary = BerkeleyLibrary::Util::ModuleInfo::SUMMARY
|
|
14
14
|
spec.description = BerkeleyLibrary::Util::ModuleInfo::DESCRIPTION
|
|
15
15
|
spec.license = BerkeleyLibrary::Util::ModuleInfo::LICENSE
|
|
@@ -21,19 +21,20 @@ Gem::Specification.new do |spec|
|
|
|
21
21
|
|
|
22
22
|
spec.required_ruby_version = ruby_version
|
|
23
23
|
|
|
24
|
-
spec.add_dependency 'berkeley_library-logging', '~> 0.
|
|
24
|
+
spec.add_dependency 'berkeley_library-logging', '~> 0.3'
|
|
25
25
|
spec.add_dependency 'rest-client', '~> 2.1'
|
|
26
26
|
spec.add_dependency 'typesafe_enum', '~> 0.3'
|
|
27
27
|
|
|
28
28
|
spec.add_development_dependency 'ci_reporter_rspec', '~> 1.0'
|
|
29
|
-
spec.add_development_dependency 'colorize', '~> 0
|
|
29
|
+
spec.add_development_dependency 'colorize', '~> 1.0'
|
|
30
30
|
spec.add_development_dependency 'dotenv', '~> 2.7'
|
|
31
|
+
spec.add_development_dependency 'okcomputer', '~> 1.19'
|
|
31
32
|
spec.add_development_dependency 'rake', '~> 13.0'
|
|
32
33
|
spec.add_development_dependency 'rspec', '~> 3.10'
|
|
33
|
-
spec.add_development_dependency 'rubocop', '
|
|
34
|
-
spec.add_development_dependency 'rubocop-rake', '
|
|
35
|
-
spec.add_development_dependency 'rubocop-rspec', '
|
|
36
|
-
spec.add_development_dependency 'ruby-prof'
|
|
34
|
+
spec.add_development_dependency 'rubocop', '~> 1.78.0'
|
|
35
|
+
spec.add_development_dependency 'rubocop-rake', '~> 0.7.1'
|
|
36
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 3.6.0'
|
|
37
|
+
spec.add_development_dependency 'ruby-prof'
|
|
37
38
|
spec.add_development_dependency 'simplecov', '~> 0.21'
|
|
38
39
|
spec.add_development_dependency 'webmock', '~> 3.12'
|
|
39
40
|
|
data/docker-compose.yml
ADDED
|
@@ -63,8 +63,8 @@ module BerkeleyLibrary
|
|
|
63
63
|
# @yieldparam target [Object] the value to compare against
|
|
64
64
|
# @return [Array<Integer>, nil] the indices in `in_array` of each value in `for_array`,
|
|
65
65
|
# or `nil` if not all values could be found
|
|
66
|
-
def find_indices(for_array:, in_array:, &
|
|
67
|
-
return find_indices_matching(for_array, in_array, &
|
|
66
|
+
def find_indices(for_array:, in_array:, &)
|
|
67
|
+
return find_indices_matching(for_array, in_array, &) if block_given?
|
|
68
68
|
|
|
69
69
|
find_all_indices(for_array, in_array)
|
|
70
70
|
end
|
|
@@ -89,10 +89,10 @@ module BerkeleyLibrary
|
|
|
89
89
|
# @param in_array [Array] the array to search
|
|
90
90
|
# @param start_index [Integer] the index to start with
|
|
91
91
|
# @return [Enumerator] a new enumerator
|
|
92
|
-
def find_index(*args, in_array:, start_index: 0, &
|
|
92
|
+
def find_index(*args, in_array:, start_index: 0, &)
|
|
93
93
|
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 0..1" if args.size > 1
|
|
94
94
|
return Enumerator.new { |y| find_index(in_array: in_array, start_index: start_index, &y) } if args.empty? && !block_given?
|
|
95
|
-
return unless (relative_index = in_array[start_index..].find_index(*args, &
|
|
95
|
+
return unless (relative_index = in_array[start_index..].find_index(*args, &))
|
|
96
96
|
|
|
97
97
|
relative_index + start_index
|
|
98
98
|
end
|
|
@@ -142,7 +142,7 @@ module BerkeleyLibrary
|
|
|
142
142
|
shorter_unmatched = shorter[0...ix_s]
|
|
143
143
|
longer_unmatched = longer[0...ix_l]
|
|
144
144
|
all_unmatched = sort_by_first_and_flatten(shorter_unmatched, longer_unmatched)
|
|
145
|
-
return (all_unmatched << v) + merge(shorter[ix_s + 1..], longer[ix_l + 1..])
|
|
145
|
+
return (all_unmatched << v) + merge(shorter[(ix_s + 1)..], longer[(ix_l + 1)..])
|
|
146
146
|
end
|
|
147
147
|
|
|
148
148
|
sort_by_first_and_flatten(longer, shorter)
|
|
@@ -2,12 +2,12 @@ module BerkeleyLibrary
|
|
|
2
2
|
module Util
|
|
3
3
|
class ModuleInfo
|
|
4
4
|
NAME = 'berkeley_library-util'.freeze
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
AUTHORS = ['David Moles', 'maría a. matienzo', 'Jason Raitz'].freeze
|
|
6
|
+
AUTHOR_EMAILS = ['dmoles@berkeley.edu', 'matienzo@berkeley.edu', 'raitz@berkeley.edu'].freeze
|
|
7
7
|
SUMMARY = 'Miscellaneous Ruby utilities for the UC Berkeley Library'.freeze
|
|
8
8
|
DESCRIPTION = 'A collection of miscellaneous Ruby routines for the UC Berkeley Library.'.freeze
|
|
9
9
|
LICENSE = 'MIT'.freeze
|
|
10
|
-
VERSION = '0.
|
|
10
|
+
VERSION = '0.3.0'.freeze
|
|
11
11
|
HOMEPAGE = 'https://github.com/BerkeleyLibrary/util'.freeze
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'berkeley_library/util/uris'
|
|
2
|
+
|
|
3
|
+
module BerkeleyLibrary
|
|
4
|
+
module Util
|
|
5
|
+
# :nocov:
|
|
6
|
+
if defined?(::OkComputer)
|
|
7
|
+
class HeadCheck < ::OkComputer::HttpCheck
|
|
8
|
+
|
|
9
|
+
def perform_request
|
|
10
|
+
headers = {}
|
|
11
|
+
if basic_auth_options.any?
|
|
12
|
+
user, password = basic_auth_options
|
|
13
|
+
headers['Authorization'] = "Basic #{Base64.strict_encode64("#{user}:#{password}")}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
options = { headers: headers, log: false }
|
|
17
|
+
options[:timeout] = request_timeout.to_i if request_timeout
|
|
18
|
+
|
|
19
|
+
URIs.head_response(url, **options)
|
|
20
|
+
rescue StandardError => e
|
|
21
|
+
raise OkComputer::HttpCheck::ConnectionFailed, e
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
# :nocov:
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -13,9 +13,11 @@ module BerkeleyLibrary
|
|
|
13
13
|
# @param log [Boolean] whether to log each request URL and response code
|
|
14
14
|
# @param max_retries [Integer] the maximum number of times to retry after a 429 or 503 with Retry-After
|
|
15
15
|
# @param max_retry_delay [Integer] the maximum retry delay (in seconds) to accept in a Retry-After header
|
|
16
|
+
# @param timeout [Integer] the request timeout in seconds (RestClient will use this to set both open and read timeouts)
|
|
16
17
|
# @raise [RestClient::Exception] in the event of an unsuccessful request.
|
|
17
|
-
def get(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS
|
|
18
|
-
|
|
18
|
+
def get(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS,
|
|
19
|
+
timeout: DEFAULT_TIMEOUT_SECONDS)
|
|
20
|
+
resp = make_request(:get, uri, params, headers, log, max_retries, max_retry_delay, timeout)
|
|
19
21
|
resp.body
|
|
20
22
|
end
|
|
21
23
|
|
|
@@ -28,8 +30,10 @@ module BerkeleyLibrary
|
|
|
28
30
|
# @param headers [Hash] the request headers.
|
|
29
31
|
# @param log [Boolean] whether to log each request URL and response code
|
|
30
32
|
# @return [Integer] the response code as an integer.
|
|
31
|
-
def head(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS
|
|
32
|
-
|
|
33
|
+
def head(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS,
|
|
34
|
+
timeout: DEFAULT_TIMEOUT_SECONDS)
|
|
35
|
+
head_response(uri, params: params, headers: headers, log: log, max_retries: max_retries, max_retry_delay: max_retry_delay,
|
|
36
|
+
timeout: timeout).code
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
# Performs a GET request and returns the response, even in the event of
|
|
@@ -40,8 +44,9 @@ module BerkeleyLibrary
|
|
|
40
44
|
# @param headers [Hash] the request headers.
|
|
41
45
|
# @param log [Boolean] whether to log each request URL and response code
|
|
42
46
|
# @return [RestClient::Response] the response
|
|
43
|
-
def get_response(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS
|
|
44
|
-
|
|
47
|
+
def get_response(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS,
|
|
48
|
+
timeout: DEFAULT_TIMEOUT_SECONDS)
|
|
49
|
+
make_request(:get, uri, params, headers, log, max_retries, max_retry_delay, timeout)
|
|
45
50
|
rescue RestClient::Exception => e
|
|
46
51
|
e.response
|
|
47
52
|
end
|
|
@@ -54,15 +59,18 @@ module BerkeleyLibrary
|
|
|
54
59
|
# @param headers [Hash] the request headers.
|
|
55
60
|
# @param log [Boolean] whether to log each request URL and response code
|
|
56
61
|
# @return [RestClient::Response] the response
|
|
57
|
-
def head_response(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS
|
|
58
|
-
|
|
62
|
+
def head_response(uri, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS,
|
|
63
|
+
timeout: DEFAULT_TIMEOUT_SECONDS)
|
|
64
|
+
make_request(:head, uri, params, headers, log, max_retries, max_retry_delay, timeout)
|
|
59
65
|
rescue RestClient::Exception => e
|
|
60
|
-
e.response
|
|
66
|
+
return e.response if e.response
|
|
67
|
+
|
|
68
|
+
raise
|
|
61
69
|
end
|
|
62
70
|
|
|
63
71
|
private
|
|
64
72
|
|
|
65
|
-
def make_request(method, url, params, headers, log, max_retries, max_retry_delay)
|
|
73
|
+
def make_request(method, url, params, headers, log, max_retries, max_retry_delay, timeout)
|
|
66
74
|
Requester.new(
|
|
67
75
|
method,
|
|
68
76
|
url,
|
|
@@ -70,7 +78,8 @@ module BerkeleyLibrary
|
|
|
70
78
|
headers: headers,
|
|
71
79
|
log: log,
|
|
72
80
|
max_retries: max_retries,
|
|
73
|
-
max_retry_delay: max_retry_delay
|
|
81
|
+
max_retry_delay: max_retry_delay,
|
|
82
|
+
timeout: timeout
|
|
74
83
|
).make_request
|
|
75
84
|
end
|
|
76
85
|
|
|
@@ -20,11 +20,12 @@ module BerkeleyLibrary
|
|
|
20
20
|
RETRY_STATUSES = [429, 503].freeze
|
|
21
21
|
MAX_RETRY_DELAY_SECONDS = 10
|
|
22
22
|
MAX_RETRIES = 3
|
|
23
|
+
DEFAULT_TIMEOUT_SECONDS = 10
|
|
23
24
|
|
|
24
25
|
# ------------------------------------------------------------
|
|
25
26
|
# Attributes
|
|
26
27
|
|
|
27
|
-
attr_reader :method, :url_str, :headers, :log, :max_retries, :max_retry_delay
|
|
28
|
+
attr_reader :method, :url_str, :headers, :log, :max_retries, :max_retry_delay, :timeout
|
|
28
29
|
|
|
29
30
|
# ------------------------------------------------------------
|
|
30
31
|
# Initializer
|
|
@@ -38,9 +39,11 @@ module BerkeleyLibrary
|
|
|
38
39
|
# @param log [Boolean] whether to log each request URL and response code
|
|
39
40
|
# @param max_retries [Integer] the maximum number of times to retry after a 429 or 503 with Retry-After
|
|
40
41
|
# @param max_retry_delay [Integer] the maximum retry delay (in seconds) to accept in a Retry-After header
|
|
42
|
+
# @param timeout [Integer] the request timeout in seconds (RestClient will use this to set both open and read timeouts)
|
|
41
43
|
# @raise URI::InvalidURIError if the specified URL is invalid
|
|
42
44
|
# rubocop:disable Metrics/ParameterLists
|
|
43
|
-
def initialize(method, url, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS
|
|
45
|
+
def initialize(method, url, params: {}, headers: {}, log: true, max_retries: MAX_RETRIES, max_retry_delay: MAX_RETRY_DELAY_SECONDS,
|
|
46
|
+
timeout: DEFAULT_TIMEOUT_SECONDS)
|
|
44
47
|
raise ArgumentError, "#{method} not supported" unless SUPPORTED_METHODS.include?(method)
|
|
45
48
|
raise ArgumentError, 'url cannot be nil' unless (uri = Validator.uri_or_nil(url))
|
|
46
49
|
|
|
@@ -50,6 +53,7 @@ module BerkeleyLibrary
|
|
|
50
53
|
@log = log
|
|
51
54
|
@max_retries = max_retries
|
|
52
55
|
@max_retry_delay = max_retry_delay
|
|
56
|
+
@timeout = timeout
|
|
53
57
|
end
|
|
54
58
|
|
|
55
59
|
# rubocop:enable Metrics/ParameterLists
|
|
@@ -73,7 +77,7 @@ module BerkeleyLibrary
|
|
|
73
77
|
private
|
|
74
78
|
|
|
75
79
|
def log_response(response)
|
|
76
|
-
return unless log
|
|
80
|
+
return unless log && response&.code
|
|
77
81
|
|
|
78
82
|
logger.info("#{method.to_s.upcase} #{url_str} returned #{response.code}")
|
|
79
83
|
end
|
|
@@ -90,6 +94,8 @@ module BerkeleyLibrary
|
|
|
90
94
|
|
|
91
95
|
def execute_request(retries_remaining = max_retries)
|
|
92
96
|
try_execute_request
|
|
97
|
+
rescue RestClient::Exceptions::Timeout
|
|
98
|
+
raise
|
|
93
99
|
rescue RestClient::Exception => e
|
|
94
100
|
response = e.response
|
|
95
101
|
raise unless (retry_delay = retry_delay_from(response))
|
|
@@ -99,7 +105,7 @@ module BerkeleyLibrary
|
|
|
99
105
|
end
|
|
100
106
|
|
|
101
107
|
def try_execute_request
|
|
102
|
-
RestClient::Request.execute(method: method, url: url_str, headers: headers).tap do |response|
|
|
108
|
+
RestClient::Request.execute(method: method, url: url_str, headers: headers, timeout: timeout).tap do |response|
|
|
103
109
|
# Not all failed RestClient requests throw exceptions
|
|
104
110
|
raise(exception_for(response)) unless response.code == 200
|
|
105
111
|
end
|
|
@@ -34,8 +34,8 @@ module BerkeleyLibrary
|
|
|
34
34
|
# @param log [Boolean] whether to log each request URL and response code
|
|
35
35
|
# @return [String] the body as a string.
|
|
36
36
|
# @raise [RestClient::Exception] in the event of an unsuccessful request.
|
|
37
|
-
def get(uri, params: {}, headers: {}, log: true)
|
|
38
|
-
Requester.get(uri, params: params, headers: headers, log: log)
|
|
37
|
+
def get(uri, params: {}, headers: {}, log: true, timeout: Requester::DEFAULT_TIMEOUT_SECONDS)
|
|
38
|
+
Requester.get(uri, params: params, headers: headers, log: log, timeout: timeout)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
# Performs a HEAD request and returns the response status as an integer.
|
|
@@ -47,8 +47,8 @@ module BerkeleyLibrary
|
|
|
47
47
|
# @param headers [Hash] the request headers.
|
|
48
48
|
# @param log [Boolean] whether to log each request URL and response code
|
|
49
49
|
# @return [Integer] the response code as an integer.
|
|
50
|
-
def head(uri, params: {}, headers: {}, log: true)
|
|
51
|
-
Requester.head(uri, params: params, headers: headers, log: log)
|
|
50
|
+
def head(uri, params: {}, headers: {}, log: true, timeout: Requester::DEFAULT_TIMEOUT_SECONDS)
|
|
51
|
+
Requester.head(uri, params: params, headers: headers, log: log, timeout: timeout)
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
# Performs a GET request and returns the response, even in the event of
|
|
@@ -59,8 +59,8 @@ module BerkeleyLibrary
|
|
|
59
59
|
# @param headers [Hash] the request headers.
|
|
60
60
|
# @param log [Boolean] whether to log each request URL and response code
|
|
61
61
|
# @return [RestClient::Response] the response
|
|
62
|
-
def get_response(uri, params: {}, headers: {}, log: true)
|
|
63
|
-
Requester.get_response(uri, params: params, headers: headers, log: log)
|
|
62
|
+
def get_response(uri, params: {}, headers: {}, log: true, timeout: Requester::DEFAULT_TIMEOUT_SECONDS)
|
|
63
|
+
Requester.get_response(uri, params: params, headers: headers, log: log, timeout: timeout)
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
# Performs a HEAD request and returns the response, even in the event of
|
|
@@ -71,8 +71,8 @@ module BerkeleyLibrary
|
|
|
71
71
|
# @param headers [Hash] the request headers.
|
|
72
72
|
# @param log [Boolean] whether to log each request URL and response code
|
|
73
73
|
# @return [RestClient::Response] the response
|
|
74
|
-
def head_response(uri, params: {}, headers: {}, log: true)
|
|
75
|
-
Requester.head_response(uri, params: params, headers: headers, log: log)
|
|
74
|
+
def head_response(uri, params: {}, headers: {}, log: true, timeout: Requester::DEFAULT_TIMEOUT_SECONDS)
|
|
75
|
+
Requester.head_response(uri, params: params, headers: headers, log: log, timeout: timeout)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# Returns the specified URL as a URI, or `nil` if the URL is `nil`.
|
|
@@ -109,14 +109,14 @@ module BerkeleyLibrary
|
|
|
109
109
|
nil
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
private
|
|
113
|
-
|
|
114
112
|
# TODO: extend to cover other modes - host, zone, path, password, query, fragment
|
|
115
113
|
# cf. https://github.com/golang/go/blob/master/src/net/url/url.go
|
|
116
114
|
ALLOWED_BYTES_BY_MODE = {
|
|
117
115
|
path_segment: [0x24, 0x26, 0x2b, 0x3a, 0x3d, 0x40] # @ & = + $
|
|
118
116
|
}.freeze
|
|
119
117
|
|
|
118
|
+
private
|
|
119
|
+
|
|
120
120
|
def should_escape?(b, mode)
|
|
121
121
|
return false if unreserved?(b)
|
|
122
122
|
return false if ALLOWED_BYTES_BY_MODE[mode].include?(b)
|
|
@@ -124,16 +124,14 @@ module BerkeleyLibrary
|
|
|
124
124
|
true
|
|
125
125
|
end
|
|
126
126
|
|
|
127
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
|
128
127
|
def unreserved?(byte)
|
|
129
|
-
return true if byte
|
|
130
|
-
return true if byte
|
|
131
|
-
return true if byte
|
|
128
|
+
return true if byte.between?(0x41, 0x5a) # A-Z
|
|
129
|
+
return true if byte.between?(0x61, 0x7a) # a-z
|
|
130
|
+
return true if byte.between?(0x30, 0x39) # 0-9
|
|
132
131
|
return true if [0x2d, 0x2e, 0x5f, 0x7e].include?(byte) # - . _ ~
|
|
133
132
|
|
|
134
133
|
false
|
|
135
134
|
end
|
|
136
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
|
137
135
|
end
|
|
138
136
|
end
|
|
139
137
|
end
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Dir.glob(File.expand_path('util/*.rb', __dir__)).
|
|
1
|
+
Dir.glob(File.expand_path('util/*.rb', __dir__)).each(&method(:require))
|
data/rakelib/.rubocop.yml
CHANGED
data/spec/.rubocop.yml
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
inherit_from: ../.rubocop.yml
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
plugins:
|
|
4
4
|
- rubocop-rspec
|
|
5
5
|
|
|
6
6
|
AllCops:
|
|
@@ -78,9 +78,12 @@ RSpec/ExpectInHook:
|
|
|
78
78
|
Enabled: false
|
|
79
79
|
|
|
80
80
|
# your naming scheme is not in possession of all the facts
|
|
81
|
-
RSpec/
|
|
81
|
+
RSpec/SpecFilePathFormat:
|
|
82
82
|
Enabled: false
|
|
83
83
|
|
|
84
|
+
RSpec/SpecFilePathSuffix:
|
|
85
|
+
Enabled: true
|
|
86
|
+
|
|
84
87
|
# explicit >>> implicit
|
|
85
88
|
RSpec/InstanceVariable:
|
|
86
89
|
Enabled: false
|
|
@@ -125,5 +128,3 @@ RSpec/VerifiedDoubles:
|
|
|
125
128
|
RSpec/IdenticalEqualityAssertion: # new in 2.4
|
|
126
129
|
Enabled: true
|
|
127
130
|
|
|
128
|
-
RSpec/Rails/AvoidSetupHook: # new in 2.4
|
|
129
|
-
Enabled: true
|
|
@@ -8,11 +8,11 @@ module BerkeleyLibrary::Util
|
|
|
8
8
|
let(:sup) { %w[a b c d e] }
|
|
9
9
|
|
|
10
10
|
it 'returns true for an identical subset' do
|
|
11
|
-
expect(Arrays.ordered_superset?(superset: sup, subset: sup.dup)).to
|
|
11
|
+
expect(Arrays.ordered_superset?(superset: sup, subset: sup.dup)).to be(true)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
it 'returns true for an empty subset' do
|
|
15
|
-
expect(Arrays.ordered_superset?(superset: sup, subset: [])).to
|
|
15
|
+
expect(Arrays.ordered_superset?(superset: sup, subset: [])).to be(true)
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
it 'returns true for an exact sublist' do
|
|
@@ -22,7 +22,7 @@ module BerkeleyLibrary::Util
|
|
|
22
22
|
%w[c d e]
|
|
23
23
|
]
|
|
24
24
|
subs.each do |sub|
|
|
25
|
-
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to
|
|
25
|
+
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to be(true)
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -33,13 +33,13 @@ module BerkeleyLibrary::Util
|
|
|
33
33
|
%w[a b d e]
|
|
34
34
|
]
|
|
35
35
|
subs.each do |sub|
|
|
36
|
-
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to
|
|
36
|
+
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to be(true)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it 'returns false for a too-large subset' do
|
|
41
41
|
sub = %w[a b c d e f g]
|
|
42
|
-
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to
|
|
42
|
+
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to be(false)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
it 'returns false when extra elements are present' do
|
|
@@ -49,7 +49,7 @@ module BerkeleyLibrary::Util
|
|
|
49
49
|
%w[c d x e]
|
|
50
50
|
]
|
|
51
51
|
subs.each do |sub|
|
|
52
|
-
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to
|
|
52
|
+
expect(Arrays.ordered_superset?(superset: sup, subset: sub)).to be(false)
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
end
|
|
@@ -150,7 +150,6 @@ module BerkeleyLibrary::Util
|
|
|
150
150
|
expect { Arrays.find_index(1, 2, 3, in_array: [1, 2, 3]) }.to raise_error(ArgumentError)
|
|
151
151
|
end
|
|
152
152
|
|
|
153
|
-
# rubocop:disable Lint/Void
|
|
154
153
|
it 'returns an enumerator if given no arguments' do
|
|
155
154
|
e = Arrays.find_index(in_array: arr)
|
|
156
155
|
expect(e.each { |x| x > 3 }).to eq(2)
|
|
@@ -158,7 +157,6 @@ module BerkeleyLibrary::Util
|
|
|
158
157
|
e = Arrays.find_index(in_array: arr, start_index: 3)
|
|
159
158
|
expect(e.each { |x| x < 5 }).to eq(4)
|
|
160
159
|
end
|
|
161
|
-
# rubocop:enable Lint/Void
|
|
162
160
|
end
|
|
163
161
|
|
|
164
162
|
describe :merge do
|
|
@@ -181,7 +179,7 @@ module BerkeleyLibrary::Util
|
|
|
181
179
|
|
|
182
180
|
merged = Arrays.merge(a1, a2)
|
|
183
181
|
[a1, a2].each do |a|
|
|
184
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
182
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
185
183
|
end
|
|
186
184
|
|
|
187
185
|
expected = [1, 2, 2, 3, 4, 4, 5, 5, 6]
|
|
@@ -195,7 +193,7 @@ module BerkeleyLibrary::Util
|
|
|
195
193
|
|
|
196
194
|
merged = Arrays.merge(a1, a2)
|
|
197
195
|
[a1, a2].each do |a|
|
|
198
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
196
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
199
197
|
end
|
|
200
198
|
|
|
201
199
|
expected = [1, 2, 3, 4, 5, 7, 8, 9]
|
|
@@ -209,7 +207,7 @@ module BerkeleyLibrary::Util
|
|
|
209
207
|
|
|
210
208
|
merged = Arrays.merge(a1, a2)
|
|
211
209
|
[a1, a2].each do |a|
|
|
212
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
210
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
213
211
|
end
|
|
214
212
|
|
|
215
213
|
expected = [1, 2, 3, 2, 2, 4]
|
|
@@ -223,7 +221,7 @@ module BerkeleyLibrary::Util
|
|
|
223
221
|
|
|
224
222
|
merged = Arrays.merge(a1, a2)
|
|
225
223
|
[a1, a2].each do |a|
|
|
226
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
224
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
227
225
|
end
|
|
228
226
|
|
|
229
227
|
expected = [1, nil, 3, nil, nil, 4]
|
|
@@ -237,7 +235,7 @@ module BerkeleyLibrary::Util
|
|
|
237
235
|
|
|
238
236
|
merged = Arrays.merge(a1, a2)
|
|
239
237
|
[a1, a2].each do |a|
|
|
240
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
238
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
241
239
|
end
|
|
242
240
|
|
|
243
241
|
expected = [1, 'two', 3, 'two', 'two', 4]
|
|
@@ -251,7 +249,7 @@ module BerkeleyLibrary::Util
|
|
|
251
249
|
|
|
252
250
|
merged = Arrays.merge(a1, a2)
|
|
253
251
|
[a1, a2].each do |a|
|
|
254
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
252
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
255
253
|
end
|
|
256
254
|
|
|
257
255
|
expected = a2
|
|
@@ -267,7 +265,7 @@ module BerkeleyLibrary::Util
|
|
|
267
265
|
|
|
268
266
|
merged = Arrays.merge(a1, a2)
|
|
269
267
|
[a1, a2].each do |a|
|
|
270
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
268
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
271
269
|
end
|
|
272
270
|
|
|
273
271
|
expected = [1, 2, 3, 4, 5, 6, 9]
|
|
@@ -283,7 +281,7 @@ module BerkeleyLibrary::Util
|
|
|
283
281
|
|
|
284
282
|
merged = Arrays.merge(a1, a2)
|
|
285
283
|
[a1, a2].each do |a|
|
|
286
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
284
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
287
285
|
end
|
|
288
286
|
|
|
289
287
|
expected = [1, 6, 9, 2, 3, 4, 5]
|
|
@@ -299,7 +297,7 @@ module BerkeleyLibrary::Util
|
|
|
299
297
|
|
|
300
298
|
merged = Arrays.merge(a1, a2)
|
|
301
299
|
[a1, a2].each do |a|
|
|
302
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
300
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
303
301
|
end
|
|
304
302
|
|
|
305
303
|
expected = [1, 2, 3, 4, 5, 6, 9]
|
|
@@ -319,7 +317,7 @@ module BerkeleyLibrary::Util
|
|
|
319
317
|
|
|
320
318
|
merged = Arrays.merge(a1, a2)
|
|
321
319
|
[a1, a2].each do |a|
|
|
322
|
-
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to
|
|
320
|
+
expect(Arrays.ordered_superset?(superset: merged, subset: a)).to be(true), "merge(#{[a1.join, a2.join].inspect}): #{a.join} not found in #{merged.join}"
|
|
323
321
|
end
|
|
324
322
|
end
|
|
325
323
|
end
|
|
@@ -14,42 +14,42 @@ module BerkeleyLibrary
|
|
|
14
14
|
describe :file_exists? do
|
|
15
15
|
it 'returns true for files that exist' do
|
|
16
16
|
path = Pathname.new(tmpdir).join('exists').tap { |p| FileUtils.touch(p) }
|
|
17
|
-
expect(path.exist?).to
|
|
17
|
+
expect(path.exist?).to be(true) # just to be sure
|
|
18
18
|
path_str = path.to_s
|
|
19
19
|
|
|
20
|
-
expect(Files.file_exists?(path)).to
|
|
21
|
-
expect(Files.file_exists?(path_str)).to
|
|
20
|
+
expect(Files.file_exists?(path)).to be(true)
|
|
21
|
+
expect(Files.file_exists?(path_str)).to be(true)
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it 'returns false for files that do not exist' do
|
|
25
25
|
path = Pathname.new(tmpdir).join('not-exists')
|
|
26
|
-
expect(path.exist?).to
|
|
26
|
+
expect(path.exist?).to be(false) # just to be sure
|
|
27
27
|
path_str = path.to_s
|
|
28
28
|
|
|
29
|
-
expect(Files.file_exists?(path)).to
|
|
30
|
-
expect(Files.file_exists?(path_str)).to
|
|
29
|
+
expect(Files.file_exists?(path)).to be(false)
|
|
30
|
+
expect(Files.file_exists?(path_str)).to be(false)
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
describe :parent_exists? do
|
|
35
35
|
it 'returns true for paths whose parent exists' do
|
|
36
36
|
parent = Pathname.new(tmpdir).join('parent').tap(&:mkdir)
|
|
37
|
-
expect(parent.exist?).to
|
|
37
|
+
expect(parent.exist?).to be(true) # just to be sure
|
|
38
38
|
path = parent.join('child')
|
|
39
39
|
path_str = path.to_s
|
|
40
40
|
|
|
41
|
-
expect(Files.parent_exists?(path)).to
|
|
42
|
-
expect(Files.parent_exists?(path_str)).to
|
|
41
|
+
expect(Files.parent_exists?(path)).to be(true)
|
|
42
|
+
expect(Files.parent_exists?(path_str)).to be(true)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
it 'returns false for paths whose parent does not' do
|
|
46
46
|
parent = Pathname.new(tmpdir).join('parent')
|
|
47
|
-
expect(parent.exist?).to
|
|
47
|
+
expect(parent.exist?).to be(false) # just to be sure
|
|
48
48
|
path = parent.join('child')
|
|
49
49
|
path_str = path.to_s
|
|
50
50
|
|
|
51
|
-
expect(Files.parent_exists?(path)).to
|
|
52
|
-
expect(Files.parent_exists?(path_str)).to
|
|
51
|
+
expect(Files.parent_exists?(path)).to be(false)
|
|
52
|
+
expect(Files.parent_exists?(path_str)).to be(false)
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
@@ -59,19 +59,19 @@ module BerkeleyLibrary
|
|
|
59
59
|
FileUtils.touch(filename)
|
|
60
60
|
|
|
61
61
|
File.open(filename, 'rb') do |out|
|
|
62
|
-
expect(Files.reader_like?(out)).to
|
|
62
|
+
expect(Files.reader_like?(out)).to be(true)
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
it 'returns true for a StringIO' do
|
|
67
67
|
out = StringIO.new
|
|
68
|
-
expect(Files.reader_like?(out)).to
|
|
68
|
+
expect(Files.reader_like?(out)).to be(true)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
it 'returns true for a Tempfile' do
|
|
72
72
|
out = Tempfile.new('out')
|
|
73
73
|
begin
|
|
74
|
-
expect(Files.reader_like?(out)).to
|
|
74
|
+
expect(Files.reader_like?(out)).to be(true)
|
|
75
75
|
ensure
|
|
76
76
|
out.close
|
|
77
77
|
out.unlink
|
|
@@ -79,7 +79,7 @@ module BerkeleyLibrary
|
|
|
79
79
|
end
|
|
80
80
|
|
|
81
81
|
it 'returns false for something that is not reader-like' do
|
|
82
|
-
expect(Files.reader_like?('not an IO')).to
|
|
82
|
+
expect(Files.reader_like?('not an IO')).to be(false)
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
@@ -88,19 +88,19 @@ module BerkeleyLibrary
|
|
|
88
88
|
filename = File.join(tmpdir, 'out')
|
|
89
89
|
|
|
90
90
|
File.open(filename, 'wb') do |out|
|
|
91
|
-
expect(Files.writer_like?(out)).to
|
|
91
|
+
expect(Files.writer_like?(out)).to be(true)
|
|
92
92
|
end
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
it 'returns true for a StringIO' do
|
|
96
96
|
out = StringIO.new
|
|
97
|
-
expect(Files.writer_like?(out)).to
|
|
97
|
+
expect(Files.writer_like?(out)).to be(true)
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it 'returns true for a Tempfile' do
|
|
101
101
|
out = Tempfile.new('out')
|
|
102
102
|
begin
|
|
103
|
-
expect(Files.writer_like?(out)).to
|
|
103
|
+
expect(Files.writer_like?(out)).to be(true)
|
|
104
104
|
ensure
|
|
105
105
|
out.close
|
|
106
106
|
out.unlink
|
|
@@ -108,7 +108,7 @@ module BerkeleyLibrary
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
it 'returns false for something that is not writer-like' do
|
|
111
|
-
expect(Files.writer_like?('not an IO')).to
|
|
111
|
+
expect(Files.writer_like?('not an IO')).to be(false)
|
|
112
112
|
end
|
|
113
113
|
end
|
|
114
114
|
end
|
|
@@ -6,7 +6,7 @@ module BerkeleyLibrary
|
|
|
6
6
|
describe :ascii_numeric do
|
|
7
7
|
it 'returns true for ASCII numeric strings' do
|
|
8
8
|
str = '8675309'
|
|
9
|
-
expect(Strings.ascii_numeric?(str)).to
|
|
9
|
+
expect(Strings.ascii_numeric?(str)).to be(true)
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
it 'returns false for non-ASCII numeric strings' do
|
|
@@ -16,7 +16,7 @@ module BerkeleyLibrary
|
|
|
16
16
|
]
|
|
17
17
|
aggregate_failures 'non-ASCII numeric strings' do
|
|
18
18
|
strs.each do |str|
|
|
19
|
-
expect(Strings.ascii_numeric?(str)).to
|
|
19
|
+
expect(Strings.ascii_numeric?(str)).to be(false), "Expected #{str.inspect} to be non-ASCII-numeric"
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -29,7 +29,7 @@ module BerkeleyLibrary
|
|
|
29
29
|
]
|
|
30
30
|
aggregate_failures 'ASCII mixed numeric and non-numeric strings' do
|
|
31
31
|
strs.each do |str|
|
|
32
|
-
expect(Strings.ascii_numeric?(str)).to
|
|
32
|
+
expect(Strings.ascii_numeric?(str)).to be(false), "Expected #{str.inspect} to be non-ASCII-numeric"
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'okcomputer'
|
|
3
|
+
require 'berkeley_library/util/uris/head_check'
|
|
4
|
+
require 'base64'
|
|
5
|
+
|
|
6
|
+
module BerkeleyLibrary
|
|
7
|
+
module Util
|
|
8
|
+
RSpec.describe HeadCheck do
|
|
9
|
+
let(:url) { 'http://example.com' }
|
|
10
|
+
let(:check) { described_class.new(url) }
|
|
11
|
+
let(:mock_response) { instance_double(RestClient::Response) }
|
|
12
|
+
|
|
13
|
+
before do
|
|
14
|
+
allow(BerkeleyLibrary::Util::URIs).to receive(:head_response).and_return(mock_response)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe '#perform_request' do
|
|
18
|
+
context 'without basic auth' do
|
|
19
|
+
it 'does not add Authorization header' do
|
|
20
|
+
check.perform_request
|
|
21
|
+
expect(BerkeleyLibrary::Util::URIs).not_to have_received(:head_response).with(anything, hash_including('Authorization' => anything), anything)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'calls URIs.head_response with the correct URL' do
|
|
25
|
+
check.perform_request
|
|
26
|
+
expect(BerkeleyLibrary::Util::URIs).to have_received(:head_response).with(URI(url), headers: {}, log: false, timeout: 5)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context 'with basic auth' do
|
|
31
|
+
let(:user) { 'user' }
|
|
32
|
+
let(:password) { 'pass' }
|
|
33
|
+
|
|
34
|
+
# Stub the configuration on the instance directly
|
|
35
|
+
before do
|
|
36
|
+
allow(check).to receive(:basic_auth_options).and_return([user, password])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'adds the Authorization header' do
|
|
40
|
+
expected_headers = { 'Authorization' => "Basic #{Base64.strict_encode64("#{user}:#{password}")}" }
|
|
41
|
+
|
|
42
|
+
check.perform_request
|
|
43
|
+
expect(BerkeleyLibrary::Util::URIs).to have_received(:head_response).with(URI(url), headers: expected_headers, log: false, timeout: 5)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context 'when URIs.head_response raises an error' do
|
|
48
|
+
let(:error_message) { 'Something went wrong' }
|
|
49
|
+
|
|
50
|
+
before do
|
|
51
|
+
allow(BerkeleyLibrary::Util::URIs).to receive(:head_response).and_raise(StandardError, error_message)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'raises an OkComputer::HttpCheck::ConnectionFailed error' do
|
|
55
|
+
expect { check.perform_request }.to raise_error(OkComputer::HttpCheck::ConnectionFailed, error_message)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -305,6 +305,13 @@ module BerkeleyLibrary
|
|
|
305
305
|
requester = Requester.new(:get, url)
|
|
306
306
|
expect { requester.make_request }.to raise_error(RestClient::ServiceUnavailable)
|
|
307
307
|
end
|
|
308
|
+
|
|
309
|
+
it "raises #{RestClient::Exceptions::Timeout} when the request times out" do
|
|
310
|
+
url = 'http://example.edu/timeout'
|
|
311
|
+
stub_request(:get, url).to_raise(RestClient::Exceptions::Timeout)
|
|
312
|
+
|
|
313
|
+
expect { Requester.get(url, timeout: 10) }.to raise_error(RestClient::Exceptions::Timeout)
|
|
314
|
+
end
|
|
308
315
|
end
|
|
309
316
|
end
|
|
310
317
|
end
|
|
@@ -374,6 +381,13 @@ module BerkeleyLibrary
|
|
|
374
381
|
end
|
|
375
382
|
end
|
|
376
383
|
|
|
384
|
+
it "raises #{RestClient::Exceptions::Timeout} when the request times out" do
|
|
385
|
+
url = 'http://example.edu/timeout'
|
|
386
|
+
stub_request(:head, url).to_raise(RestClient::Exceptions::Timeout)
|
|
387
|
+
|
|
388
|
+
expect { Requester.head(url, timeout: 10) }.to raise_error(RestClient::Exceptions::Timeout)
|
|
389
|
+
end
|
|
390
|
+
|
|
377
391
|
it 'handles redirects' do
|
|
378
392
|
url1 = 'https://example.org/'
|
|
379
393
|
url2 = 'https://example.edu/'
|
metadata
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: berkeley_library-util
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- David Moles
|
|
8
|
+
- maría a. matienzo
|
|
9
|
+
- Jason Raitz
|
|
8
10
|
autorequire:
|
|
9
11
|
bindir: bin
|
|
10
12
|
cert_chain: []
|
|
11
|
-
date:
|
|
13
|
+
date: 2026-02-04 00:00:00.000000000 Z
|
|
12
14
|
dependencies:
|
|
13
15
|
- !ruby/object:Gem::Dependency
|
|
14
16
|
name: berkeley_library-logging
|
|
@@ -16,14 +18,14 @@ dependencies:
|
|
|
16
18
|
requirements:
|
|
17
19
|
- - "~>"
|
|
18
20
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0.
|
|
21
|
+
version: '0.3'
|
|
20
22
|
type: :runtime
|
|
21
23
|
prerelease: false
|
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
25
|
requirements:
|
|
24
26
|
- - "~>"
|
|
25
27
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0.
|
|
28
|
+
version: '0.3'
|
|
27
29
|
- !ruby/object:Gem::Dependency
|
|
28
30
|
name: rest-client
|
|
29
31
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,14 +74,14 @@ dependencies:
|
|
|
72
74
|
requirements:
|
|
73
75
|
- - "~>"
|
|
74
76
|
- !ruby/object:Gem::Version
|
|
75
|
-
version: '0
|
|
77
|
+
version: '1.0'
|
|
76
78
|
type: :development
|
|
77
79
|
prerelease: false
|
|
78
80
|
version_requirements: !ruby/object:Gem::Requirement
|
|
79
81
|
requirements:
|
|
80
82
|
- - "~>"
|
|
81
83
|
- !ruby/object:Gem::Version
|
|
82
|
-
version: '0
|
|
84
|
+
version: '1.0'
|
|
83
85
|
- !ruby/object:Gem::Dependency
|
|
84
86
|
name: dotenv
|
|
85
87
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -94,6 +96,20 @@ dependencies:
|
|
|
94
96
|
- - "~>"
|
|
95
97
|
- !ruby/object:Gem::Version
|
|
96
98
|
version: '2.7'
|
|
99
|
+
- !ruby/object:Gem::Dependency
|
|
100
|
+
name: okcomputer
|
|
101
|
+
requirement: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - "~>"
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '1.19'
|
|
106
|
+
type: :development
|
|
107
|
+
prerelease: false
|
|
108
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
109
|
+
requirements:
|
|
110
|
+
- - "~>"
|
|
111
|
+
- !ruby/object:Gem::Version
|
|
112
|
+
version: '1.19'
|
|
97
113
|
- !ruby/object:Gem::Dependency
|
|
98
114
|
name: rake
|
|
99
115
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -126,58 +142,58 @@ dependencies:
|
|
|
126
142
|
name: rubocop
|
|
127
143
|
requirement: !ruby/object:Gem::Requirement
|
|
128
144
|
requirements:
|
|
129
|
-
- -
|
|
145
|
+
- - "~>"
|
|
130
146
|
- !ruby/object:Gem::Version
|
|
131
|
-
version:
|
|
147
|
+
version: 1.78.0
|
|
132
148
|
type: :development
|
|
133
149
|
prerelease: false
|
|
134
150
|
version_requirements: !ruby/object:Gem::Requirement
|
|
135
151
|
requirements:
|
|
136
|
-
- -
|
|
152
|
+
- - "~>"
|
|
137
153
|
- !ruby/object:Gem::Version
|
|
138
|
-
version:
|
|
154
|
+
version: 1.78.0
|
|
139
155
|
- !ruby/object:Gem::Dependency
|
|
140
156
|
name: rubocop-rake
|
|
141
157
|
requirement: !ruby/object:Gem::Requirement
|
|
142
158
|
requirements:
|
|
143
|
-
- -
|
|
159
|
+
- - "~>"
|
|
144
160
|
- !ruby/object:Gem::Version
|
|
145
|
-
version: 0.
|
|
161
|
+
version: 0.7.1
|
|
146
162
|
type: :development
|
|
147
163
|
prerelease: false
|
|
148
164
|
version_requirements: !ruby/object:Gem::Requirement
|
|
149
165
|
requirements:
|
|
150
|
-
- -
|
|
166
|
+
- - "~>"
|
|
151
167
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: 0.
|
|
168
|
+
version: 0.7.1
|
|
153
169
|
- !ruby/object:Gem::Dependency
|
|
154
170
|
name: rubocop-rspec
|
|
155
171
|
requirement: !ruby/object:Gem::Requirement
|
|
156
172
|
requirements:
|
|
157
|
-
- -
|
|
173
|
+
- - "~>"
|
|
158
174
|
- !ruby/object:Gem::Version
|
|
159
|
-
version:
|
|
175
|
+
version: 3.6.0
|
|
160
176
|
type: :development
|
|
161
177
|
prerelease: false
|
|
162
178
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
179
|
requirements:
|
|
164
|
-
- -
|
|
180
|
+
- - "~>"
|
|
165
181
|
- !ruby/object:Gem::Version
|
|
166
|
-
version:
|
|
182
|
+
version: 3.6.0
|
|
167
183
|
- !ruby/object:Gem::Dependency
|
|
168
184
|
name: ruby-prof
|
|
169
185
|
requirement: !ruby/object:Gem::Requirement
|
|
170
186
|
requirements:
|
|
171
|
-
- - "
|
|
187
|
+
- - ">="
|
|
172
188
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: 0
|
|
189
|
+
version: '0'
|
|
174
190
|
type: :development
|
|
175
191
|
prerelease: false
|
|
176
192
|
version_requirements: !ruby/object:Gem::Requirement
|
|
177
193
|
requirements:
|
|
178
|
-
- - "
|
|
194
|
+
- - ">="
|
|
179
195
|
- !ruby/object:Gem::Version
|
|
180
|
-
version: 0
|
|
196
|
+
version: '0'
|
|
181
197
|
- !ruby/object:Gem::Dependency
|
|
182
198
|
name: simplecov
|
|
183
199
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -207,12 +223,16 @@ dependencies:
|
|
|
207
223
|
- !ruby/object:Gem::Version
|
|
208
224
|
version: '3.12'
|
|
209
225
|
description: A collection of miscellaneous Ruby routines for the UC Berkeley Library.
|
|
210
|
-
email:
|
|
226
|
+
email:
|
|
227
|
+
- dmoles@berkeley.edu
|
|
228
|
+
- matienzo@berkeley.edu
|
|
229
|
+
- raitz@berkeley.edu
|
|
211
230
|
executables: []
|
|
212
231
|
extensions: []
|
|
213
232
|
extra_rdoc_files: []
|
|
214
233
|
files:
|
|
215
234
|
- ".github/workflows/build.yml"
|
|
235
|
+
- ".github/workflows/gem-push.yml"
|
|
216
236
|
- ".gitignore"
|
|
217
237
|
- ".idea/.gitignore"
|
|
218
238
|
- ".idea/inspectionProfiles/Project_Default.xml"
|
|
@@ -225,11 +245,13 @@ files:
|
|
|
225
245
|
- ".simplecov"
|
|
226
246
|
- ".yardopts"
|
|
227
247
|
- CHANGES.md
|
|
248
|
+
- Dockerfile
|
|
228
249
|
- Gemfile
|
|
229
250
|
- LICENSE.md
|
|
230
251
|
- README.md
|
|
231
252
|
- Rakefile
|
|
232
253
|
- berkeley_library-util.gemspec
|
|
254
|
+
- docker-compose.yml
|
|
233
255
|
- lib/berkeley_library/util.rb
|
|
234
256
|
- lib/berkeley_library/util/arrays.rb
|
|
235
257
|
- lib/berkeley_library/util/files.rb
|
|
@@ -242,6 +264,7 @@ files:
|
|
|
242
264
|
- lib/berkeley_library/util/uris.rb
|
|
243
265
|
- lib/berkeley_library/util/uris/appender.rb
|
|
244
266
|
- lib/berkeley_library/util/uris/exceptions.rb
|
|
267
|
+
- lib/berkeley_library/util/uris/head_check.rb
|
|
245
268
|
- lib/berkeley_library/util/uris/requester.rb
|
|
246
269
|
- lib/berkeley_library/util/uris/requester/class_methods.rb
|
|
247
270
|
- lib/berkeley_library/util/uris/validator.rb
|
|
@@ -257,6 +280,7 @@ files:
|
|
|
257
280
|
- spec/berkeley_library/util/stringios_spec.rb
|
|
258
281
|
- spec/berkeley_library/util/strings_spec.rb
|
|
259
282
|
- spec/berkeley_library/util/times_spec.rb
|
|
283
|
+
- spec/berkeley_library/util/uris/head_check_spec.rb
|
|
260
284
|
- spec/berkeley_library/util/uris/requester_spec.rb
|
|
261
285
|
- spec/berkeley_library/util/uris/validator_spec.rb
|
|
262
286
|
- spec/berkeley_library/util/uris_spec.rb
|
|
@@ -272,16 +296,16 @@ require_paths:
|
|
|
272
296
|
- lib
|
|
273
297
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
274
298
|
requirements:
|
|
275
|
-
- - "
|
|
299
|
+
- - "~>"
|
|
276
300
|
- !ruby/object:Gem::Version
|
|
277
|
-
version: '
|
|
301
|
+
version: '3.3'
|
|
278
302
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
279
303
|
requirements:
|
|
280
304
|
- - ">="
|
|
281
305
|
- !ruby/object:Gem::Version
|
|
282
306
|
version: '0'
|
|
283
307
|
requirements: []
|
|
284
|
-
rubygems_version: 3.
|
|
308
|
+
rubygems_version: 3.5.22
|
|
285
309
|
signing_key:
|
|
286
310
|
specification_version: 4
|
|
287
311
|
summary: Miscellaneous Ruby utilities for the UC Berkeley Library
|