berkeley_library-util 0.1.0 → 0.1.3

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: ab2d3fd2a0a839a3d733b0280ebff5b9b260b4cec4c2b06c6bdbe065d1b25871
4
- data.tar.gz: dcd700d56670c53e894e59239b9b90ab740d9761f7c80e67340428d357c290d1
3
+ metadata.gz: c52542412eba63da568f64ede565f97e941321d108f42e89920341df02a268b2
4
+ data.tar.gz: 3a56f6a5dd154c44d3d94e601f3093a8c4aca81e05fb3f7e18cd70ca6389f930
5
5
  SHA512:
6
- metadata.gz: 662ad15a9f80a79a379d70aa7fb4672b2f6e7adf3232796b6e814d238cb984ee8ebbc8e481d188d9fa92316929eb9e826a569eb5ccf6eb5892d96e6f0fa37d60
7
- data.tar.gz: 3bee84460660635c47f88102b0dc554ae0d5120089541d5733a45e785ab0ac8cfd56269beecf1d324b6174a594ab68b8133f4bc2a66db75d31d928c2c7390101
6
+ metadata.gz: 0ff8d42319d6faa217bb540d7276a7dd48499a9660242a3c875496594105a16a6bd63190ea234781b8950d269548d4400cabcf87292a161eb16cf8f5a3d205b8
7
+ data.tar.gz: ebfbe371422bbbb59587d583409200968742511013aa49df1f2922df5c9880102c3014ebe7622a7be663cd327a5a742f69c622e8369a912929edad1cc4a0b4fe
@@ -11,6 +11,10 @@
11
11
  <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
12
12
  <inspection_tool class="Rubocop" enabled="false" level="WARNING" enabled_by_default="false" />
13
13
  <inspection_tool class="RubyCaseWithoutElseBlockInspection" enabled="false" level="WARNING" enabled_by_default="false" />
14
+ <inspection_tool class="RubyMismatchedReturnType" enabled="true" level="WARNING" enabled_by_default="true">
15
+ <option name="myCheckNilability" value="false" />
16
+ </inspection_tool>
17
+ <inspection_tool class="RubyNilAnalysis" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
14
18
  <inspection_tool class="RubyStringKeysInHashInspection" enabled="true" level="INFORMATION" enabled_by_default="true" />
15
19
  <inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
16
20
  <option name="processCode" value="true" />
data/.idea/util.iml CHANGED
@@ -1,28 +1,31 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <module type="RUBY_MODULE" version="4">
3
+ <component name="ModuleRunConfigurationManager">
4
+ <shared />
5
+ </component>
3
6
  <component name="NewModuleRootManager" inherit-compiler-output="true">
4
7
  <exclude-output />
5
8
  <content url="file://$MODULE_DIR$" />
6
9
  <orderEntry type="jdk" jdkName="RVM: ruby-2.7.4" jdkType="RUBY_SDK" />
7
10
  <orderEntry type="sourceFolder" forTests="false" />
8
- <orderEntry type="library" scope="PROVIDED" name="actionpack (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
9
- <orderEntry type="library" scope="PROVIDED" name="actionview (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
10
- <orderEntry type="library" scope="PROVIDED" name="activesupport (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
11
+ <orderEntry type="library" scope="PROVIDED" name="actionpack (v7.0.2.4, RVM: ruby-2.7.4) [gem]" level="application" />
12
+ <orderEntry type="library" scope="PROVIDED" name="actionview (v7.0.2.4, RVM: ruby-2.7.4) [gem]" level="application" />
13
+ <orderEntry type="library" scope="PROVIDED" name="activesupport (v7.0.2.4, RVM: ruby-2.7.4) [gem]" level="application" />
11
14
  <orderEntry type="library" scope="PROVIDED" name="addressable (v2.8.0, RVM: ruby-2.7.4) [gem]" level="application" />
12
- <orderEntry type="library" scope="PROVIDED" name="amazing_print (v1.3.0, RVM: ruby-2.7.4) [gem]" level="application" />
15
+ <orderEntry type="library" scope="PROVIDED" name="amazing_print (v1.4.0, RVM: ruby-2.7.4) [gem]" level="application" />
13
16
  <orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, RVM: ruby-2.7.4) [gem]" level="application" />
14
- <orderEntry type="library" scope="PROVIDED" name="berkeley_library-logging (v0.2.3, RVM: ruby-2.7.4) [gem]" level="application" />
17
+ <orderEntry type="library" scope="PROVIDED" name="berkeley_library-logging (v0.2.6, RVM: ruby-2.7.4) [gem]" level="application" />
15
18
  <orderEntry type="library" scope="PROVIDED" name="builder (v3.2.4, RVM: ruby-2.7.4) [gem]" level="application" />
