ecfr 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +11 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +3 -0
  5. data/.rspec_parallel +4 -0
  6. data/.rubocop.yml +28 -0
  7. data/.yardopts +3 -0
  8. data/CHANGELOG.md +6 -0
  9. data/Dockerfile +6 -0
  10. data/Gemfile +6 -0
  11. data/Gemfile.lock +138 -0
  12. data/LICENSE.txt +21 -0
  13. data/README.md +133 -0
  14. data/Rakefile +12 -0
  15. data/bin/console +15 -0
  16. data/bin/setup +8 -0
  17. data/ecfr.gemspec +74 -0
  18. data/lib/ecfr/admin_service/agency/hierarchy.rb +27 -0
  19. data/lib/ecfr/admin_service/agency.rb +34 -0
  20. data/lib/ecfr/admin_service/api_documentation.rb +7 -0
  21. data/lib/ecfr/admin_service/base.rb +26 -0
  22. data/lib/ecfr/admin_service/build.rb +38 -0
  23. data/lib/ecfr/admin_service/ecfr_correction/cfr_reference.rb +17 -0
  24. data/lib/ecfr/admin_service/ecfr_correction.rb +78 -0
  25. data/lib/ecfr/admin_service/editorial_note/hierarchy.rb +19 -0
  26. data/lib/ecfr/admin_service/editorial_note.rb +40 -0
  27. data/lib/ecfr/admin_service/ibr_cfr_range/address.rb +17 -0
  28. data/lib/ecfr/admin_service/ibr_cfr_range/organization.rb +28 -0
  29. data/lib/ecfr/admin_service/ibr_cfr_range.rb +67 -0
  30. data/lib/ecfr/admin_service/issue/change.rb +19 -0
  31. data/lib/ecfr/admin_service/issue.rb +86 -0
  32. data/lib/ecfr/admin_service/site_notification.rb +34 -0
  33. data/lib/ecfr/admin_service/status.rb +7 -0
  34. data/lib/ecfr/attribute_caster.rb +72 -0
  35. data/lib/ecfr/attribute_method_definition.rb +92 -0
  36. data/lib/ecfr/base.rb +71 -0
  37. data/lib/ecfr/client.rb +318 -0
  38. data/lib/ecfr/common/hierarchy.rb +35 -0
  39. data/lib/ecfr/configuration.rb +58 -0
  40. data/lib/ecfr/constants.rb +21 -0
  41. data/lib/ecfr/default_documentation_setup.rb +39 -0
  42. data/lib/ecfr/default_status_setup.rb +46 -0
  43. data/lib/ecfr/diff_service/base.rb +17 -0
  44. data/lib/ecfr/diff_service/status.rb +34 -0
  45. data/lib/ecfr/extensible.rb +45 -0
  46. data/lib/ecfr/facet_attribute_method_definition.rb +47 -0
  47. data/lib/ecfr/faraday/user_agent/middleware.rb +14 -0
  48. data/lib/ecfr/ofr_profile_service/base.rb +20 -0
  49. data/lib/ecfr/ofr_profile_service/status.rb +7 -0
  50. data/lib/ecfr/parallel_client.rb +33 -0
  51. data/lib/ecfr/prince_xml_service/base.rb +17 -0
  52. data/lib/ecfr/prince_xml_service/pdf.rb +31 -0
  53. data/lib/ecfr/renderer_service/base.rb +31 -0
  54. data/lib/ecfr/renderer_service/content.rb +34 -0
  55. data/lib/ecfr/renderer_service/diff.rb +31 -0
  56. data/lib/ecfr/renderer_service/origin.rb +56 -0
  57. data/lib/ecfr/renderer_service/status.rb +7 -0
  58. data/lib/ecfr/request_representation.rb +12 -0
  59. data/lib/ecfr/search_service/api_documentation.rb +7 -0
  60. data/lib/ecfr/search_service/base.rb +23 -0
  61. data/lib/ecfr/search_service/content_version/count.rb +33 -0
  62. data/lib/ecfr/search_service/content_version/hierarchical_count.rb +17 -0
  63. data/lib/ecfr/search_service/content_version/hierarchical_count_node.rb +30 -0
  64. data/lib/ecfr/search_service/content_version/hierarchichal_result.rb +42 -0
  65. data/lib/ecfr/search_service/content_version/result.rb +110 -0
  66. data/lib/ecfr/search_service/content_version/suggestion.rb +76 -0
  67. data/lib/ecfr/search_service/content_version/summary.rb +27 -0
  68. data/lib/ecfr/search_service/content_version.rb +85 -0
  69. data/lib/ecfr/search_service/date_facet.rb +19 -0
  70. data/lib/ecfr/search_service/facet_base.rb +55 -0
  71. data/lib/ecfr/search_service/status.rb +7 -0
  72. data/lib/ecfr/search_service/title_facet.rb +18 -0
  73. data/lib/ecfr/subscriptions_service/base.rb +19 -0
  74. data/lib/ecfr/subscriptions_service/status.rb +7 -0
  75. data/lib/ecfr/subscriptions_service/subscription.rb +97 -0
  76. data/lib/ecfr/testing/extensions/admin_service/ecfr_correction_extensions.rb +13 -0
  77. data/lib/ecfr/testing/extensions/admin_service/issue_extensions.rb +13 -0
  78. data/lib/ecfr/testing/extensions/renderer_service/origin_extensions.rb +13 -0
  79. data/lib/ecfr/testing/extensions/search_service/content_version_result_extensions.rb +16 -0
  80. data/lib/ecfr/testing/extensions/search_service/date_facet_extensions.rb +13 -0
  81. data/lib/ecfr/testing/extensions/versioner_service/ancestors_extensions.rb +20 -0
  82. data/lib/ecfr/testing/extensions/versioner_service/title_extenstions.rb +16 -0
  83. data/lib/ecfr/testing/factories/admin_service/cfr_reference_factory.rb +14 -0
  84. data/lib/ecfr/testing/factories/admin_service/ecfr_correction_factory.rb +31 -0
  85. data/lib/ecfr/testing/factories/admin_service/issue_change_factory.rb +12 -0
  86. data/lib/ecfr/testing/factories/admin_service/issue_factory.rb +21 -0
  87. data/lib/ecfr/testing/factories/common/hierarchy_factory.rb +36 -0
  88. data/lib/ecfr/testing/factories/renderer_service/origin_factory.rb +32 -0
  89. data/lib/ecfr/testing/factories/search_service/content_version_count_factory.rb +20 -0
  90. data/lib/ecfr/testing/factories/search_service/content_version_result_factory.rb +76 -0
  91. data/lib/ecfr/testing/factories/search_service/date_facet_factory.rb +12 -0
  92. data/lib/ecfr/testing/factories/versioner_service/ancestors_factory.rb +26 -0
  93. data/lib/ecfr/testing/factories/versioner_service/metadata_node_info_factory.rb +15 -0
  94. data/lib/ecfr/testing/factories/versioner_service/node_summary_factory.rb +16 -0
  95. data/lib/ecfr/testing/factories/versioner_service/structure_factory.rb +57 -0
  96. data/lib/ecfr/testing/factories/versioner_service/title_factory.rb +36 -0
  97. data/lib/ecfr/testing/factory_bot_helpers/content_version.rb +38 -0
  98. data/lib/ecfr/testing/factory_bot_helpers/ecfr_gem_initialize_helpers.rb +51 -0
  99. data/lib/ecfr/testing/helpers/response_helper.rb +5 -0
  100. data/lib/ecfr/testing/strategies/ecfr_attribute_hash_strategy.rb +37 -0
  101. data/lib/ecfr/testing.rb +28 -0
  102. data/lib/ecfr/version.rb +5 -0
  103. data/lib/ecfr/versioner_service/ancestors/metadata_node_info.rb +22 -0
  104. data/lib/ecfr/versioner_service/ancestors/node_summary.rb +54 -0
  105. data/lib/ecfr/versioner_service/ancestors.rb +152 -0
  106. data/lib/ecfr/versioner_service/api_documentation.rb +7 -0
  107. data/lib/ecfr/versioner_service/base.rb +24 -0
  108. data/lib/ecfr/versioner_service/status.rb +7 -0
  109. data/lib/ecfr/versioner_service/structure.rb +120 -0
  110. data/lib/ecfr/versioner_service/title.rb +78 -0
  111. data/lib/ecfr/versioner_service/xml_content.rb +59 -0
  112. data/lib/ecfr.rb +90 -0
  113. data/lib/yard/attribute_handler.rb +87 -0
  114. data/lib/yard/metadata_handler.rb +87 -0
  115. metadata +389 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e01bffb47225f9d31bd9a6d862f8b6e967586b4ac296ec25814e04dd254dacbe
