cartage-rack 1.1 → 2.0.rc1

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
  SHA1:
3
- metadata.gz: f1f756831e081111a68cf696035705057d5b06a8
4
- data.tar.gz: 5d02f8976aa4b7433e9c8d96c6ccc3558007e50b
3
+ metadata.gz: 94047d31b87bd33b0ede49ddc37cf6919449cfd4
4
+ data.tar.gz: 129d78a6a5cf83122b5a3581efdc446f9462688c
5
5
  SHA512:
6
- metadata.gz: da2f68e98d8ae476143c955ea2e8e1921b89890491a5b7ed41746bf518c42a8c9c26cb824397bfe4557c67da3686826ffd4f2b24f3023c2d90dd76e002f84d57
7
- data.tar.gz: 0515b3f19b46cdd5725ff1650ea4d87b7c354a16e535ccafe7282488558f4de09a159ee560c1f1ed2fa79f25938f4adcb266616ae31609359d78d7a5ea44c9d2
6
+ metadata.gz: e86abeee60243641fe003a20024e7a54bb756ce7decc1f43e4288f1fb0fc120821c87371d4423f3161e94e3e7f7e156d8a7abb58be343da11ddd250f5074b341
7
+ data.tar.gz: 24876ea56317cd8ab71d106cc58fc868d185307d4e4b4ff37299de00a33dc167f869909ed0b29523cd449a9e3c1e887a4cf3c9c761488c212b8227f53187f839
data/Contributing.md ADDED
@@ -0,0 +1,66 @@
1
+ ## Contributing
2
+
3
+ We value any contribution to cartage-rack you can provide: a bug report, a
4
+ feature request, or code contributions. cartage-rack is reasonably complex
5
+ code, so there are a few contribution guidelines:
6
+
7
+ * Changes *will* *not* be accepted without tests. The test suite is written
8
+ with [Minitest][].
9
+ * Match our coding style.
10
+ * Use a thoughtfully-named topic branch that contains your change. Rebase
11
+ your commits into logical chunks as necessary.
12
+ * Use [quality commit messages][].
13
+ * Do not change the version number; when your patch is accepted and a release
14
+ is made, the version will be updated at that point.
15
+ * Submit a GitHub pull request with your changes.
16
+
17
+ ### Test Dependencies
18
+
19
+ cartage-rack uses Ryan Davis’s [Hoe][] to manage the release process, which
20
+ adds a number of rake tasks. You will mostly be interested in:
21
+
22
+ $ rake
23
+
24
+ which runs the tests the same way that:
25
+
26
+ $ rake test
27
+ $ rake travis
28
+
29
+ will do.
30
+
31
+ To assist with the installation of the development dependencies for
32
+ cartage-rack, I have provided the simplest possible Gemfile pointing to the
33
+ (generated) `cartage-rack.gemspec` file. This will permit you to do:
34
+
35
+ $ bundle install
36
+
37
+ to get the development dependencies. If you aleady have `hoe` installed, you
38
+ can accomplish the same thing with:
39
+
40
+ $ rake newb
41
+
42
+ This task will install any missing dependencies, run the tests/specs, and
43
+ generate the RDoc.
44
+
45
+ ### Workflow
46
+
47
+ Here's the most direct way to get your work merged into the project:
48
+
49
+ * Fork the project.
50
+ * Clone down your fork (`git clone git://github.com/KineticCafe/cartage-rack.git`).
51
+ * Create a topic branch to contain your change (`git checkout -b my_awesome_feature`).
52
+ * Hack away, add tests. Not necessarily in that order.
53
+ * Make sure everything still passes by running `rake`.
54
+ * If necessary, rebase your commits into logical chunks, without errors.
55
+ * Push the branch up (`git push origin my_awesome_feature`).
56
+ * Create a pull request against KineticCafe/cartage-rack and describe
57
+ what your change does and the why you think it should be merged.
58
+
59
+ ### Contributors
60
+
61
+ * Austin Ziegler created cartage-rack.
62
+
63
+ [Minitest]: https://github.com/seattlerb/minitest
64
+ [quality commit messages]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
65
+ [Hoe]: https://github.com/seattlerb/hoe
66
+ [kccoc]: https://github.com/KineticCafe/code-of-conduct
data/History.md ADDED
@@ -0,0 +1,46 @@
1
+ ### 2.0 / 2016-05-DD
2
+
3
+ * Rewrote for compatibility with cartage 2.0.
4
+
5
+ * Renamed Cartage::Rack to Cartage::Rack::Simple and created a *new*
6
+ Cartage::Rack that returns more information.
7
+
8
+ * Extracted metadata gathering out of Cartage::Rack and into
9
+ Cartage::Rack::Metadata.
10
+
11
+ * Deprecated Cartage::Rack.mount in favour of Cartage::Rack() and
12
+ Cartage::Rack::Simple() methods.
13
+
14
+ * 1 governance change
15
+
16
+ * cartage-rack is now under the Kinetic Cafe Open Source [Code of
17
+ Conduct][kccoc].
18
+
19
+ ### 1.1 / 2015-04-11
20
+
21
+ * 2 minor enhancements
22
+
23
+ * Implemented Cartage::Rack#inspect to prevent `rake routes` from
24
+ presenting badly.
25
+
26
+ * Preparing for a future Cartage change to the contents of the
27
+ `release_hashref` file. The future `release_hashref` will be two lines:
28
+
29
+ hashref
30
+ timestamp
31
+
32
+ If `release_hashref` has two lines, the timestamp will be included in
33
+ the response. A timestamp will not be included if there is no
34
+ `release_hashref` file.
35
+
36
+ * 1 development change
37
+
38
+ * Implemented tests for Cartage::Rack.
39
+
40
+ ### 1.0 / 2015-03-20
41
+
42
+ * 1 major enhancement
43
+
44
+ * Birthday!
45
+
46
+ [kccoc]: https://github.com/KineticCafe/code-of-conduct
@@ -1,8 +1,8 @@
1
- == Licence
1
+ ## Licence
2
2
 