16
19
  <orderEntry type="library" scope="PROVIDED" name="bundle-audit (v0.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
17
- <orderEntry type="library" scope="PROVIDED" name="bundler (v2.2.14, RVM: ruby-2.7.4) [gem]" level="application" />
20
+ <orderEntry type="library" scope="PROVIDED" name="bundler (v2.2.31, RVM: ruby-2.7.4) [gem]" level="application" />
18
21
  <orderEntry type="library" scope="PROVIDED" name="bundler-audit (v0.9.0.1, RVM: ruby-2.7.4) [gem]" level="application" />
19
22
  <orderEntry type="library" scope="PROVIDED" name="ci_reporter (v2.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
20
23
  <orderEntry type="library" scope="PROVIDED" name="ci_reporter_rspec (v1.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
21
24
  <orderEntry type="library" scope="PROVIDED" name="colorize (v0.8.1, RVM: ruby-2.7.4) [gem]" level="application" />
22
- <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.9, RVM: ruby-2.7.4) [gem]" level="application" />
25
+ <orderEntry type="library" scope="PROVIDED" name="concurrent-ruby (v1.1.10, RVM: ruby-2.7.4) [gem]" level="application" />
23
26
  <orderEntry type="library" scope="PROVIDED" name="crack (v0.4.5, RVM: ruby-2.7.4) [gem]" level="application" />
24
27
  <orderEntry type="library" scope="PROVIDED" name="crass (v1.0.6, RVM: ruby-2.7.4) [gem]" level="application" />
25
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.4.4, RVM: ruby-2.7.4) [gem]" level="application" />
28
+ <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.5.0, RVM: ruby-2.7.4) [gem]" level="application" />
26
29
  <orderEntry type="library" scope="PROVIDED" name="docile (v1.4.0, RVM: ruby-2.7.4) [gem]" level="application" />
27
30
  <orderEntry type="library" scope="PROVIDED" name="domain_name (v0.5.20190701, RVM: ruby-2.7.4) [gem]" level="application" />
28
31
  <orderEntry type="library" scope="PROVIDED" name="dotenv (v2.7.6, RVM: ruby-2.7.4) [gem]" level="application" />
@@ -30,55 +33,55 @@
30
33
  <orderEntry type="library" scope="PROVIDED" name="hashdiff (v1.0.1, RVM: ruby-2.7.4) [gem]" level="application" />
31
34
  <orderEntry type="library" scope="PROVIDED" name="http-accept (v1.7.0, RVM: ruby-2.7.4) [gem]" level="application" />
32
35
  <orderEntry type="library" scope="PROVIDED" name="http-cookie (v1.0.4, RVM: ruby-2.7.4) [gem]" level="application" />
33
- <orderEntry type="library" scope="PROVIDED" name="i18n (v1.8.10, RVM: ruby-2.7.4) [gem]" level="application" />
34
- <orderEntry type="library" scope="PROVIDED" name="lograge (v0.11.2, RVM: ruby-2.7.4) [gem]" level="application" />
35
- <orderEntry type="library" scope="PROVIDED" name="loofah (v2.12.0, RVM: ruby-2.7.4) [gem]" level="application" />
36
+ <orderEntry type="library" scope="PROVIDED" name="i18n (v1.10.0, RVM: ruby-2.7.4) [gem]" level="application" />
37
+ <orderEntry type="library" scope="PROVIDED" name="lograge (v0.12.0, RVM: ruby-2.7.4) [gem]" level="application" />
38
+ <orderEntry type="library" scope="PROVIDED" name="loofah (v2.17.0, RVM: ruby-2.7.4) [gem]" level="application" />
36
39
  <orderEntry type="library" scope="PROVIDED" name="method_source (v1.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
37
- <orderEntry type="library" scope="PROVIDED" name="mime-types (v3.3.1, RVM: ruby-2.7.4) [gem]" level="application" />
38
- <orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.2021.0901, RVM: ruby-2.7.4) [gem]" level="application" />
39
- <orderEntry type="library" scope="PROVIDED" name="minitest (v5.14.4, RVM: ruby-2.7.4) [gem]" level="application" />
40
+ <orderEntry type="library" scope="PROVIDED" name="mime-types (v3.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
41
+ <orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.2022.0105, RVM: ruby-2.7.4) [gem]" level="application" />
42
+ <orderEntry type="library" scope="PROVIDED" name="minitest (v5.15.0, RVM: ruby-2.7.4) [gem]" level="application" />
40
43
  <orderEntry type="library" scope="PROVIDED" name="netrc (v0.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