4
+ data.tar.gz: 0b1f9d5b015063e167a27fc98036299ceb8b10d486a8a3d188044da99ad4c903
5
+ SHA512:
6
+ metadata.gz: a294244d1e845f3ea9d3b6a128c557f85f9bc5b5c9eebea84ea507437b0101b27a9c87528c26e6dfb0ebb9d7c3888963569698b366b653399e2bf79eb37d579b
7
+ data.tar.gz: dc588b8531cb89e27a69a53c6a47deb8648c493d4fdc176e17bf51018ef88fd884876ebf69a875d44c30421be6735775555038cd4c6d19f3d7a8b3c6da399633
@@ -0,0 +1,11 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ cj: criticaljuncture/cj-orb@0.1
5
+
6
+ workflows:
7
+ build_and_notify:
8
+ jobs:
9
+ - cj/build_gem:
10
+ channel: ofr
11
+ context: orb-slack
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rspec_parallel ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --require spec_helper
3
+ --format progress
4
+ --format RspecJunitFormatter --out tmp/test-results/rspec/rspec<%= ENV["TEST_ENV_NUMBER"] %>.xml
data/.rubocop.yml ADDED
@@ -0,0 +1,28 @@
1
+ AllCops:
2
+ Exclude:
3
+ - bin/*
4
+ - lib/yard/*
5
+ TargetRubyVersion: 3.1
6
+
7
+ Layout/EmptyLineBetweenDefs:
8
+ AllowAdjacentOneLineDefs: true
9
+
10
+ Lint/ConstantDefinitionInBlock:
11
+ Exclude:
12
+ - spec/ecfr/extensible_spec.rb
13
+
14
+ # We want Exclude directives from different
15
+ # config files to get merged, not overwritten
16
+ inherit_mode:
17
+ merge:
18
+ - Exclude
19
+
20
+ require:
21
+ # Performance cops are bundled with Standard
22
+ - rubocop-performance
23
+ # Standard's config uses this custom cop,
24
+ # so it must be loaded
25
+ - standard/cop/block_single_line_braces
26
+
27
+ inherit_gem:
28
+ standard: config/base.yml
data/.yardopts ADDED
@@ -0,0 +1,3 @@
1
+ --load ./lib/yard/attribute_handler.rb
2
+ --load ./lib/yard/metadata_handler.rb
3
+ --exclude ./lib/yard
data/CHANGELOG.md ADDED
@@ -0,0 +1,6 @@
1
+ ## [Unreleased]
2
+
3
+ ## [1.0.0] - 2023-04-12
4
+
5
+ - Initial release
6
+ - built based on usage from the ecfr-web project
data/Dockerfile ADDED
@@ -0,0 +1,6 @@
1
+ FROM ruby:3.0
2
+
3
+ ADD . /ecfr
4
+ WORKDIR /ecfr
5
+
6
+ RUN bundle
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in ecfr.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,138 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ecfr (1.0.0)
5
+ activemodel (~> 6.0)
6
+ activesupport (~> 6.0)
7
+ faraday (~> 2.0)
8
+ faraday-net_http_persistent (~> 2.0)
9
+
10
+ GEM
11
+ remote: https://rubygems.org/
12
+ specs:
13
+ activemodel (6.1.4)
14
+ activesupport (= 6.1.4)
15
+ activesupport (6.1.4)
16
+ concurrent-ruby (~> 1.0, >= 1.0.2)
17
+ i18n (>= 1.6, < 2)
18
+ minitest (>= 5.1)
19
+ tzinfo (~> 2.0)
20
+ zeitwerk (~> 2.3)
21
+ ast (2.4.2)
22
+ coderay (1.1.3)
23
+ concurrent-ruby (1.1.9)
24
+ connection_pool (2.4.0)
25
+ diff-lcs (1.4.4)
26
+ ethon (0.16.0)
27
+ ffi (>= 1.15.0)
28
+ factory_bot (6.2.1)
29
+ activesupport (>= 5.0.0)
30
+ faraday (2.5.2)
31
+ faraday-net_http (>= 2.0, < 3.1)
32
+ ruby2_keywords (>= 0.0.4)
33
+ faraday-net_http (3.0.0)
34
+ faraday-net_http_persistent (2.1.0)
35
+ faraday (~> 2.5)
36
+ net-http-persistent (~> 4.0)
37
+ faraday-typhoeus (1.0.0)
38
+ faraday (~> 2.0)
39
+ typhoeus (~> 1.4)
40
+ ffi (1.15.5)
41
+ i18n (1.8.10)
42
+ concurrent-ruby (~> 1.0)
43
+ json (2.6.3)
44
+ language_server-protocol (3.17.0.3)
45
+ method_source (1.0.0)
46
+ mini_portile2 (2.8.1)
47
+ minitest (5.14.4)
48
+ net-http-persistent (4.0.2)
49
+ connection_pool (~> 2.2)
50
+ nokogiri (1.14.0)
51
+ mini_portile2 (~> 2.8.0)
52
+ racc (~> 1.4)
53
+ optparse (0.3.1)
54
+ parallel (1.22.1)
55
+ parallel_tests (4.2.0)
56
+ parallel
57
+ parser (3.2.2.0)
58
+ ast (~> 2.4.1)
59
+ pry (0.14.1)
60
+ coderay (~> 1.1)
61
+ method_source (~> 1.0)
62
+ racc (1.6.2)
63
+ rack (3.0.4.1)
64
+ rainbow (3.1.1)
65
+ regexp_parser (2.7.0)
66
+ request_store (1.5.1)
67
+ rack (>= 1.4)
68
+ rexml (3.2.5)
69
+ rspec (3.10.0)
70
+ rspec-core (~> 3.10.0)
71
+ rspec-expectations (~> 3.10.0)
72
+ rspec-mocks (~> 3.10.0)
73
+ rspec-core (3.10.1)
74
+ rspec-support (~> 3.10.0)
75
+ rspec-expectations (3.10.1)
76
+ diff-lcs (>= 1.2.0, < 2.0)
77
+ rspec-support (~> 3.10.0)
78
+ rspec-mocks (3.10.2)
79
+ diff-lcs (>= 1.2.0, < 2.0)
80
+ rspec-support (~> 3.10.0)
81
+ rspec-support (3.10.2)
82
+ rspec_junit_formatter (0.6.0)
83
+ rspec-core (>= 2, < 4, != 2.12.0)
84
+ rubocop (1.48.1)
85
+ json (~> 2.3)
86
+ parallel (~> 1.10)
87
+ parser (>= 3.2.0.0)
88
+ rainbow (>= 2.2.2, < 4.0)
89
+ regexp_parser (>= 1.8, < 3.0)
90
+ rexml (>= 3.2.5, < 4.0)
91
+ rubocop-ast (>= 1.26.0, < 2.0)
92
+ ruby-progressbar (~> 1.7)
93
+ unicode-display_width (>= 2.4.0, < 3.0)
94
+ rubocop-ast (1.28.0)
95
+ parser (>= 3.2.1.0)
96
+ rubocop-performance (1.16.0)
97
+ rubocop (>= 1.7.0, < 2.0)
98
+ rubocop-ast (>= 0.4.0)
99
+ ruby-progressbar (1.13.0)
100
+ ruby2_keywords (0.0.5)
101
+ standard (1.26.0)
102
+ language_server-protocol (~> 3.17.0.2)
103
+ rubocop (~> 1.48.1)
104
+ rubocop-performance (~> 1.16.0)
105
+ turbo_tests (1.0.0)
106
+ optparse
107
+ parallel_tests
108
+ rspec
109
+ typhoeus (1.4.0)
110
+ ethon (>= 0.9.0)
111
+ tzinfo (2.0.4)
112
+ concurrent-ruby (~> 1.0)
113
+ unicode-display_width (2.4.2)
114
+ webrick (1.7.0)
115
+ yard (0.9.28)
116
+ webrick (~> 1.7.0)
117
+ zeitwerk (2.4.2)
118
+
119
+ PLATFORMS
120
+ ruby
121
+
122
+ DEPENDENCIES
123
+ ecfr!
124
+ factory_bot
125
+ faraday-typhoeus
126
+ nokogiri
127
+ parallel_tests
128
+ pry
129
+ request_store
130
+ rspec (~> 3.0)
131
+ rspec_junit_formatter
132
+ rubocop
133
+ standard (~> 1.0)
134
+ turbo_tests
135
+ yard
136
+
137
+ BUNDLED WITH
138
+ 2.2.33
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Critical Juncture, LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,133 @@
1
+ # Ecfr
2
+
3
+ Provides a Ruby API client for the eCFR.gov APIs.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'ecfr'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle install
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install ecfr
20
+
21
+ ## Usage
22
+
23
+ Configuration is supported via a configuration block. Only `user_agent` is required to be configured. See `lib/ecfr/configuration.rb` for options.
24
+
25
+ ```ruby
26
+ Ecfr.configure do |config|
27
+ config.user_agent = "MyProject(me@myproject.com)"
28
+ end
29
+ ```
30
+
31
+ ### XML parsing
32
+
33
+ Some endpoints return XML (like the Structure) and will be automatically parsed using Nokogiri. However we do not bundle this as a gem dependency since it may not always be used. To use this you will need to add the Nokogiri gem to your code.
34
+
35
+ ### Response caching
36
+
37
+ Response caching can be enabled via a configuration option. This is a performance feature that allows the calling code to not worry about performance when different parts of the application call the same endpoints at different times in the same request. Responses are cached my HTTP method, api endpoint and requested parameters. You will need to install the [request_store](https://github.com/steveklabnik/request_store) gem when enabling this option.
38
+
39
+ If you are using request store outside of a Rails project or in a background process (eg Sidekiq) check the RequestStore documentation for how to use the required middleware.
40
+
41
+ ### Parallel client
42
+
43
+ A basic parallel client is provided to support some use cases (we use it internally for our status page). This requires the use of [faraday-typhoeus](https://github.com/dleavitt/faraday-typhoeus) adapter. However we do not bundle this as a gem dependency since it may not always be used. To use the parallel client you will need to add the typhoeus faraday adapter gem to your code.
44
+
45
+ ## Development
46
+
47
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
48
+
49
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
50
+
51
+ ### Simple endpoints that return an array of data under a single key
52
+
53
+ For endpoints that return results like:
54
+
55
+ ```
56
+ {
57
+ items: [
58
+ {name: "Item 1", active: true},
59
+ {name: "Item 2", active: true},
60
+ {name: "Item 3", active: false}
61
+ ]
62
+ }
63
+ ```
64
+
65
+ We support a `result_key` in the definition. In this example `result_key: :items`. This will cause each item in the items array to be instantiated as an instance of the class and delegate enumerable methods such as `.each`, `.first`, `.last`.
66
+
67
+ So the following definition:
68
+ ```
69
+ class Items < Base
70
+ result_key: :items
71
+
72
+ attribute :name
73
+ attribute :active, type: boolean
74
+
75
+ def self.all
76
+ new(
77
+ get(...)
78
+ )
79
+ end
80
+ end
81
+ ```
82
+
83
+ could be used `Items.all.each` which would iterate through an array of `Item` instances with `name` and `active` (and `active?`) methods.
84
+
85
+
86
+ ### More complex endpoints
87
+
88
+ If however the endpoint returns data more like:
89
+
90
+ ```
91
+ {
92
+ items: [
93
+ {name: "Item 1", active: true},
94
+ {name: "Item 2", active: true},
95
+ {name: "Item 3", active: false}
96
+ ],
97
+ warehouse: "Warehouse 32",
98
+ dock: "Dock A"
99
+ }
100
+ ```
101
+
102
+ then we support the following definition:
103
+
104
+ ```
105
+ class Items < Base
106
+ class Item
107
+ include AttributeMethodDefinition
108
+
109
+ attribute :name
110
+ attribute :active, type: boolean
111
+ end
112
+
113
+ attribute: :items, type: Array(Item)
114
+ attribute: :dock, :warehouse
115
+
116
+ def self.all
117
+ new(
118
+ get(...)
119
+ )
120
+ end
121
+ end
122
+ ```
123
+
124
+ which can then be used like `result = Items.all; result.items.each...; result.warehouse`.
125
+
126
+
127
+ ## Contributing
128
+
129
+ Bug reports and pull requests are welcome on GitHub at https://github.com/criticaljuncture/ecfr.
130
+
131
+ ## License
132
+
133
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "ecfr"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/ecfr.gemspec ADDED
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/ecfr/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "ecfr"
7
+ spec.version = Ecfr::VERSION
8
+ spec.authors = ["Peregrinator"]
9
+ spec.email = ["bob.burbach@gmail.com"]
10
+
11
+ spec.summary = "ecfr.federalregister.gov API client"
12
+ spec.description = "Ruby client for APIs provided by ecfr.federalregister.gov"
13
+ spec.homepage = "https://github.com/criticaljuncture/ecfr"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
18
+
19
+ spec.metadata["homepage_uri"] = spec.homepage
20
+ spec.metadata["source_code_uri"] = "https://github.com/criticaljuncture/ecfr"
21
+ spec.metadata["changelog_uri"] = "https://github.com/criticaljuncture/ecfr"
22
+
23
+ # Specify which files should be added to the gem when it is released.
24
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
26
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_dependency "activemodel", "~> 6.0"
33
+ spec.add_dependency "activesupport", "~> 6.0"
34
+ spec.add_dependency "faraday", "~> 2.0"
35
+ spec.add_dependency "faraday-net_http_persistent", "~> 2.0"
36
+
37
+ spec.add_development_dependency "factory_bot"
38
+ spec.add_development_dependency "parallel_tests"
39
+ spec.add_development_dependency "pry"
40
+ spec.add_development_dependency "rspec", "~> 3.0"
41
+ spec.add_development_dependency "rspec_junit_formatter"
42
+ spec.add_development_dependency "rubocop"
43
+ spec.add_development_dependency "standard", "~> 1.0"
44
+ spec.add_development_dependency "turbo_tests"
45
+ spec.add_development_dependency "yard"
46
+
47
+ # A parallel client is made available when the faraday-typhoeus adapter
48
+ # is installed. However we don't bundle this as a dependency. If you want
49
+ # to use the parallel client make sure to require it in your code.
50
+ spec.add_development_dependency "faraday-typhoeus"
51
+
52
+ # Some features of the gem support parsing XML responses
53
+ # with Nokogiri.
54
+ # However we don't bundle this as a dependency. If you want
55
+ # to use such features make sure to require it in your code.
56
+ spec.add_development_dependency "nokogiri"
57
+
58
+ # Caching of responses can be enabled and require the
59
+ # request store gem. However we don't bundle this as a
60
+ # dependency - it will need to be installed in your code.
61
+ spec.add_development_dependency "request_store"
62
+
63
+ spec.post_install_message = '
64
+ Some features of the eCFR gem support parsing XML responses, response
65
+ caching, and parallel requests.
66
+
67
+ To use these features you will beed to install the appropriate gems
68
+ (nokogiri, request_store, and faraday-typhoeus respectively) in your
69
+ application. In order to minimize depedencies and code that is loaded these
70
+ are not a default dependencies of the eCFR gem.
71
+
72
+ See the README for details of these features.
73
+ '
74
+ end
@@ -0,0 +1,27 @@
1
+ module Ecfr
2
+ module AdminService
3
+ class Agency
4
+ class Hierarchy
5
+ include AttributeMethodDefinition
6
+ extend Extensible
7
+
8
+ attribute :title,
9
+ desc: "Title number"
10
+ attribute :subtitle,
11
+ desc: "Subtitle identifier"
12
+ attribute :chapter,
13
+ desc: "Chapter identifier"
14
+ attribute :subchapter,
15
+ desc: "Subchapter identifier"
16
+ attribute :part,
17
+ desc: "Part identifier"
18
+
19
+ def to_hash
20
+ @attributes.each_with_object({}) { |attr, hsh|
21
+ hsh[attr[0]] = attr[1]
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ module Ecfr
2
+ module AdminService
3
+ class Agency < Base
4
+ require_relative "agency/hierarchy"
5
+
6
+ result_key :agencies
7
+
8
+ attribute :name, desc: "name of agency"
9
+
10
+ attribute :cfr_references, type: Array(Ecfr::Common::Hierarchy),
11
+ desc: "portions of the CFR this agency is responsible for,
12
+ expected keys are only :title, :subtitle, :chapter,
13
+ :subchapter, and :part"
14
+
15
+ attribute :children, type: Array(Agency),
16
+ desc: "sub-agencies of the current agency"
17
+
18
+ AGENCIES_PATH = "v1/agencies.json"
19
+
20
+ #
21
+ # Retrieve the list of all agencies, their subagencies
22
+ # and the portions of the CFR they are responsible for
23
+ #
24
+ # @return [[<Agency>]] an array of agency records
25
+ #
26
+ def self.all
27
+ perform(
28
+ :get,
29
+ AGENCIES_PATH
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ module Ecfr
2
+ module AdminService
3
+ class ApiDocumentation < Base
4
+ include DefaultDocumentationSetup
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ module Ecfr
2
+ module AdminService
3
+ class Base < Ecfr::Base
4
+ require_relative "api_documentation"
5
+ require_relative "status"
6
+
7
+ require_relative "agency"
8
+ require_relative "build"
9
+ require_relative "ecfr_correction"
10
+ require_relative "editorial_note"
11
+ require_relative "ibr_cfr_range"
12
+ require_relative "issue"
13
+ require_relative "site_notification"
14
+
15
+ SERVICE_PATH = "/admin/api/admin"
16
+
17
+ def self.base_url
18
+ Ecfr.config.admin_service_url || Ecfr.config.base_url
19
+ end
20
+
21
+ def self.service_name
22
+ "Admin Service"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,38 @@
1
+ module Ecfr
2
+ module AdminService
3
+ class Build < Base
4
+ result_key :builds
5
+
6
+ attribute :id,
7
+ desc: "build id"
8
+ attribute :status,
9
+ desc: "build status - either *Success* or *Failure*"
10
+
11
+ attribute :expired,
12
+ type: :boolean
13
+ attribute :previewable,
14
+ type: :boolean
15
+
16
+ BUILDS_PATH = "v1/builds"
17
+
18
+ #
19
+ # Retrieve a Build by id
20
+ #
21
+ # @param [<String>] build_id - id of the desired build
22
+ #
23
+ # @return [<Build>] data for a single build
24
+ #
25
+ def self.find(build_id)
26
+ perform(
27
+ :get,
28
+ build_path(build_id)
29
+ )
30
+ end
31
+
32
+ def self.build_path(build_id)
33
+ "#{BUILDS_PATH}/#{build_id}"
34
+ end
35
+ private_class_method :build_path
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,17 @@
1
+ module Ecfr
2
+ module AdminService
3
+ class EcfrCorrection
4
+ class CfrReference
5
+ include AttributeMethodDefinition
6
+ extend Extensible
7
+
8
+ attribute :cfr_reference,
9
+ desc: "CFR reference in the form '40 CFR 100'"
10
+
11
+ attribute :hierarchy,
12
+ type: Ecfr::Common::Hierarchy,
13
+ desc: "hash of CFR hierarchy attributes"
14
+ end
15
+ end
16
+ end
17
+ end