capistrano-crontab 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0b55fea9c50337accbc5ea2d5ad5de57a589be0f
4
+ data.tar.gz: 9575801ba52762a84c644005792c96385e6554a4
5
+ SHA512:
6
+ metadata.gz: f79ef57a256bfe97ae9c11e12b15fc5ae1ac1d0afbdd3543ed6c94ec1a703f592c10a405b6cd39a83ed8f0a77fdd75595699ddb8ff004003985b1bd36d737bc4
7
+ data.tar.gz: 7ca9478f13d7a459864909635427709d563c99509eba9d6f03ab717257bdfe7bd8e117a48e84f3ea5c3c77a4d966cfd811b915e32097bef5f824c493305bb5a7
@@ -0,0 +1,2 @@
1
+ pkg
2
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,7 @@
1
+ # Contributing
2
+
3
+ 1. Fork it ([https://github.com/KumukanGmbH/capistrano-crontab/fork](https://github.com/KumukanGmbH/capistrano-crontab/fork))
4
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
5
+ 3. Commit your changes (`git commit -am 'add some feature'`)
6
+ 4. Push to the branch (`git push origin my-new-feature`)
7
+ 5. Create a new Pull Request
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in *.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016, Kumukan GmbH
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 all
13
+ 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 THE
21
+ SOFTWARE.
@@ -0,0 +1,105 @@
1
+ # Capistrano::Crontab
2
+
3
+ This capistrano plugin is inspired by [fab_deploy.crontab](https://bitbucket.org/kmike/django-fab-deploy/src/9c07813e136bf3e059684b4205e0577973c157b4/fab_deploy/crontab.py?at=default&fileviewer=file-view-default)
4
+ and allows you to add, remove and update cronjobs in your crontab.
5
+
6
+ ## Requirements
7
+
8
+ * capistrano >= 3.0
9
+ * sshkit >= 1.2
10
+
11
+ ## Installation
12
+
13
+ Add this to your `Gemfile`:
14
+
15
+ ```ruby
16
+ group :development do
17
+ gem "capistrano"
18
+ gem "capistrano-crontab"
19
+ end
20
+ ```
21
+
22
+ And then:
23
+
24
+ ```
25
+ $ bundle install
26
+ ```
27
+
28
+ ## Setup
29
+
30
+ Add this line to `Capfile`:
31
+
32
+ ```ruby
33
+ require "capistrano/crontab"
34
+ ```
35
+
36
+ ## DSL usage
37
+
38
+ ```ruby
39
+ on roles(:all) do
40
+ # output the content of your crontab using `puts`
41
+ crontab_puts_content
42
+
43
+ #
44
+ # Crontab:
45
+ # 30 7 * * * start -q anacron || :
46
+ #
47
+
48
+ # get the content of your crontab
49
+ crontab = crontab_get_content
50
+
51
+ #
52
+ # Crontab:
53
+ # 30 7 * * * start -q anacron || :
54
+ #
55
+
56
+ # add a new cronjob to your crontab and mark it with "date"
57
+ crontab_add_line("*/5 * * * * date >> /tmp/date", "date")
58
+
59
+ #
60
+ # Crontab:
61
+ # 30 7 * * * start -q anacron || :
62
+ # */5 * * * * data >> /tmp/date # MARKER:date
63
+ #
64
+
65
+ # update an existing cronjob in your crontab, which is marked with "date"
66
+ crontab_update_line("*/2 * * * * date >> /tmp/date", "date")
67
+
68
+ #
69
+ # Crontab:
70
+ # 30 7 * * * start -q anacron || :
71
+ # */2 * * * * date >> /tmp/date # MARKER:date
72
+ #
73
+
74
+ # ensure that a cronjob exists in your crontab, and mark it with "snapshot"
75
+ crontab_update_line("0 * * * * create_snapshot", "snapshot")
76
+
77
+ #
78
+ # Crontab
79
+ # 30 7 * * * start -q anacron || :
80
+ # */2 * * * * date >> /tmp/date # MARKER:date
81
+ # 0 * * * * create_snapshot # MARKER:snapshot
82
+ #
83
+
84
+ # remove the cronjob, which is marked with "date"
85
+ crontab_remove_line("date")
86
+
87
+ #
88
+ # Crontab:
89
+ # 30 7 * * * start -q anacron || :
90
+ # 0 * * * * create_snapshot # MARKER:snapshot
91
+ #
92
+
93
+ # overwrite the whole crontab
94
+ crontab_set_content("* * 1 * * send_invoices_to_customers")
95
+
96
+ #
97
+ # Crontab:
98
+ # * * 1 * * send_invoices_to_customers
99
+ #
100
+ end
101
+ ```
102
+
103
+ ## TODOs
104
+
105
+ * Update DSL to look more like `fab_deploy.crontab` (e.g. `crontab.add_line`)
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib)
4
+ require "capistrano/crontab/version"
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "capistrano-crontab"
8
+ gem.version = Capistrano::Crontab::VERSION
9
+ gem.authors = [ "Jan Pieper" ]
10
+ gem.email = [ "tech@kumukan.com" ]
11
+ gem.description = "Crontab DSL for Capistrano."
12
+ gem.summary = "Capistrano plugin for crontab DSL extension, to add/update/remove cronjobs."
13
+ gem.homepage = "https://github.com/KumukanGmbH/capistrano-crontab"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{bin/}).map { |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{spec/})
18
+ gem.require_paths = [ "lib" ]
19
+
20
+ gem.add_dependency "capistrano", ">= 3.0"
21
+ gem.add_dependency "sshkit", ">= 1.2"
22
+
23
+ gem.add_development_dependency "rake"
24
+ gem.add_development_dependency "rspec", ">= 3.0"
25
+ end
File without changes
@@ -0,0 +1 @@
1
+ require "capistrano/dsl/crontab"
@@ -0,0 +1,5 @@
1
+ module Capistrano
2
+ module Crontab
3
+ VERSION = "0.2.0"
4
+ end
5
+ end
@@ -0,0 +1,49 @@
1
+ module Capistrano
2
+ module DSL
3
+ def crontab_get_content
4
+ capture(:crontab, "-l")
5
+ end
6
+
7
+ def crontab_set_content(content)
8
+ tempfile = Tempfile.new
9
+ tempfile.write("#{content}\n")
10
+ tempfile.close
11
+
12
+ begin
13
+ upload!(tempfile.path, tempfile.path)
14
+ execute(:crontab, tempfile.path)
15
+ ensure
16
+ execute(:rm, "-f", tempfile.path)
17
+ tempfile.unlink
18
+ end
19
+ end
20
+
21
+ def crontab_puts_content
22
+ puts crontab_get_content
23
+ end
24
+
25
+ def crontab_add_line(content, marker = nil)
26
+ old_crontab = crontab_get_content
27
+ marker = crontab_marker(marker)
28
+ crontab_set_content("#{old_crontab.rstrip}\n#{content}#{marker}")
29
+ end
30
+
31
+ def crontab_remove_line(marker)
32
+ marker = crontab_marker(marker)
33
+
34
+ lines = crontab_get_content.split("\n")
35
+ .reject { |line| line.end_with?(marker) }
36
+
37
+ crontab_set_content(lines.join("\n"))
38
+ end
39
+
40
+ def crontab_update_line(content, marker)
41
+ crontab_remove_line(marker)
42
+ crontab_add_line(content, marker)
43
+ end
44
+
45
+ def crontab_marker(marker = nil)
46
+ marker.nil? ? "" : " # MARKER:%s" % [marker]
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,191 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe Capistrano::DSL do
4
+ let(:dsl) { Class.new { extend Capistrano::DSL } }
5
+ let(:tempfile) { StringIO.new }
6
+
7
+ before(:each) do
8
+ allow(Tempfile).to receive(:new).and_wrap_original { tempfile.reopen }
9
+ allow(tempfile).to receive(:path).and_return("/tmp/capistrano-crontab")
10
+ allow(tempfile).to receive(:unlink)
11
+
12
+ allow(dsl).to receive(:capture).with(:crontab, "-l").and_wrap_original { tempfile.string }
13
+ allow(dsl).to receive(:upload!)
14
+ allow(dsl).to receive(:execute)
15
+ end
16
+
17
+ describe ".crontab_get_content" do
18
+ it "should call .capture with :crontab and '-l' as arguments" do
19
+ expect(dsl).to receive(:capture).once.with(:crontab, "-l")
20
+ dsl.crontab_get_content
21
+ end
22
+
23
+ it "should return the return value of the call to .capture" do
24
+ allow(dsl).to receive(:capture).and_return("crontab content\n")
25
+ expect(dsl.crontab_get_content).to eql("crontab content\n")
26
+ end
27
+ end
28
+
29
+ describe ".crontab_set_content" do
30
+ context "if upload of tempfile fails" do
31
+ before(:each) do
32
+ expect(dsl).to receive(:upload!)
33
+ .once.with(tempfile.path, tempfile.path)
34
+ .and_raise("Upload failed")
35
+ end
36
+
37
+ after(:each) do
38
+ expect { dsl.crontab_set_content("irrelevant") }.to raise_error("Upload failed")
39
+ end
40
+
41
+ it "should not update crontab on the server" do
42
+ expect(dsl).not_to receive(:execute).with(:crontab, tempfile.path)
43
+ end
44
+
45
+ it "should delete tempfile on the server" do
46
+ expect(dsl).to receive(:execute).once.with(:rm, "-f", tempfile.path)
47
+ end
48
+
49
+ it "should delete tempfile locally" do
50
+ expect(tempfile).to receive(:unlink).once
51
+ end
52
+ end
53
+
54
+ context "if update of crontab fails" do
55
+ before(:each) do
56
+ expect(dsl).to receive(:execute)
57
+ .once.with(:crontab, tempfile.path)
58
+ .and_raise("Crontab update failed")
59
+ end
60
+
61
+ after(:each) do
62
+ expect { dsl.crontab_set_content("Irrelevant") }.to raise_error("Crontab update failed")
63
+ end
64
+
65
+ it "should upload tempfile to the server" do
66
+ expect(dsl).to receive(:upload!).once.with(tempfile.path, tempfile.path)
67
+ end
68
+
69
+ it "should delete tempfile on the server" do
70
+ expect(dsl).to receive(:execute).once.with(:rm, "-f", tempfile.path)
71
+ end
72
+
73
+ it "should delete tempfile locally" do
74
+ expect(tempfile).to receive(:unlink).once
75
+ end
76
+ end
77
+
78
+ context "if update of crontab is successful" do
79
+ after(:each) do
80
+ dsl.crontab_set_content("Irrelevant")
81
+ end
82
+
83
+ it "should upload tempfile to the server" do
84
+ expect(dsl).to receive(:upload!).once.with(tempfile.path, tempfile.path)
85
+ end
86
+
87
+ it "should update crontab on the server" do
88
+ expect(dsl).to receive(:execute).once.with(:crontab, tempfile.path)
89
+ end
90
+
91
+ it "should delete tempfile on the server" do
92
+ expect(dsl).to receive(:execute).once.with(:rm, "-f", tempfile.path)
93
+ end
94
+
95
+ it "should delete tempfile locally" do
96
+ expect(tempfile).to receive(:unlink)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe ".crontab_puts_content" do
102
+ it "should call .crontab_get_content without any args" do
103
+ expect(dsl).to receive(:crontab_get_content).once.with(no_args)
104
+ expect { dsl.crontab_puts_content }.to output.to_stdout
105
+ end
106
+
107
+ it "should write the return value of .crontab_get_content to stdout" do
108
+ allow(dsl).to receive(:crontab_get_content).and_return("crontab content\n")
109
+ expect { dsl.crontab_puts_content }.to output("crontab content\n").to_stdout
110
+ end
111
+ end
112
+
113
+ describe ".crontab_add_line" do
114
+ before(:each) do
115
+ dsl.crontab_set_content("* * * * * create_snapshot")
116
+ end
117
+
118
+ it "should call .crontab_set_content with previous crontab content and new line marked with 'backup'" do
119
+ expect(dsl).to receive(:crontab_set_content).once.with(
120
+ "* * * * * create_snapshot\n" \
121
+ "* * * * * rotate_logs # MARKER:backup"
122
+ )
123
+
124
+ dsl.crontab_add_line("* * * * * rotate_logs", "backup")
125
+ end
126
+ end
127
+
128
+ describe ".crontab_remove_line" do
129
+ before(:each) do
130
+ dsl.crontab_set_content(
131
+ "* * * * * create_snapshot\n" \
132
+ "* * * * * rotate_logs # MARKER:rotate\n" \
133
+ "* * * * * clear_cache # MARKER:clear"
134
+ )
135
+ end
136
+
137
+ it "should call .crontab_set_content with previous crontab content except the line marked with 'rotate'" do
138
+ expect(dsl).to receive(:crontab_set_content).once.with(
139
+ "* * * * * create_snapshot\n" \
140
+ "* * * * * clear_cache # MARKER:clear"
141
+ )
142
+
143
+ dsl.crontab_remove_line("rotate")
144
+ end
145
+ end
146
+
147
+ describe ".crontab_update_line" do
148
+ before(:each) do
149
+ dsl.crontab_set_content(
150
+ "* * * * * create_snapshot\n" \
151
+ "* * * * * rotate_logs # MARKER:rotate\n" \
152
+ "* * * * * clear_cache # MARKER:clear"
153
+ )
154
+ end
155
+
156
+ after(:each) do
157
+ dsl.crontab_update_line("0 0 * * * rotate_logs", "rotate")
158
+ end
159
+
160
+ it "should call .crontab_set_content with previous crontab content except the line to be updated" do
161
+ expect(dsl).to receive(:crontab_set_content).once.with(
162
+ "* * * * * create_snapshot\n" \
163
+ "* * * * * clear_cache # MARKER:clear" \
164
+ ).and_call_original
165
+
166
+ allow(dsl).to receive(:crontab_set_content)
167
+ .once.with(anything).and_call_original
168
+ end
169
+
170
+ it "should call .crontab_set_content with previous crontab content and updated line marked with 'rotate'" do
171
+ allow(dsl).to receive(:crontab_set_content)
172
+ .once.with(anything).and_call_original
173
+
174
+ expect(dsl).to receive(:crontab_set_content).with(
175
+ "* * * * * create_snapshot\n" \
176
+ "* * * * * clear_cache # MARKER:clear\n" \
177
+ "0 0 * * * rotate_logs # MARKER:rotate"
178
+ ).and_call_original
179
+ end
180
+ end
181
+
182
+ describe ".crontab_marker" do
183
+ it "should return empty marker string if no marker name is given" do
184
+ expect(dsl.crontab_marker).to eql("")
185
+ end
186
+
187
+ it "should return ' # MARKER:backup' if marker name is 'backup'" do
188
+ expect(dsl.crontab_marker("backup")).to eql(" # MARKER:backup")
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,92 @@
1
+ $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
2
+
3
+ require "capistrano/all"
4
+ require "capistrano/crontab"
5
+
6
+ # This file was generated by the `rspec --init` command. Conventionally, all
7
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
8
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
9
+ # this file to always be loaded, without a need to explicitly require it in any
10
+ # files.
11
+ #
12
+ # Given that it is always loaded, you are encouraged to keep this file as
13
+ # light-weight as possible. Requiring heavyweight dependencies from this file
14
+ # will add to the boot time of your test suite on EVERY test run, even for an
15
+ # individual file that may not need all of that loaded. Instead, consider making
16
+ # a separate helper file that requires the additional dependencies and performs
17
+ # the additional setup, and require it from the spec files that actually need
18
+ # it.
19
+ #
20
+ # The `.rspec` file also contains a few flags that are not defaults but that
21
+ # users commonly want.
22
+ #
23
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
24
+ RSpec.configure do |config|
25
+ # rspec-expectations config goes here. You can use an alternate
26
+ # assertion/expectation library such as wrong or the stdlib/minitest
27
+ # assertions if you prefer.
28
+ config.expect_with :rspec do |expectations|
29
+ # This option will default to `true` in RSpec 4. It makes the `description`
30
+ # and `failure_message` of custom matchers include text for helper methods
31
+ # defined using `chain`, e.g.:
32
+ # be_bigger_than(2).and_smaller_than(4).description
33
+ # # => "be bigger than 2 and smaller than 4"
34
+ # ...rather than:
35
+ # # => "be bigger than 2"
36
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
37
+ end
38
+
39
+ # rspec-mocks config goes here. You can use an alternate test double
40
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
41
+ config.mock_with :rspec do |mocks|
42
+ # Prevents you from mocking or stubbing a method that does not exist on
43
+ # a real object. This is generally recommended, and will default to
44
+ # `true` in RSpec 4.
45
+ #mocks.verify_partial_doubles = true
46
+ end
47
+
48
+ # These two settings work together to allow you to limit a spec run
49
+ # to individual examples or groups you care about by tagging them with
50
+ # `:focus` metadata. When nothing is tagged with `:focus`, all examples
51
+ # get run.
52
+ #config.filter_run :focus
53
+ #config.run_all_when_everything_filtered = true
54
+
55
+ # Limits the available syntax to the non-monkey patched syntax that is
56
+ # recommended. For more details, see:
57
+ # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
58
+ # - http://teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
59
+ # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
60
+ config.disable_monkey_patching!
61
+
62
+ # This setting enables warnings. It's recommended, but in some cases may
63
+ # be too noisy due to issues in dependencies.
64
+ config.warnings = true
65
+
66
+ # Many RSpec users commonly either run the entire suite or an individual
67
+ # file, and it's useful to allow more verbose output when running an
68
+ # individual spec file.
69
+ if config.files_to_run.one?
70
+ # Use the documentation formatter for detailed output,
71
+ # unless a formatter has already been configured
72
+ # (e.g. via a command-line flag).
73
+ config.default_formatter = "doc"
74
+ end
75
+
76
+ # Print the 10 slowest examples and example groups at the
77
+ # end of the spec run, to help surface which specs are running
78
+ # particularly slow.
79
+ #config.profile_examples = 10
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ config.order = :random
86
+
87
+ # Seed global randomization in this process using the `--seed` CLI option.
88
+ # Setting this allows you to use `--seed` to deterministically reproduce
89
+ # test failures related to randomization by passing the same `--seed` value
90
+ # as the one that triggered the failure.
91
+ Kernel.srand config.seed
92
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: capistrano-crontab
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Jan Pieper
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: capistrano
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sshkit
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: Crontab DSL for Capistrano.
70
+ email:
71
+ - tech@kumukan.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".rspec"
78
+ - CONTRIBUTING.md
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - capistrano-crontab.gemspec
84
+ - lib/capistrano-crontab.rb
85
+ - lib/capistrano/crontab.rb
86
+ - lib/capistrano/crontab/version.rb
87
+ - lib/capistrano/dsl/crontab.rb
88
+ - spec/lib/capistrano/dsl/crontab_spec.rb
89
+ - spec/spec_helper.rb
90
+ homepage: https://github.com/KumukanGmbH/capistrano-crontab
91
+ licenses: []
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.5.1
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Capistrano plugin for crontab DSL extension, to add/update/remove cronjobs.
113
+ test_files:
114
+ - spec/lib/capistrano/dsl/crontab_spec.rb
115
+ - spec/spec_helper.rb