41
- <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.12.4, RVM: ruby-2.7.4) [gem]" level="application" />
42
- <orderEntry type="library" scope="PROVIDED" name="oj (v3.13.7, RVM: ruby-2.7.4) [gem]" level="application" />
44
+ <orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.13.5, RVM: ruby-2.7.4) [gem]" level="application" />
45
+ <orderEntry type="library" scope="PROVIDED" name="oj (v3.13.11, RVM: ruby-2.7.4) [gem]" level="application" />
43
46
  <orderEntry type="library" scope="PROVIDED" name="ougai (v1.9.1, RVM: ruby-2.7.4) [gem]" level="application" />
44
- <orderEntry type="library" scope="PROVIDED" name="parallel (v1.21.0, RVM: ruby-2.7.4) [gem]" level="application" />
45
- <orderEntry type="library" scope="PROVIDED" name="parser (v3.0.2.0, RVM: ruby-2.7.4) [gem]" level="application" />
46
- <orderEntry type="library" scope="PROVIDED" name="public_suffix (v4.0.6, RVM: ruby-2.7.4) [gem]" level="application" />
47
- <orderEntry type="library" scope="PROVIDED" name="racc (v1.5.2, RVM: ruby-2.7.4) [gem]" level="application" />
47
+ <orderEntry type="library" scope="PROVIDED" name="parallel (v1.22.1, RVM: ruby-2.7.4) [gem]" level="application" />
48
+ <orderEntry type="library" scope="PROVIDED" name="parser (v3.1.2.0, RVM: ruby-2.7.4) [gem]" level="application" />
49
+ <orderEntry type="library" scope="PROVIDED" name="public_suffix (v4.0.7, RVM: ruby-2.7.4) [gem]" level="application" />
50
+ <orderEntry type="library" scope="PROVIDED" name="racc (v1.6.0, RVM: ruby-2.7.4) [gem]" level="application" />
48
51
  <orderEntry type="library" scope="PROVIDED" name="rack (v2.2.3, RVM: ruby-2.7.4) [gem]" level="application" />
49
52
  <orderEntry type="library" scope="PROVIDED" name="rack-test (v1.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
50
53
  <orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v2.0.3, RVM: ruby-2.7.4) [gem]" level="application" />
51
54
  <orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.4.2, RVM: ruby-2.7.4) [gem]" level="application" />
52
- <orderEntry type="library" scope="PROVIDED" name="railties (v6.1.4.1, RVM: ruby-2.7.4) [gem]" level="application" />
53
- <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.0.0, RVM: ruby-2.7.4) [gem]" level="application" />
55
+ <orderEntry type="library" scope="PROVIDED" name="railties (v7.0.2.4, RVM: ruby-2.7.4) [gem]" level="application" />
56
+ <orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, RVM: ruby-2.7.4) [gem]" level="application" />
54
57
  <orderEntry type="library" scope="PROVIDED" name="rake (v13.0.6, RVM: ruby-2.7.4) [gem]" level="application" />
55
- <orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.1.1, RVM: ruby-2.7.4) [gem]" level="application" />
56
- <orderEntry type="library" scope="PROVIDED" name="request_store (v1.5.0, RVM: ruby-2.7.4) [gem]" level="application" />
58
+ <orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.3.1, RVM: ruby-2.7.4) [gem]" level="application" />
59
+ <orderEntry type="library" scope="PROVIDED" name="request_store (v1.5.1, RVM: ruby-2.7.4) [gem]" level="application" />
57
60
  <orderEntry type="library" scope="PROVIDED" name="rest-client (v2.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
58
61
  <orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.5, RVM: ruby-2.7.4) [gem]" level="application" />
59
- <orderEntry type="library" scope="PROVIDED" name="rspec (v3.10.0, RVM: ruby-2.7.4) [gem]" level="application" />
60
- <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.10.1, RVM: ruby-2.7.4) [gem]" level="application" />
61
- <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.10.1, RVM: ruby-2.7.4) [gem]" level="application" />
62
- <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.10.2, RVM: ruby-2.7.4) [gem]" level="application" />
63
- <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.10.2, RVM: ruby-2.7.4) [gem]" level="application" />
62
+ <orderEntry type="library" scope="PROVIDED" name="rspec (v3.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
63
+ <orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
64
+ <orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
65
+ <orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.11.1, RVM: ruby-2.7.4) [gem]" level="application" />
66
+ <orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
64
67
  <orderEntry type="library" scope="PROVIDED" name="rubocop (v1.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
65
- <orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
68
+ <orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.17.0, RVM: ruby-2.7.4) [gem]" level="application" />
66
69
  <orderEntry type="library" scope="PROVIDED" name="rubocop-rake (v0.6.0, RVM: ruby-2.7.4) [gem]" level="application" />
67
70
  <orderEntry type="library" scope="PROVIDED" name="rubocop-rspec (v2.4.0, RVM: ruby-2.7.4) [gem]" level="application" />