3
3
  This software is available under an MIT-style licence.
4
4
 
5
- * Copyright 2015 Kinetic Cafe
5
+ * Copyright 2015–2016 Kinetic Cafe
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy of
8
8
  this software and associated documentation files (the "Software"), to deal in
@@ -11,9 +11,9 @@ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
11
11
  of the Software, and to permit persons to whom the Software is furnished to do
12
12
  so, subject to the following conditions:
13
13
 
14
- * The names of its contributors may not be used to endorse or promote
15
- products derived from this software without specific prior written
16
- permission.
14
+ * The names of its contributors may not be used to endorse or promote
15
+ products derived from this software without specific prior written
16
+ permission.
17
17
 
18
18
  The above copyright notice and this permission notice shall be included in all
19
19
  copies or substantial portions of the Software.
data/Manifest.txt CHANGED
@@ -1,14 +1,13 @@
1
- .autotest
2
- .gemtest
3
- .minitest.rb
4
- .travis.yml
5
- Contributing.rdoc
6
- Gemfile
7
- History.rdoc
8
- Licence.rdoc
1
+ Contributing.md
2
+ History.md
3
+ Licence.md
9
4
  Manifest.txt
10
5
  README.rdoc
11
6
  Rakefile
12
7
  lib/cartage/rack.rb
8
+ lib/cartage/rack/metadata.rb
9
+ lib/cartage/rack/simple.rb
13
10
  test/minitest_config.rb
14
11
  test/test_cartage_rack.rb
