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 +4 -4
- data/.idea/inspectionProfiles/Project_Default.xml +4 -0
- data/.idea/util.iml +39 -36
- data/CHANGES.md +15 -1
- data/README.md +7 -3
- data/lib/berkeley_library/util/files.rb +37 -0
- data/lib/berkeley_library/util/module_info.rb +2 -4
- data/lib/berkeley_library/util/paths.rb +8 -0
- data/lib/berkeley_library/util/uris/appender.rb +2 -1
- data/lib/berkeley_library/util/uris/requester.rb +23 -3
- data/lib/berkeley_library/util/uris.rb +10 -0
- data/spec/berkeley_library/util/files_spec.rb +115 -0
- data/spec/berkeley_library/util/uris/requester_spec.rb +8 -11
- data/spec/berkeley_library/util/uris_spec.rb +59 -10
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c52542412eba63da568f64ede565f97e941321d108f42e89920341df02a268b2
|
|
4
|
+
data.tar.gz: 3a56f6a5dd154c44d3d94e601f3093a8c4aca81e05fb3f7e18cd70ca6389f930
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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 (
|
|
9
|
-
<orderEntry type="library" scope="PROVIDED" name="actionview (
|
|
10
|
-
<orderEntry type="library" scope="PROVIDED" name="activesupport (
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
34
|
-
<orderEntry type="library" scope="PROVIDED" name="lograge (v0.
|
|
35
|
-
<orderEntry type="library" scope="PROVIDED" name="loofah (v2.
|
|
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.
|
|
38
|
-
<orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.
|
|
39
|
-
<orderEntry type="library" scope="PROVIDED" name="minitest (v5.
|
|
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.
|
|
42
|
-
<orderEntry type="library" scope="PROVIDED" name="oj (v3.13.
|
|
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.
|
|
45
|
-
<orderEntry type="library" scope="PROVIDED" name="parser (v3.
|
|
46
|
-
<orderEntry type="library" scope="PROVIDED" name="public_suffix (v4.0.
|
|
47
|
-
<orderEntry type="library" scope="PROVIDED" name="racc (v1.
|
|
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 (
|
|
53
|
-
<orderEntry type="library" scope="PROVIDED" name="rainbow (v3.
|
|
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.
|
|
56
|
-
<orderEntry type="library" scope="PROVIDED" name="request_store (v1.5.
|
|
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.
|
|
60
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.
|
|
61
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.
|
|
62
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.
|
|
63
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.
|
|
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.
|
|
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.
|
|
73
|
-
<orderEntry type="library" scope="PROVIDED" name="simplecov_json_formatter (v0.1.
|
|
74
|
-
<orderEntry type="library" scope="PROVIDED" name="thor (v1.1
|
|
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
|
|
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.
|
|
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 =
|
|
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.
|
|
10
|
+
VERSION = '0.1.3'.freeze
|
|
13
11
|
HOMEPAGE = 'https://github.com/BerkeleyLibrary/util'.freeze
|
|
14
12
|
end
|
|
15
13
|
end
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
-
|
|
125
|
-
|
|
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
|
-
|
|
129
|
-
|
|
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.
|
|
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:
|
|
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
|