68
71
  <orderEntry type="library" scope="PROVIDED" name="ruby-prof (v0.17.0, RVM: ruby-2.7.4) [gem]" level="application" />
69
72
  <orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.11.0, RVM: ruby-2.7.4) [gem]" level="application" />
70
73
  <orderEntry type="library" scope="PROVIDED" name="simplecov (v0.21.2, RVM: ruby-2.7.4) [gem]" level="application" />
71
74
  <orderEntry type="library" scope="PROVIDED" name="simplecov-html (v0.12.3, RVM: ruby-2.7.4) [gem]" level="application" />
72
- <orderEntry type="library" scope="PROVIDED" name="simplecov-rcov (v0.2.3, RVM: ruby-2.7.4) [gem]" level="application" />
73
- <orderEntry type="library" scope="PROVIDED" name="simplecov_json_formatter (v0.1.3, RVM: ruby-2.7.4) [gem]" level="application" />
74
- <orderEntry type="library" scope="PROVIDED" name="thor (v1.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
75
+ <orderEntry type="library" scope="PROVIDED" name="simplecov-rcov (v0.3.1, RVM: ruby-2.7.4) [gem]" level="application" />
76
+ <orderEntry type="library" scope="PROVIDED" name="simplecov_json_formatter (v0.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
77
+ <orderEntry type="library" scope="PROVIDED" name="thor (v1.2.1, RVM: ruby-2.7.4) [gem]" level="application" />
75
78
  <orderEntry type="library" scope="PROVIDED" name="typesafe_enum (v0.3.0, RVM: ruby-2.7.4) [gem]" level="application" />
76
79
  <orderEntry type="library" scope="PROVIDED" name="tzinfo (v2.0.4, RVM: ruby-2.7.4) [gem]" level="application" />
77
80
  <orderEntry type="library" scope="PROVIDED" name="unf (v0.1.4, RVM: ruby-2.7.4) [gem]" level="application" />
78
- <orderEntry type="library" scope="PROVIDED" name="unf_ext (v0.0.8, RVM: ruby-2.7.4) [gem]" level="application" />
81
+ <orderEntry type="library" scope="PROVIDED" name="unf_ext (v0.0.8.1, RVM: ruby-2.7.4) [gem]" level="application" />
79
82
  <orderEntry type="library" scope="PROVIDED" name="unicode-display_width (v2.1.0, RVM: ruby-2.7.4) [gem]" level="application" />
80
83
  <orderEntry type="library" scope="PROVIDED" name="webmock (v3.14.0, RVM: ruby-2.7.4) [gem]" level="application" />
81
- <orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.4.2, RVM: ruby-2.7.4) [gem]" level="application" />
84
+ <orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.5.4, RVM: ruby-2.7.4) [gem]" level="application" />
82
85
  </component>
83
86
  <component name="RModuleSettingsStorage">
84
87
  <LOAD_PATH number="2" string0="$MODULE_DIR$/lib" string1="$MODULE_DIR$/spec" />
@@ -95,7 +98,7 @@
95
98
  </RakeTaskImpl>
96
99
  <RakeTaskImpl description="Run all specs in spec directory, with coverage" fullCommand="coverage" id="coverage" />
97
100
  <RakeTaskImpl description="Run tests, check test coverage, check code style, check for vulnerabilities, build gem" fullCommand="default" id="default" />
98
- <RakeTaskImpl description="Build berkeley_library-util.gemspec as berkeley_library-util-0.1.0.gem" fullCommand="gem" id="gem" />
101
+ <RakeTaskImpl description="Build berkeley_library-util.gemspec as berkeley_library-util-0.1.1.gem" fullCommand="gem" id="gem" />
99
102
  <RakeTaskImpl description="Run RuboCop with auto-correct, and output results to console" fullCommand="ra" id="ra" />
100
103
  <RakeTaskImpl description="Run rubocop with HTML output" fullCommand="rubocop" id="rubocop" />
101
104
  <RakeTaskImpl id="rubocop">
data/CHANGES.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 0.1.3 (2022-05-11)
2
+
3
+ - Adds `URIs#get_response`, which returns a complete `RestClient::Response` rather than just
4
+ the response body.
5
+
6
+ # 0.1.2 (2022-05-05)
7
+
8
+ - Adds `BerkeleyLibrary::Files`, which contains file and IO utility methods
9
+
10
+ # 0.1.1 (2021-09-23)
11
+
12
+ - `URIs#append` now handles bare URLs with empty paths, with the caveat that
13
+ a root path `/` will always be added, even if there are no path elements to append.
14
+
1
15
  # 0.1.0 (2021-09-23)
2
16
 
