crntb 0.1.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7098325dce85f1836393f1a6e509b52cc8dee461
4
- data.tar.gz: 641ce5840bdc17aac7f2be6f2d0c084322ab05c8
3
+ metadata.gz: def18eedf778b1a5c534906f63c3ed9b12a3129f
4
+ data.tar.gz: a25aed6ca83b0e4a03efc25d54f456d2f29a41bd
5
5
  SHA512:
6
- metadata.gz: 99cb97810cdeec9ddfe1302226910a1ed2e17dae58c549f5090511d418e44c0ac8c13662bca3b9af1bbe8f68ac16522265bd0852b833621a2157a0b0c1542abf
7
- data.tar.gz: bed6742c8ba7f9c110b133aa4730184c9e5ad839fe3da6270ea12cf5758a3e76170767b6f366c46f8bed9db0cc0747870bf5b62a3468d0fe49e8fab81f423bf5
6
+ metadata.gz: e3328a02999cc990fb254044b11a986feae3bbfe5f54715d3729441ea19cee712c34380934307dfa36a006a8aee34894e4597150f016d6ebcca855a6504e0f6c
7
+ data.tar.gz: 4921ce724624cd787132c924e7e93f8052c06f724e981b7c680502ca259efea58fae2315234cb4d903b992e4a4f9e86af228acdb1ca34ef5223bc009c4b2f145
@@ -0,0 +1,44 @@
1
+ # Ruby CircleCI 2.0 configuration file
2
+ #
3
+ # Check https://circleci.com/docs/2.0/language-ruby/ for more details
4
+ #
5
+ version: 2
6
+ jobs:
7
+ build:
8
+ docker:
9
+ # specify the version you desire here
10
+ - image: circleci/ruby:2.4.1-node-browsers
11
+
12
+ # Specify service dependencies here if necessary
13
+ # CircleCI maintains a library of pre-built images
14
+ # documented at https://circleci.com/docs/2.0/circleci-images/
15
+ # - image: circleci/postgres:9.4
16
+
17
+ working_directory: ~/repo
18
+
19
+ steps:
20
+ - checkout
21
+
22
+ # Download and cache dependencies
23
+ - restore_cache:
24
+ keys:
25
+ - v1-dependencies-{{ checksum "Gemfile.lock" }}
26
+ # fallback to using the latest cache if no exact match is found
27
+ - v1-dependencies-
28
+
29
+ - run:
30
+ name: install dependencies
31
+ command: |
32
+ gem install bundler
33
+ bundle install --jobs=4 --retry=3 --path vendor/bundle
34
+
35
+ - save_cache:
36
+ paths:
37
+ - ./vendor/bundle
38
+ key: v1-dependencies-{{ checksum "Gemfile.lock" }}
39
+
40
+ # run tests!
41
+ - run:
42
+ name: run tests
43
+ command: |
44
+ bundle exec rake
data/Gemfile CHANGED
@@ -4,6 +4,8 @@ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
4
 
5
5
  gemspec
6
6
 
7
+ gem "crontab", github: 'litencatt/crontab', branch: 'keep-cron-definition'
8
+
7
9
  group :development do
8
10
  gem "pry-byebug"
9
11
  end
@@ -1,7 +1,14 @@
1
+ GIT
2
+ remote: https://github.com/litencatt/crontab
3
+ revision: 9c758a82a124f2b83a6e28ffb8cffce608f41844
4
+ branch: keep-cron-definition
5
+ specs:
6
+ crontab (0.0.2)
7
+
1
8
  PATH
2
9
  remote: .
3
10
  specs:
4
- crntb (0.1.0)
11
+ crntb (0.3.0)
5
12
 
6
13
  GEM
7
14
  remote: https://rubygems.org/
@@ -24,10 +31,11 @@ PLATFORMS
24
31
  DEPENDENCIES
25
32
  bundler (~> 1.16)
26
33
  crntb!
34
+ crontab!
27
35
  minitest
28
36
  pry
29
37
  pry-byebug
30
38
  rake (~> 10.0)
31
39
 
32
40
  BUNDLED WITH