12
+ test/test_cartage_rack_metadata.rb
13
+ test/test_cartage_rack_simple.rb
data/README.rdoc CHANGED
@@ -7,7 +7,7 @@ continuous integration :: {<img src="https://travis-ci.org/KineticCafe/cartage-r
7
7
  == Description
8
8
 
9
9
  cartage-rack is a plug-in for {cartage}[https://github.com/KineticCafe/cartage]
10
- to provide a Rack application.
10
+ to provide a Rack application that reports on release metadata.
11
11
 
12
12
  Cartage provides a repeatable means to create a package for a Rails application
13
13
  that can be used in deployment with a configuration tool like Ansible, Chef,
@@ -17,58 +17,123 @@ control rules and without requiring development tool access.
17
17
 
18
18
  == Synopsis
19
19
 
20
- Cartage::Rack provides a Rack application generator to read and return the
21
- +release_hashref+ from an endpoint to verify that the server was deployed. This
22
- endpoint supports both JSON and plaintext output. To add this to a Rails
23
- application, simply mount it in +config/routes.rb+:
20
+ cartage-rack provides a generator method that instantiates a Rack application
21
+ that reports on release metadata, which will assist in verifying application
22
+ deploys.
23
+
24
+ To add the default generator to a Rails application, simply mount it in
25
+ +config/routes.rb+:
24
26
 
25
27
  require 'cartage/rack'
26
28
 
27
29
  Rails.application.routes.draw do
28
- get '/release' => Cartage::Rack.mount(Rails.root)
30
+ get '/release' => Cartage::Rack::Simple(Rails.root)
29
31
  end
30
32
 
31
- Or map it in a normal Rack application in +config.ru+:
33
+ To map it in a normal Rack application in +config.ru+:
32
34
 
33
35
  require 'cartage/rack'
34
36
  map('/release') do
35
- run Cartage::Rack.mount(Dir.pwd)
37
+ run Cartage::Rack::Simple(Dir.pwd)
36
38
  end
37
39
 
38
- It can then be queried easily:
40
+ Once mounted, it can then be queried easily:
39
41
 
40
42
  % rails start
41
43
  % curl localhost:3000/release
42
44
  development: (git) main
43
- % curl localhost:3000/release.json | jshon
45
+ % curl localhost:3000/release.json | jq .
44
46
  {
45
47
  "env" : "development",
46
48
  "release_hashref" : "(git) main"
47
49
  }
48
50
 
49
- If there is a +release_hashref+ file, the value returned will be from this
50
- file. There are two versions of +release_hashref+ files supported; the original
51
- format (Cartage 1.0 and 1.1) has one line (just the hashref of the release).
52
- The new format has two lines, the hashref of the release and the timestamp of
53
- the release.
51
+ == \Metadata
52
+
53
+ The core of cartage-rack is Cartage::Rack::Metadata, which collects data from
54
+ <tt>release-metadata.json</tt>, +release_hashref+, or the runtime environment
55
+ (if Cartage::Rack.require_metadata is +false+). You may instantiate the class
56
+ yourself if you wish to have a different sort of report for the release.
57
+
58
+ == \Metadata Reporters
59
+
60
+ There are two \Rack applications provided in cartage-rack 2.0 to report on
61
+ release metadata. \Metadata is pulled from <tt>release-metadata.json</tt>,
62
+ +release_hashref+, or the current environment (which allows Cartage::Rack
63
+ verification in development).
64
+
65
+ When reading +release_hashref+, the first line is the hashref of the release; a
66
+ second line, if present, is the Cartage timestamp of the release (an integer
67
+ value of the form +YYYYmmddHHMMSS+).
68
+
69
+ If a metadata file (<tt>release-metadata.json</tt> or <tt>release_hashref</tt>)
70
+ exists, it will be read on application creation and cached for the lifetime of
71
+ the Rack application. cartage-rack may be configured to throw an exception if a
72
+ metadata file cannot be found:
73
+
74
+ Cartage::Rack.require_metadata false
75
+
76
+ All reporters support JSON and plain text formats.
77
+
78
+ === Cartage::Rack
79
+
80
+ A full metadata reporter. This reporter may include information that is
81
+ considered *private* (including the source repository URL), so it is only
82
+ recommended for use on protected endpoints. The default report format is JSON.
83
+
84
+ The data returned is what is recorded in <tt>release-metadata.json</tt>, plus
85
+ the name of the environment.
54
86
 
55
- % curl localhost:3000/release.json | jshon
56
87
  {
57
- "env" : "production",
58
- "release_hashref" : "134458c3e3c02dd7c1cac8d5d41d85ce1e4decab"
59
- "timestamp" : "20150411001143"
88
+ "env": {
89
+ "name": "production",
90
+ },
91
+ "package": {
92
+ "name": "package-name",
93
+ "repo": {
94
+ "type": "git",
95
+ "url": "git:git@github.com/KineticCafe/cartage-rack.git"
96
+ },
97
+ hashref: "decafbad",
98
+ timestamp: "19851027024200"
99
+ }
60
100
  }
61
101
 
102
+ Mount this reporter with <tt>Cartage::Rack(Rails.root)</tt>. The data may be
103
+ filtered out by providing a block to <tt>Cartage::Rack()</tt> which modifies
104
+ the +metadata+ in place.
105
+
106
+ Cartage::Rack(Rails.root) do |metadata|
107
+ unless Rails.env.development?
108
+ # Remove the repo data before returning
109
+ metadata[:package].delete(:repo)
110
+ end
111
+ end
112
+
113
+ === Cartage::Rack::Simple
114
+
115
+ A simplified metadata reporter, including only the information that was
116
+ provided in cartage-rack 1.x (the environment, the hashref, and optionally a
117
+ timestamp). The default report format is plain text.
118
+
119
+ Mount this reporter with <tt>Cartage::Rack::Simple(Rails.root)</tt>. For
120
+ backwards compatibility, this reporter may also be mounted with
121
+ <tt>Cartage::Rack.mount(Rails.root)</tt>. The Simple reporter does not support
122
+ filtering.
123
+
62
124
  == Install
63
125
 
64
126
  Add cartage-rack to your Gemfile:
65
127
 
66
- gem 'cartage-rack', '~> 1.1'
128
+ gem 'cartage-rack', '~> 2.0'
67
129
 
68
130
  Or manually install:
69
131
 
70
132
  % gem install cartage-rack
71
133
 
134
+ cartage-rack should be in the main section of your Gemfile, unlike Cartage
135
+ itself.
136
+
72
137
  == cartage-rack Semantic Versioning
73
138
 
74
139
  cartage-rack uses a {Semantic Versioning}[http://semver.org/] scheme with one
@@ -79,6 +144,10 @@ change:
79
144
  cartage-rack will generally track cartage for major versions to ensure plugin API
80
145
  compatibility.
81
146
 
82
- :include: Contributing.rdoc
147
+ == Community and Contributing
83
148
 
84
- :include: Licence.rdoc
149
+ cartage-rack welcomes your contributions as described in
150
+ {Contributing.md}[https://github.com/KineticCafe/cartage-rack/blob/master/Contributing.md].
151
+ This project, like all Kinetic Cafe {open source
152
+ projects}[https://github.com/KineticCafe], is under the Kinetic Cafe Open
153
+ Source {Code of Conduct}[https://github.com/KineticCafe/code-of-conduct].
data/Rakefile CHANGED
@@ -1,11 +1,11 @@
1
- # -*- ruby -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
- require 'pathname'
5
+ require 'rake/clean'
6
6
 
7
7
  Hoe.plugin :doofus
8
- Hoe.plugin :email unless ENV['CI'] or ENV['TRAVIS']
8
+ Hoe.plugin :email unless ENV['CI'] || ENV['TRAVIS']
9
9
  Hoe.plugin :gemspec2
10
10
  Hoe.plugin :git
11
11
  Hoe.plugin :minitest
@@ -15,46 +15,55 @@ Hoe.plugin :travis
15
15
  spec = Hoe.spec 'cartage-rack' do
16
16
  developer('Austin Ziegler', 'aziegler@kineticcafe.com')
17
17
 
18
- self.history_file = 'History.rdoc'
18
+ self.history_file = 'History.md'
19
19
  self.readme_file = 'README.rdoc'
20
- self.extra_rdoc_files = FileList['*.rdoc'].to_a
21
20
 
22
21
  license 'MIT'
23
22
 
24
- self.extra_dev_deps << ['rake', '~> 10.0']
25
- self.extra_dev_deps << ['rack-test', '~> 0.6']
26
- self.extra_dev_deps << ['hoe-doofus', '~> 1.0']
27
- self.extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
28
- self.extra_dev_deps << ['hoe-git', '~> 1.5']
29
- self.extra_dev_deps << ['hoe-travis', '~> 1.2']
30
- self.extra_dev_deps << ['minitest', '~> 5.4']
31
- self.extra_dev_deps << ['minitest-autotest', '~> 1.0']
32
- self.extra_dev_deps << ['minitest-bisect', '~> 1.2']
33
- self.extra_dev_deps << ['minitest-focus', '~> 1.1']
34
- self.extra_dev_deps << ['minitest-moar', '~> 0.0']
35
- self.extra_dev_deps << ['minitest-pretty_diff', '~> 0.1']
36
- self.extra_dev_deps << ['simplecov', '~> 0.7']
23
+ ruby20!
24
+
25
+ # This gem *explicitly* does not have a hard link to cartage.
26
+
27
+ extra_dev_deps << ['rake', '>= 10.0']
28
+ extra_dev_deps << ['rdoc', '~> 4.2']
29
+ extra_dev_deps << ['rack-test', '~> 0.6']
30
+ extra_dev_deps << ['hoe-doofus', '~> 1.0']
31
+ extra_dev_deps << ['hoe-gemspec2', '~> 1.1']
32
+ extra_dev_deps << ['hoe-git', '~> 1.5']
33
+ extra_dev_deps << ['hoe-travis', '~> 1.2']
34
+ extra_dev_deps << ['minitest', '~> 5.4']
35
+ extra_dev_deps << ['minitest-autotest', '~> 1.0']
36
+ extra_dev_deps << ['minitest-bisect', '~> 1.2']
37
+ extra_dev_deps << ['minitest-bonus-assertions', '~> 2.0']
38
+ extra_dev_deps << ['minitest-focus', '~> 1.1']
39
+ extra_dev_deps << ['minitest-hooks', '~> 1.4']
40
+ extra_dev_deps << ['minitest-moar', '~> 0.0']
41
+ extra_dev_deps << ['minitest-pretty_diff', '~> 0.1']
42
+ extra_dev_deps << ['timecop', '~> 0.8']
43
+ extra_dev_deps << ['simplecov', '~> 0.7']
37
44
  end
38
45
 
39
- module Hoe::Publish
40
- alias_method :original_make_rdoc_cmd, :make_rdoc_cmd
46
+ ENV['RUBYOPT'] = '-W0'
47
+
48
+ module Hoe::Publish #:nodoc:
49
+ alias __make_rdoc_cmd__cartage__ make_rdoc_cmd
41
50
 
42
51
  def make_rdoc_cmd(*extra_args) # :nodoc:
43
- spec.extra_rdoc_files.reject! { |f| f == 'Manifest.txt' }
44
- original_make_rdoc_cmd(*extra_args)
52
+ spec.extra_rdoc_files.delete_if { |f| f == 'Manifest.txt' }
53
+ __make_rdoc_cmd__cartage__(*extra_args)
45
54
  end
46
55
  end
47
56
 
48
57
  namespace :test do
49
- task :coverage do
50
- prelude = <<-EOS
51
- require 'simplecov'
52
- SimpleCov.start('test_frameworks') { command_name 'Minitest' }
53
- gem 'minitest'
54
- EOS
55
- spec.test_prelude = prelude.split($/).join('; ')
56
- Rake::Task['test'].execute
58
+ if File.exist?('.simplecov-prelude.rb')
59
+ task :coverage do
60
+ spec.test_prelude = 'load ".simplecov-prelude.rb"'
61
+
62
+ Rake::Task['test'].execute
63
+ end
57
64
  end
65
+
66
+ CLOBBER << 'coverage'
58
67
  end
59
68
 
60
- # vim: syntax=ruby
69
+ CLOBBER << 'tmp'
data/lib/cartage/rack.rb CHANGED
@@ -1,76 +1,105 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
  require 'json'
3
5
 
4
6
  # Cartage, a package builder.
5
- class Cartage; end
6
-
7
- # Cartage::Rack is a simple application that reads an application’s
8
- # +release_hashref+ and returns it as a +text/plain+ string, or as
9
- # +application/json+ if it is called with +.json+.
10
- #
11
- # If +release_hashref+ does not exist, Cartage::Rack will read the hash of the
12
- # current HEAD.
13
- class Cartage::Rack
14
- VERSION = '1.1' #:nodoc:
15
-
16
- # Creates a new version of the Cartage::Rack application to the specified
17
- # +root_path+, or +Dir.pwd+.
18
- def self.mount(root_path = nil)
19
- new(root_path || Dir.pwd)
7
+ class Cartage
8
+ # Generate and mount the full metadata reporter, Cartage::Rack.
9
+ def self.Rack(root_path = nil, &filter)
10
+ Cartage::Rack.send(:new, root_path, &filter)
20
11
  end
21
12
 
22
- # Sets the root path for Cartage::Rack.
23
- def initialize(root_path)
24
- @root_path = Pathname(root_path)
25
- end
13
+ # Cartage::Rack is a simple application that reads an application's static
14
+ # release metadata and returns it as an (optionally filtered)
15
+ # +application/json+ value, or as a +text/plain+ string if called with
16
+ # +.text+ or +.txt+.
17
+ class Rack
18
+ VERSION = '2.0.rc1' #:nodoc:
19
+
20
+ class << self
21
+ # When +true+, Cartage::Rack and Cartage::Rack::Simple will raise an
22
+ # exception if there is no metadata file (<tt>release-metadata.json</tt> or
23
+ # +release_hashref+). May be explicitly turned off.
24
+ #
25
+ # Defaults to +true+ except in development or test environments (based on
26
+ # <tt>$RAILS_ENV</tt> and <tt>$RACK_ENV</tt>).
27
+ def require_metadata(value = (arg = false; nil)) # rubocop:disable Style/Semicolon
28
+ @require_metadata = value unless arg == false
29
+ @require_metadata || default_require_metadata
30
+ end
26
31
 
27
- # The Rack application method.
28
- def call(env)
29
- content = {
30
- env: application_env,
31
- release_hashref: release_hashref,
32
- timestamp: timestamp
33
- }.delete_if(&->(_, v) { v.nil? })
34
-
35
- case env['PATH_INFO']
36
- when /\.json\z/
37
- type = 'application/json'
38
- body = content.to_json
39
- else
40
- type = 'text/plain'
41
- body = "#{content[:env]}: #{content[:release_hashref]}"
42
- body += " (#{content[:timestamp]})" if content[:timestamp]
32
+ private
33
+
34
+ def default_require_metadata
35
+ (ENV['RAILS_ENV'] || ENV['RACK_ENV']).to_s !~ /\A(?:development|test)\z/i
36
+ end
43
37
  end
44
38
 
45
- [ '200', { 'Content-Type' => type }, [ body ] ]
46
- end
39
+ def initialize(root_path = nil, &filter) # :nodoc:
40
+ @metadata = Cartage::Rack::Metadata.new(root_path, filter: filter)
41
+ end
47
42
 
48
- def inspect
49
- %Q(#{self.class} for #{@root_path.expand_path.basename})
50
- end
43
+ def call(env) #:nodoc:
44
+ type, body = resolve_content(env)
45
+ [ '200', { 'Content-Type' => type }, [ body ] ]
46
+ end
51
47
 
52
- private
53
- def application_env
54
- ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'UNKNOWN'
55
- end
48
+ def inspect #:nodoc:
49
+ "#{self.class} for #{@metadata.inspect}"
50
+ end
56
51
 
57
- def release_hashref
58
- file = @root_path.join('release_hashref')
59
- if file.exist?
60
- file.read.split($/).first.chomp
61
- elsif @root_path.join('.git').directory?
62
- "(git) #{%x(git rev-parse --abbrev-ref HEAD).chomp}"
63
- else
64
- 'UNKNOWN - no release_hashref or .git directory'
52
+ private
53
+
54
+ def resolve_content(env)
55
+ content = @metadata.resolve
56
+
57
+ case env['PATH_INFO']
58
+ when /\.te?xt\z/
59
+ type = 'text/plain'
60
+ body = [
61
+ "name: #{dig(content, 'package', 'name')}",
62
+ "environment: #{dig(content, 'env', 'name')}",
63
+ "hashref: #{dig(content, 'package', 'hashref')}"
64
+ ]
65
+
66
+ value = dig(content, 'package', 'timestamp')
67
+ body << "timestamp: #{value}" if value
68
+
69
+ repo = dig(content, 'package', 'repo')
70
+ body << "#{repo['type']}: #{repo['url']}" if repo
71
+ body = body.join("\n")
72
+ else
73
+ type = 'application/json'
74
+ body = content.to_json
75
+ end
76
+
77
+ [ type, body ]
65
78
  end
66
- end
67
79
 
68
- def timestamp
69
- file = @root_path.join('release_hashref')
70
- if file.exist?
71
- stamp = file.read.split($/, 2)[1]
72
- stamp = nil if stamp && stamp.empty?
73
- stamp.chomp if stamp
80
+ attr_reader :metadata
81
+
82
+ #:nocov:
83
+ def dig(hash, key, *rest)
84
+ if hash.respond_to?(:dig)
85
+ hash.dig(key, *rest)
86
+ else
87
+ DIGGER.call(hash, key, *rest)
88
+ end
74
89
  end
90
+
91
+ DIGGER = ->(h, k, *r) { #:nodoc:
92
+ v = h[k]
93
+ if v.nil? || r.empty?
94
+ v
95
+ else
96
+ DIGGER.call(v, *r)
97
+ end
98
+ }
99
+ private_constant :DIGGER
100
+ #:nocov:
75
101
  end
76
102
  end
103
+
104
+ require_relative 'rack/simple'
105
+ require_relative 'rack/metadata'