3
- Initial extraction of code from [`berkeley_library/tind`](https://github.com/BerkeleyLibrary/tind).
17
+ - Initial extraction of code from [`berkeley_library/tind`](https://github.com/BerkeleyLibrary/tind).
data/README.md CHANGED
@@ -7,15 +7,19 @@ Miscellaneous utility code for the UC Berkeley Library.
7
7
 
8
8
  ### Notable modules
9
9
 
10
- ## [BerkeleyLibrary::Util::Arrays](lib/berkeley_library/util/arrays.rb)]
10
+ ## [BerkeleyLibrary::Util::Arrays](lib/berkeley_library/util/arrays.rb)
11
11
 
12
12
  Routines for comparing, merging, and examining the contents of arrays.
13
13
 
14
- ## [BerkeleyLibrary::Util::Paths](lib/berkeley_library/util/paths.rb)]
14
+ ## [BerkeleyLibrary::Util::Paths](lib/berkeley_library/util/paths.rb)
15
15
 
16
16
  Routines for modifying paths separated by forward slashes,
17
17
  (such as URL paths), modeled on the [Go `path` package](https://golang.org/pkg/path/).
18
18
 
19
- ## [BerkeleyLibrary::Util::URIs](lib/berkeley_library/util/uris.rb)]
19
+ ## [BerkeleyLibrary::Util::URIs](lib/berkeley_library/util/uris.rb)
20
20
 
21
21
  Routines for constructing, validating, and retrieving the content from URIs.
22
+
23
+ ## [BerkeleyLibrary::Util::Files](lib/berkeley_library/util/files.rb)
24
+
25
+ Routines for working with file paths and IO objects.
@@ -0,0 +1,37 @@
1
+ module BerkeleyLibrary
2
+ module Util
3
+ module Files
4
+ class << self
5
+ include Files
6
+ end
7
+
8
+ def file_exists?(path)
9
+ (path.respond_to?(:exist?) && path.exist?) ||
10
+ (path.respond_to?(:to_str) && File.exist?(path))
11
+ end
12
+
13
+ def parent_exists?(path)
14
+ path.respond_to?(:parent) && path.parent.exist? ||
15
+ path.respond_to?(:to_str) && Pathname.new(path).parent.exist?
16
+ end
17
+
18
+ # Returns true if `obj` is close enough to an IO object for Nokogiri
19
+ # to parse as one.
20
+ #
21
+ # @param obj [Object] the object that might be an IO
22
+ # @see https://github.com/sparklemotion/nokogiri/blob/v1.11.1/lib/nokogiri/xml/sax/parser.rb#L81 Nokogiri::XML::SAX::Parser#parse
23
+ def reader_like?(obj)
24
+ obj.respond_to?(:read) && obj.respond_to?(:close)
25
+ end
26
+
27
+ # Returns true if `obj` is close enough to an IO object for Nokogiri
28
+ # to write to.
29
+ #
30
+ # @param obj [Object] the object that might be an IO
31
+ def writer_like?(obj)
32
+ obj.respond_to?(:write) && obj.respond_to?(:close)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -5,11 +5,9 @@ module BerkeleyLibrary
5
5
  AUTHOR = 'David Moles'.freeze
6
6
  AUTHOR_EMAIL = 'dmoles@berkeley.edu'.freeze
7
7
  SUMMARY = 'Miscellaneous Ruby utilities for the UC Berkeley Library'.freeze
8
- DESCRIPTION = <<~DESC.gsub(/\s+/, ' ').strip
9
- A collection of miscellaneous Ruby routines for the UC Berkeley Library.
10
- DESC
8
+ DESCRIPTION = 'A collection of miscellaneous Ruby routines for the UC Berkeley Library.'.freeze
11
9
  LICENSE = 'MIT'.freeze
12
- VERSION = '0.1.0'.freeze
10
+ VERSION = '0.1.3'.freeze
13
11
  HOMEPAGE = 'https://github.com/BerkeleyLibrary/util'.freeze
14
12
  end
15
13
  end
@@ -55,6 +55,14 @@ module BerkeleyLibrary
55
55
  clean(joined_raw)
56
56
  end
57
57
 
58
+ def abs?(path)
59
+ path.to_s.start_with?('/')
60
+ end
61
+
62
+ def ensure_abs(path)
63
+ abs?(path) ? path : "/#{path}"
64
+ end
65
+
58
66
  private
59
67
 
60
68
  def process_next(r, dotdot, path, out)
@@ -35,7 +35,8 @@ module BerkeleyLibrary
35
35
  # @raise URI::InvalidComponentError if appending the specified elements would create an invalid URI
36
36
  def to_uri
37
37
  original_uri.dup.tap do |new_uri|
38
- new_uri.path = Paths.join(original_uri.path, *path_elements)
38
+ new_path = Paths.join(new_uri.path, *path_elements)
39
+ new_uri.path = Paths.ensure_abs(new_path)
39
40
  new_uri.query = query unless query_elements.empty?
40
41
  new_uri.fragment = fragment unless fragment_elements.empty?
41
42
  end
@@ -10,7 +10,7 @@ module BerkeleyLibrary
10
10
  class << self
11
11
  include BerkeleyLibrary::Logging
12
12
 
13
- # Performs a GET request.
13
+ # Performs a GET request and returns the response body as a string.
14
14
  #
15
15
  # @param uri [URI, String] the URI to GET
16
16
  # @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
@@ -18,18 +18,36 @@ module BerkeleyLibrary
18
18
  # @return [String] the body as a string.
19
19
  # @raise [RestClient::Exception] in the event of an error.
20
20
  def get(uri, params: {}, headers: {})
21
- url_str = url_str_with_params(uri, params)
22
- resp = get_or_raise(url_str, headers)
21
+ resp = make_get_request(uri, params, headers)
23
22
  resp.body
24
23
  end
25
24
 
25
+ # Performs a GET request and returns the response.
26
+ #
27
+ # @param uri [URI, String] the URI to GET
28
+ # @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
29
+ # @param headers [Hash] the request headers.
30
+ # @return [RestClient::Response] the body as a string.
31
+ def get_response(uri, params: {}, headers: {})
32
+ make_get_request(uri, params, headers)
33
+ rescue RestClient::Exception => e
34
+ e.response
35
+ end
36
+
26
37
  private
27
38
 
39
+ def make_get_request(uri, params, headers)
40
+ url_str = url_str_with_params(uri, params)
41
+ get_or_raise(url_str, headers)
42
+ end
43
+
28
44
  def url_str_with_params(uri, params)
29
45
  raise ArgumentError, 'uri cannot be nil' unless (url_str = Validator.url_str_or_nil(uri))
30
46
 
31
47
  elements = [].tap do |ee|
32
48
  ee << url_str
49
+ next if params.empty?
50
+
33
51
  ee << '?' unless url_str.include?('?')
34
52
  ee << URI.encode_www_form(params)
35
53
  end
@@ -38,6 +56,7 @@ module BerkeleyLibrary
38
56
  uri.to_s
39
57
  end
40
58
 
59
+ # @return [RestClient::Response]
41
60
  def get_or_raise(url_str, headers)
42
61
  resp = RestClient.get(url_str, headers)
43
62
  begin
@@ -45,6 +64,7 @@ module BerkeleyLibrary
45
64
 
46
65
  raise(exception_for(resp, status))
47
66
  ensure
67
+ # noinspection RubyMismatchedReturnType
48
68
  logger.info("GET #{url_str} returned #{status}")
49
69
  end
50
70
  end
@@ -32,6 +32,16 @@ module BerkeleyLibrary
32
32
  Requester.get(uri, params: params, headers: headers)
33
33
  end
34
34
 
35
+ # Performs a GET request and returns the response.
36
+ #
37
+ # @param uri [URI, String] the URI to GET
38
+ # @param params [Hash] the query parameters to add to the URI. (Note that the URI may already include query parameters.)
39
+ # @param headers [Hash] the request headers.
40
+ # @return [RestClient::Response] the body as a string.
41
+ def get_response(uri, params: {}, headers: {})
42
+ Requester.get_response(uri, params: params, headers: headers)
43
+ end
44
+
35
45
  # Returns the specified URL as a URI.
36
46
  # @param url [String, URI] the URL.
37
47
  # @return [URI] the URI.
@@ -0,0 +1,115 @@
1
+ require 'spec_helper'
2
+
3
+ module BerkeleyLibrary
4
+ module Util
5
+ describe Files do
6
+ let(:basename) { File.basename(__FILE__, '.rb') }
7
+
8
+ attr_reader :tmpdir
9
+
10
+ before { @tmpdir = Dir.mktmpdir(basename) }
11
+ after { FileUtils.remove_entry(tmpdir) }
12
+
13
+ describe :file_exists? do
14
+ it 'returns true for files that exist' do
15
+ path = Pathname.new(tmpdir).join('exists').tap { |p| FileUtils.touch(p) }
16
+ expect(path.exist?).to eq(true) # just to be sure
17
+ path_str = path.to_s
18
+
19
+ expect(Files.file_exists?(path)).to eq(true)
20
+ expect(Files.file_exists?(path_str)).to eq(true)
21
+ end
22
+
23
+ it 'returns false for files that do not exist' do
24
+ path = Pathname.new(tmpdir).join('not-exists')
25
+ expect(path.exist?).to eq(false) # just to be sure
26
+ path_str = path.to_s
27
+
28
+ expect(Files.file_exists?(path)).to eq(false)
29
+ expect(Files.file_exists?(path_str)).to eq(false)
30
+ end
31
+ end
32
+
33
+ describe :parent_exists? do
34
+ it 'returns true for paths whose parent exists' do
35
+ parent = Pathname.new(tmpdir).join('parent').tap(&:mkdir)
36
+ expect(parent.exist?).to eq(true) # just to be sure
37
+ path = parent.join('child')
38
+ path_str = path.to_s
39
+
40
+ expect(Files.parent_exists?(path)).to eq(true)
41
+ expect(Files.parent_exists?(path_str)).to eq(true)
42
+ end
43
+
44
+ it 'returns false for paths whose parent does not' do
45
+ parent = Pathname.new(tmpdir).join('parent')
46
+ expect(parent.exist?).to eq(false) # just to be sure
47
+ path = parent.join('child')
48
+ path_str = path.to_s
49
+
50
+ expect(Files.parent_exists?(path)).to eq(false)
51
+ expect(Files.parent_exists?(path_str)).to eq(false)
52
+ end
53
+ end
54
+
55
+ describe :reader_like? do
56
+ it 'returns true for a readable file' do
57
+ filename = File.join(tmpdir, 'out')
58
+ FileUtils.touch(filename)
59
+
60
+ File.open(filename, 'rb') do |out|
61
+ expect(Files.reader_like?(out)).to eq(true)
62
+ end
63
+ end
64
+
65
+ it 'returns true for a StringIO' do
66
+ out = StringIO.new
67
+ expect(Files.reader_like?(out)).to eq(true)
68
+ end
69
+
70
+ it 'returns true for a Tempfile' do
71
+ out = Tempfile.new('out')
72
+ begin
73
+ expect(Files.reader_like?(out)).to eq(true)
74
+ ensure
75
+ out.close
76
+ out.unlink
77
+ end
78
+ end
79
+
80
+ it 'returns false for something that is not reader-like' do
81
+ expect(Files.reader_like?('not an IO')).to eq(false)
82
+ end
83
+ end
84
+
85
+ describe :writer_like? do
86
+ it 'returns true for a writable file' do
87
+ filename = File.join(tmpdir, 'out')
88
+
89
+ File.open(filename, 'wb') do |out|
90
+ expect(Files.writer_like?(out)).to eq(true)
91
+ end
92
+ end
93
+
94
+ it 'returns true for a StringIO' do
95
+ out = StringIO.new
96
+ expect(Files.writer_like?(out)).to eq(true)
97
+ end
98
+
99
+ it 'returns true for a Tempfile' do
100
+ out = Tempfile.new('out')
101
+ begin
102
+ expect(Files.writer_like?(out)).to eq(true)
103
+ ensure
104
+ out.close
105
+ out.unlink
106
+ end
107
+ end
108
+
109
+ it 'returns false for something that is not writer-like' do
110
+ expect(Files.writer_like?('not an IO')).to eq(false)
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -44,18 +44,15 @@ module BerkeleyLibrary
44
44
  expect(result).to eq(expected_body)
45
45
  end
46
46
 
47
- it 'raises an error for a failure status' do
48
- url = 'https://example.org/'
49
- stub_request(:get, url).to_return(status: 404)
50
-
51
- expect { Requester.get(url) }.to raise_error(RestClient::RequestFailed)
52
- end
53
-
54
- it 'raises an error for a weird non-failure status' do
55
- url = 'https://example.org/'
56
- stub_request(:get, url).to_return(status: 207)
47
+ it "raises #{RestClient::Exception} in the event of an invalid response" do
48
+ aggregate_failures 'responses' do
49
+ [207, 400, 401, 403, 404, 405, 418, 451, 500, 503].each do |code|
50
+ url = "http://example.edu/#{code}"
51
+ stub_request(:get, url).to_return(status: code)
57
52
 
58
- expect { Requester.get(url) }.to raise_error(RestClient::RequestFailed)
53
+ expect { Requester.get(url) }.to raise_error(RestClient::Exception)
54
+ end
55
+ end
59
56
  end
60
57
 
61
58
  it 'handles redirects' do
@@ -9,6 +9,29 @@ module BerkeleyLibrary::Util
9
9
  expect(new_uri).to eq(URI('https://example.org/foo/bar/qux/corge/garply'))
10
10
  end
11
11
 
12
+ it 'appends paths to bare URIs without root' do
13
+ original_url = 'https://example.org'
14
+ new_uri = URIs.append(original_url, 'foo', 'bar')
15
+ expected_uri = URI('https://example.org/foo/bar')
16
+ expect(new_uri).to eq(expected_uri)
17
+ end
18
+
19
+ # TODO: make this work
20
+ xit "doesn't append to a bare URI when there's nothing to append" do
21
+ original_url = 'https://example.org'
22
+ new_uri = URIs.append(original_url)
23
+ expected_uri = URI(original_url)
24
+ expect(new_uri).to eq(expected_uri)
25
+ end
26
+
27
+ # TODO: make this work
28
+ xit "doesn't append to a bare URI when there's only a query string" do
29
+ original_url = 'https://example.org'
30
+ new_uri = URIs.append(original_url, '?foo=bar')
31
+ expected_uri = URI("#{original_url}?foo=bar")
32
+ expect(new_uri).to eq(expected_uri)
33
+ end
34
+
12
35
  it 'does not modify the original URI' do
13
36
  original_uri = URI('https://example.org/foo/bar')
14
37
  original_url = original_uri.to_s
@@ -115,18 +138,44 @@ module BerkeleyLibrary::Util
115
138
  end
116
139
  end
117
140
 
118
- describe :get do
119
- it 'makes a GET request' do
120
- url = 'https://example.org/'
121
- params = { p1: 1, p2: 2 }
122
- headers = { 'X-help' => 'I am trapped in a unit test' }
141
+ describe 'requests' do
142
+ let(:url) { 'https://example.org/' }
143
+ let(:params) { { p1: 1, p2: 2 } }
144
+ let(:headers) { { 'X-help' => 'I am trapped in a unit test' } }
145
+ let(:url_with_query) { "#{url}?#{URI.encode_www_form(params)}" }
146
+ let(:expected_body) { 'Help! I am trapped in a unit test' }
147
+
148
+ describe :get do
149
+ it 'makes a GET request' do
150
+ stub_request(:get, url_with_query).with(headers: headers).to_return(body: expected_body)
151
+
152
+ result = URIs.get(url, params: params, headers: headers)
153
+ expect(result).to eq(expected_body)
154
+ end
155
+
156
+ it 'raises an error in the event of a 404' do
157
+ stub_request(:get, url_with_query).with(headers: headers).to_return(status: 404, body: expected_body)
158
+
159
+ expect { URIs.get(url, params: params, headers: headers) }.to raise_error(RestClient::NotFound)
160
+ end
161
+ end
162
+
163
+ describe :get_response do
164
+ it 'makes a GET request' do
165
+ stub_request(:get, url_with_query).with(headers: headers).to_return(body: expected_body)
166
+
167
+ response = URIs.get_response(url, params: params, headers: headers)
168
+ expect(response.body).to eq(expected_body)
169
+ expect(response.code).to eq(200)
170
+ end
123
171
 
124
- url_with_query = "#{url}?#{URI.encode_www_form(params)}"
125
- expected_body = 'Help! I am trapped in a unit test'
126
- stub_request(:get, url_with_query).with(headers: headers).to_return(body: expected_body)
172
+ it 'returns the response even for errors' do
173
+ stub_request(:get, url_with_query).with(headers: headers).to_return(status: 404, body: expected_body)
127
174
 
128
- result = URIs.get(url, params: params, headers: headers)
129
- expect(result).to eq(expected_body)
175
+ response = URIs.get_response(url, params: params, headers: headers)
176
+ expect(response.body).to eq(expected_body)
177
+ expect(response.code).to eq(404)
178
+ end
130
179
  end
131
180
  end
132
181
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: berkeley_library-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Moles
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-23 00:00:00.000000000 Z
11
+ date: 2022-05-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: berkeley_library-logging
@@ -260,6 +260,7 @@ files:
260
260
  - berkeley_library-util.gemspec
261
261
  - lib/berkeley_library/util.rb
262
262
  - lib/berkeley_library/util/arrays.rb
263
+ - lib/berkeley_library/util/files.rb
263
264
  - lib/berkeley_library/util/module_info.rb
264
265
  - lib/berkeley_library/util/paths.rb
265
266
  - lib/berkeley_library/util/stringios.rb
@@ -277,6 +278,7 @@ files:
277
278
  - rakelib/spec.rake
278
279
  - spec/.rubocop.yml
279
280
  - spec/berkeley_library/util/arrays_spec.rb
281
+ - spec/berkeley_library/util/files_spec.rb
280
282
  - spec/berkeley_library/util/paths_spec.rb
281
283
  - spec/berkeley_library/util/stringios_spec.rb
282
284
  - spec/berkeley_library/util/strings_spec.rb
@@ -311,6 +313,7 @@ summary: Miscellaneous Ruby utilities for the UC Berkeley Library
311
313
  test_files:
312
314
  - spec/.rubocop.yml
313
315
  - spec/berkeley_library/util/arrays_spec.rb
316
+ - spec/berkeley_library/util/files_spec.rb
314
317
  - spec/berkeley_library/util/paths_spec.rb
315
318
  - spec/berkeley_library/util/stringios_spec.rb
316
319
  - spec/berkeley_library/util/strings_spec.rb