33
- 1.16.1
41
+ 1.16.5
@@ -0,0 +1,54 @@
1
+ Inspired by http://crontab.homecoded.com/
2
+
3
+ Convert crontab lines to other format.
4
+
5
+ ### Install
6
+ ```
7
+ $ git clone https://github.com/litencatt/crntb
8
+ $ cd /path/to/crntb
9
+ $ bundle install --path vendor/bundle
10
+ ```
11
+
12
+ ### Usage
13
+ Convert a line.
14
+ ```rb
15
+ $ bin/console
16
+ [1] pry(main)> Crntb.parse("* * * * * foo.sh").to_h
17
+ => "{\"minute\":\"*\",\"hour\":\"*\",\"day_of_month\":\"*\",\"month\":\"*\",\"day_of_week\":\"*\",\"command\":\"foo.sh\"}"
18
+
19
+ [1] pry(main)> Crntb.parse("* * * * * foo.sh").to_json
20
+ => "{\"minute\":\"*\",\"hour\":\"*\",\"day_of_month\":\"*\",\"month\":\"*\",\"day_of_week\":\"*\",\"command\":\"foo.sh\"}"
21
+
22
+ [2] pry(main)> puts Crntb.parse("* * * * * foo.sh").to_chef
23
+ cron 'exec_foo.sh' do
24
+ minute "*"
25
+ hour "*"
26
+ day "*"
27
+ month "*"
28
+ weekday "*"
29
+ command "foo.sh"
30
+ end
31
+ => nil
32
+
33
+ [3] pry(main)> puts Crntb.parse("* * * * * foo.sh").to_whenever
34
+ every '* * * * *' do
35
+ command "foo.sh"
36
+ end
37
+ => nil
38
+ ```
39
+
40
+ Convert crontabs written in a file.
41
+ ```rb
42
+ $ bin/console
43
+ [1] pry(main)> entries = Crntb.parse_file("./sample.cron")
44
+
45
+ [2] pry(main)> entries.map{|e| pp e.to_json}
46
+ => ["{\"minute\":\"0\",\"hour\":\"8,10,12,14,16,18\",\"day_of_month\":\"*\",\"month\":\"*\",\"day_of_week\":\"*\",\"command\":\"php emptyTrash.php > log.txt\"}",
47
+ "{\"minute\":\"1-6,9,32\",\"hour\":\"*\",\"day_of_month\":\"*\",\"month\":\"*\",\"day_of_week\":\"*\",\"command\":\"echo \\\"sample me good\\\" > /etc/tmp/trash.txt\"}",
48
+ "{\"minute\":\"*\",\"hour\":\"4\",\"day_of_month\":\"*\",\"month\":\"*\",\"day_of_week\":\"*\",\"command\":\"/etc/init.d/apache2 restart\"}",
49
+ "{\"minute\":\"*\",\"hour\":\"*\",\"day_of_month\":\"3-4\",\"month\":\"1,4,5\",\"day_of_week\":\"*\",\"command\":\"/etc/init.d/apache2 restart\"}",
50
+ "{\"minute\":\"*\",\"hour\":\"*\",\"day_of_month\":\"3,5\",\"month\":\"12\",\"day_of_week\":\"1,5,6\",\"command\":\"/etc/init.d/apache2 restart\"}",
51
+ "{\"minute\":\"10\",\"hour\":\"4\",\"day_of_month\":\"1\",\"month\":\"*\",\"day_of_week\":\"*\",\"command\":\"/root/scripts/backup.sh\"}",
52
+ "{\"minute\":\"30\",\"hour\":\"3\",\"day_of_month\":\"*\",\"month\":\"*\",\"day_of_week\":\"mon\",\"command\":\"cat /proc/meminfo >> /tmp/meminfo\"}",
53
+ "{\"minute\":\"*\",\"hour\":\"*\",\"day_of_month\":\"*\",\"month\":\"*\",\"day_of_week\":\"*\",\"command\":\"top > test.txt\"}"]
54
+ ```
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/*_test.rb"]
8
+ end
9
+
10
+ task :default => :test
@@ -1,12 +1,14 @@
1
- require 'crntb/file'
2
- require 'crntb/field'
1
+ require 'crntb/line'
2
+ require 'crontab'
3
3
 
4
4
  module Crntb
5
- def self.parse(file)
6
- Crntb::File.parse(file)
5
+ def self.parse(line)
6
+ Crntb::Line.new(line)
7
7
  end
8
8
 
9
- def self.parse_line(line)
10
- Crntb::Line.new(line).parse
9
+ def self.parse_file(file)
10
+ ::File.readlines(file).each_with_object([]) do |line, arr|
11
+ arr << Crntb::Line.new(line.chomp!)
12
+ end
11
13
  end
12
14
  end
@@ -0,0 +1,27 @@
1
+ require 'crntb/outputer'
2
+ require 'json'
3
+
4
+ module Crntb
5
+ class Line
6
+ def initialize(line)
7
+ return if line.empty?
8
+ @entry = ::Crontab::Entry.parse(line)
9
+ end
10
+
11
+ def to_h
12
+ Crntb::Outputer::Hash.build(@entry)
13
+ end
14
+
15
+ def to_json
16
+ to_h.to_json
17
+ end
18
+
19
+ def to_chef
20
+ Crntb::Outputer::ChefCron.build(@entry)
21
+ end
22
+
23
+ def to_whenever
24
+ Crntb::Outputer::Whenever.build(@entry)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,8 @@
1
+ require 'crntb/outputer/hash'
2
+ require 'crntb/outputer/chef_cron'
3
+ require 'crntb/outputer/whenever'
4
+
5
+ module Crntb
6
+ module Outputer
7
+ end
8
+ end
@@ -0,0 +1,22 @@
1
+ module Crntb
2
+ module Outputer
3
+ module ChefCron
4
+ class << self
5
+ def build(entry)
6
+ fields = entry.cron_definition.split(/\s/, 5)
7
+
8
+ <<EOS
9
+ cron 'exec_#{entry.command}' do
10
+ minute "#{fields[0]}"
11
+ hour "#{fields[1]}"
12
+ day "#{fields[2]}"
13
+ month "#{fields[3]}"
14
+ weekday "#{fields[4]}"
15
+ command "#{entry.command}"
16
+ end
17
+ EOS
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ module Crntb
2
+ module Outputer
3
+ module Hash
4
+ class << self
5
+ def build(entry)
6
+ fields = entry.cron_definition.split(/\s/, 5)
7
+
8
+ {
9
+ "minute": fields[0],
10
+ "hour": fields[1],
11
+ "day_of_month": fields[2],
12
+ "month": fields[3],
13
+ "day_of_week": fields[4],
14
+ "command": entry.command
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,100 @@
1
+ module Crntb
2
+ module Outputer
3
+ module Text
4
+ class << self
5
+ attr_reader :result, :fields
6
+
7
+ def build(fields)
8
+ @result = ''
9
+ @fields = fields
10
+ day_week_month_result
11
+ min_hour_result
12
+ %Q{#{@result}\n run command "#{fields.command}"}
13
+ end
14
+
15
+ def day_week_month_result
16
+ build_month
17
+ build_day_of_month
18
+ build_day_of_week
19
+ end
20
+
21
+ def build_month
22
+ @result += "in #{fields.month}, on " if fields.month != '*'
23
+ @result += "every month on " if fields.month == '*' and fields.day_of_month != '*'
24
+ end
25
+
26
+ def build_day_of_month
27
+ if fields.day_of_month == '*'
28
+ @result += 'every day ' if fields.day_of_week == '*'
29
+ else
30
+ @result += 'the '
31
+ days = fields.day_of_month.split(',')
32
+ days.each do |day|
33
+ case day.to_i
34
+ when 1
35
+ @result += "#{day}st,"
36
+ when 2
37
+ @result += "#{day}nd,"
38
+ when 3
39
+ @result += "#{day}rd,"
40
+ else
41
+ @result += "#{day}th,"
42
+ end
43
+ end
44
+ @result.slice!(@result.size - 1, 1)
45
+ @result += ' '
46
+ end
47
+ end
48
+
49
+ def build_day_of_week
50
+ if fields.day_of_week != '*'
51
+ @result += 'and on ' if fields.day_of_month != '*'
52
+ @result += fields.day_of_week + ' '
53
+ end
54
+ end
55
+
56
+ def min_hour_result
57
+ hour_collections = fields.hour.split(',')
58
+ min_collections = fields.minute.split(',')
59
+ if hour_collections.length > 1 or hour_collections[0].to_i.to_s == hour_collections[0]
60
+ # input exp. ["1,2"]
61
+ if min_collections.length > 1 or min_collections[0].to_i.to_s == min_collections[0]
62
+ @result += 'at '
63
+ hour_collections.each do |hour_collection|
64
+ min_collections.each do |min_collection|
65
+ @result += "%#02d" % hour_collection + ':' + "%#02d" % min_collections + ', '
66
+ end
67
+ end
68
+ @result.slice!(@result.size - 2, 2)
69
+ else
70
+ @result += "on #{fields.minute} when hour is ("
71
+ hour_collections.each do |hour_collection|
72
+ @result += "%#02d" % hour_collection + ', '
73
+ end
74
+ @result.slice!(@result.size - 2, 2)
75
+ @result += ')'
76
+ end
77
+ else
78
+ # input exp. ["every hour"]
79
+ if min_collections.length > 1
80
+ @result += "on #{fields.hour} when minute equals one of ("
81
+ min_collections.each do |min_collection|
82
+ @result += "%#02d" % min_collection + ', '
83
+ end
84
+ @result.slice!(@result.size - 2, 2)
85
+ @result += ')'
86
+ else
87
+ if fields.hour.to_i.to_s == fields.hour and fields.minute.to_i.to_s == fields.minute
88
+ @result += "on #{fields.hour}:#{fields.minute}"
89
+ elsif fields.minute.to_i.to_s == fields.minute
90
+ @result += "on #{fields.hour} when minute equals " + "%#02d" % fields.minute
91
+ else
92
+ @result += "on #{fields.hour} on #{fields.minute}"
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,15 @@
1
+ module Crntb
2
+ module Outputer
3
+ module Whenever
4
+ class << self
5
+ def build(entry)
6
+ <<EOS
7
+ every '#{entry.cron_definition}' do
8
+ command "#{entry.command}"
9
+ end
10
+ EOS
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -1,3 +1,3 @@
1
1
  module Crntb
2
- VERSION = '0.1.0'
2
+ VERSION = '0.3.0'
3
3
  end
@@ -1 +1,8 @@
1
- * * * * * sample.sh
1
+ 0 8,10,12,14,16,18 * * * php emptyTrash.php > log.txt
2
+ 1-6,9,32 * * * * echo "sample me good" > /etc/tmp/trash.txt
3
+ * 4 * * * /etc/init.d/apache2 restart
4
+ * * 3-4 1,4,5 * /etc/init.d/apache2 restart
5
+ * * 3,5 12 1,5,6 /etc/init.d/apache2 restart
6
+ 10 4 1 * * /root/scripts/backup.sh
7
+ 30 3 * * mon cat /proc/meminfo >> /tmp/meminfo
8
+ * * * * * top > test.txt
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: crntb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - litencatt
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-06-17 00:00:00.000000000 Z
11
+ date: 2018-10-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -73,17 +73,23 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".circleci/config.yml"
76
77
  - Gemfile
77
78
  - Gemfile.lock
78
79
  - LICENSE
80
+ - README.md
81
+ - Rakefile
79
82
  - bin/console
80
83
  - crntb.gemspec
81
84
  - lib/crntb.rb
82
- - lib/crntb/field.rb
83
- - lib/crntb/file.rb
85
+ - lib/crntb/line.rb
86
+ - lib/crntb/outputer.rb
87
+ - lib/crntb/outputer/chef_cron.rb
88
+ - lib/crntb/outputer/hash.rb
89
+ - lib/crntb/outputer/text.rb
90
+ - lib/crntb/outputer/whenever.rb
84
91
  - lib/crntb/version.rb
85
92
  - sample.cron
86
- - sample.cron1
87
93
  homepage: https://github.com/litencatt/crntb
88
94
  licenses:
89
95
  - MIT
@@ -104,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
104
110
  version: '0'
105
111
  requirements: []
106
112
  rubyforge_project:
107
- rubygems_version: 2.6.14
113
+ rubygems_version: 2.6.13
108
114
  signing_key:
109
115
  specification_version: 4
110
116
  summary: Crontab format parser
@@ -1,202 +0,0 @@
1
- module Crntb
2
- class Field
3
- attr_reader :field
4
-
5
- class << self
6
- def parse(field)
7
- self.new(field).parse
8
- end
9
- end
10
-
11
- def initialize(field)
12
- @field = field
13
- end
14
-
15
- def parse
16
- #return nil unless valid?
17
- return '*' if first_to_last?
18
- interpretation
19
- end
20
-
21
- # 先頭文字列を処理
22
- # */...
23
- # n...
24
- # それ以降はカンマ区切りでsplitして-はloop処理しての繰り返し
25
- def interpretation
26
- step_collections = field.split(',')
27
- collections = []
28
- step_collections.each do |step_collection|
29
- # /でsplitした結果
30
- step = get_step(step_collection)
31
-
32
- # /が使われてればstep[1]には分割数が来るはず, なければ1
33
- # 次のrange処理で使う
34
- if step[1] && step[1].match(/^[0-9]+$/)
35
- step_size = step[1].to_i
36
- else
37
- step_size = 1
38
- end
39
-
40
- # step[0] : * => min..max
41
- # step[0] : n-m => n..m
42
- range = get_range(step[0])
43
- if range.length > 1
44
- s = range[0].to_i
45
- e = range[1].to_i
46
- s.step(e, step_size) { |r| collections << r }
47
- end
48
- end
49
- collections.uniq.sort
50
- # 曜日や月は文字列にして追加
51
- # そうでなければ数字を追加
52
- result = collections.inject '' do |res, collection|
53
- res += collection.to_s
54
- res += ", "
55
- end
56
- result.slice!(result.size - 2, 2)
57
- result
58
- end
59
-
60
- def get_collection
61
-
62
- end
63
-
64
- # e.g
65
- # "*/1" => ["*", "1"]
66
- # "*/1,2-4" => ["*", "1,2-4"]
67
- def get_range(value)
68
- if value == '*'
69
- [field_range.first, field_range.last]
70
- else
71
- value.split('-')
72
- end
73
- end
74
-
75
- def get_step(value)
76
- value.split('/')
77
- end
78
-
79
- def expand_range(collections)
80
- result = []
81
- collections.each do |collection|
82
- if collection.include?('-')
83
- min, max = collection.split('-', 2)
84
- for i in min..max do
85
- result << i
86
- end
87
- else
88
- result << collection
89
- end
90
- end
91
- end
92
-
93
- def first_to_last?
94
- field == '*'
95
- end
96
-
97
- def range_time?
98
- end
99
-
100
- def every_time?
101
- end
102
-
103
- private
104
-
105
- def have_asterisk?
106
- field.include?('*')
107
- end
108
-
109
- def have_hyphen?
110
- field.include?('-')
111
- end
112
-
113
- def have_slash?
114
- field.include?('/')
115
- end
116
-
117
- def have_comma?
118
- field.include?(',')
119
- end
120
- end
121
-
122
- class Minute < Field
123
- def field_range
124
- 0..59
125
- end
126
-
127
- def parse
128
- case field
129
- when '*'
130
- "every minute"
131
- else
132
- "when minute equals #{super}"
133
- end
134
- end
135
- end
136
-
137
- class Hour < Field
138
- def parse
139
- case field
140
- when '*'
141
- "every hour "
142
- else
143
- "at #{super}"
144
- end
145
- end
146
-
147
- def field_range
148
- 0..23
149
- end
150
- end
151
-
152
- class DayOfMonth < Field
153
- def parse
154
- case field
155
- when '*'
156
- ""
157
- else
158
- "on the #{super}"
159
- end
160
-
161
- end
162
-
163
- def field_range
164
- 1..31
165
- end
166
- end
167
-
168
- class Month < Field
169
- def parse
170
- case field
171
- when '*'
172
- "every day "
173
- else
174
- "In #{super}"
175
- end
176
-
177
- end
178
-
179
- def field_range
180
- 1..12
181
- end
182
- end
183
-
184
- class DayOfWeek < Field
185
- def parse
186
- case field
187
- when '*'
188
- ""
189
- else
190
- "and on #{super}"
191
- end
192
- end
193
-
194
- def field_range
195
- 0..7
196
- end
197
- end
198
- class Command < Field
199
- def parse
200
- end
201
- end
202
- end
@@ -1,38 +0,0 @@
1
- module Crntb
2
- class File
3
- def self.parse(file)
4
- ::File.readlines(file).each do |line|
5
- Crntb::Line.new(line).parse
6
- end
7
- end
8
- end
9
-
10
- class Line
11
- attr_reader :minute, :hour, :day_of_month, :month, :day_of_week, :command
12
-
13
- def initialize(line)
14
- fields = manipuate(line)
15
- @minute = Minute.parse(fields[0])
16
- @hour = Hour.parse(fields[1])
17
- @day_of_month = DayOfWeek.parse(fields[2])
18
- @month = Month.parse(fields[3])
19
- @day_of_week = DayOfMonth.parse(fields[4])
20
- @command = fields[5].chomp
21
- end
22
-
23
- def parse
24
- [
25
- day_of_week,
26
- month,
27
- day_of_month,
28
- hour,
29
- minute,
30
- "\n exec #{@command}",
31
- ].join
32
- end
33
-
34
- def manipuate(line)
35
- line.split(' ', 6)
36
- end
37
- end
38
- end
@@ -1,14 +0,0 @@
1
- * * * * * sample.sh && foo.sh && bar.sh
2
- 0 * * * * sample.sh
3
- 00 * * * * sample.sh
4
- */10 * * * * sample.sh
5
- 00 05 * * * sample.sh
6
- 30 08 * * * sample.sh
7
- 0,30 8-22 * * * sample.sh
8
- 00,30 * * * * sample.sh
9
- 00 00 1 * * sample.sh
10
- 00 01 1 * * sample.sh
11
- 0 9 25-29 * * sample.sh
12
- 00 09 13-17 * * sample.sh
13
- 00 02,05,08 * * * sample.sh
14
- 30 23 28-31 * * sample.sh