at-random 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/Gemfile +5 -0
- data/README.md +33 -0
- data/Rakefile +2 -0
- data/at-random.gemspec +20 -0
- data/bin/at-random +6 -0
- data/lib/at-random/app.rb +44 -0
- data/lib/at-random/at_cmd.rb +24 -0
- data/lib/at-random/pick_time.rb +34 -0
- data/lib/at-random/version.rb +3 -0
- data/lib/at-random.rb +4 -0
- data/spec/at-random/app_spec.rb +204 -0
- data/spec/at-random/at_cmd_spec.rb +84 -0
- data/spec/at-random/pick_time_spec.rb +54 -0
- data/spec/at-random/version_spec.rb +7 -0
- data/spec/at_random_spec.rb +12 -0
- data/spec/spec_helper.rb +6 -0
- metadata +103 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# at-random
|
2
|
+
|
3
|
+
at-random [--random-seed seed] [--from HH[:MM]] [--to [HH[:MM]] [at-args]
|
4
|
+
|
5
|
+
Picks some time
|
6
|
+
between `--from` and `--to`
|
7
|
+
(in 24-hour format)
|
8
|
+
uniformly at random.
|
9
|
+
Passes the remaining args
|
10
|
+
(namely `[-q queue] [-f file] [-m]`)
|
11
|
+
along with standard input
|
12
|
+
to `at(1)` to run
|
13
|
+
at that time.
|
14
|
+
|
15
|
+
If `--from` is in the past,
|
16
|
+
`at-random` will re-roll times
|
17
|
+
until it gets one in the future.
|
18
|
+
If `--to` is in the past,
|
19
|
+
it will print an error message
|
20
|
+
and exit nonzero.
|
21
|
+
|
22
|
+
If `--random-seed` is passed,
|
23
|
+
it will be used to seed the PRNG.
|
24
|
+
|
25
|
+
|
26
|
+
This script can be used to implement random job start times in `cron(8)` with
|
27
|
+
`crontab(5)` lines like the following:
|
28
|
+
|
29
|
+
# m h dom month dow command
|
30
|
+
0 0 0 * 0 at-random --from 12:00 --to 17:00 -f /home/bob/reflect
|
31
|
+
|
32
|
+
which runs `at-random` at midnight every Sunday to tell `at(1)` to execute the
|
33
|
+
contents of `/home/bob/reflect` some time between noon and five PM.
|
data/Rakefile
ADDED
data/at-random.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/at-random/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Steve Dee"]
|
6
|
+
gem.email = ["steve@smartercode.net"]
|
7
|
+
gem.description = %q{Pick a random time subject to some constraints, and fork `at` with the remaining args.}
|
8
|
+
gem.summary = %q{Do things at random times}
|
9
|
+
gem.homepage = "https://github.com/mrdomino/at-random"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "at-random"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = AtRandom::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency 'rspec', ['>= 2']
|
19
|
+
gem.add_development_dependency 'mocha'
|
20
|
+
end
|
data/bin/at-random
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'at-random/at_cmd'
|
2
|
+
require 'at-random/pick_time'
|
3
|
+
|
4
|
+
module AtRandom
|
5
|
+
class App
|
6
|
+
def initialize(argv=[])
|
7
|
+
@pick_time_opts = {}
|
8
|
+
while argv[0] =~ /--(from|to|random-seed)/
|
9
|
+
arg = argv.shift
|
10
|
+
if arg =~ /--from/
|
11
|
+
from_str = arg.length > 6 ? arg[7..-1] : argv.shift
|
12
|
+
@pick_time_opts[:from] = from_str
|
13
|
+
elsif arg =~ /--to/
|
14
|
+
to_str = arg.length > 4 ? arg[5..-1] : argv.shift
|
15
|
+
@pick_time_opts[:to] = to_str
|
16
|
+
elsif arg =~ /--random-seed/
|
17
|
+
@random_seed = arg.length > 13 ? arg[14..-1].to_i : argv.shift
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
if @pick_time_opts[:from] && @pick_time_opts[:from].length == 2
|
22
|
+
@pick_time_opts[:from] += ':00'
|
23
|
+
end
|
24
|
+
|
25
|
+
if @pick_time_opts[:to] && @pick_time_opts[:to].length == 2
|
26
|
+
@pick_time_opts[:to] += ':59'
|
27
|
+
end
|
28
|
+
|
29
|
+
@at_args = argv
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
Kernel.srand(@random_seed) if @random_seed
|
34
|
+
@picked_time = PickTime.new @pick_time_opts
|
35
|
+
begin
|
36
|
+
AtCmd.new(@picked_time.time_s, @at_args).exec
|
37
|
+
0
|
38
|
+
rescue Exception => e
|
39
|
+
$stderr.puts e.message
|
40
|
+
-1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module AtRandom
|
2
|
+
class AtCmd
|
3
|
+
class InvalidTime < Exception; end
|
4
|
+
|
5
|
+
def initialize(*args)
|
6
|
+
if args[0]
|
7
|
+
timespec = args.shift
|
8
|
+
if !(timespec =~ /[0-2][0-9]:[0-5][0-9]/)
|
9
|
+
raise ArgumentError
|
10
|
+
end
|
11
|
+
|
12
|
+
if timespec < Time.now.strftime('%H:%M')
|
13
|
+
raise InvalidTime, "Timespec #{timespec} is earlier than now"
|
14
|
+
end
|
15
|
+
|
16
|
+
@exec_args = ['at', timespec, args].flatten
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def exec
|
21
|
+
Process.exec(*@exec_args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module AtRandom
|
2
|
+
class PickTime
|
3
|
+
class ImpossibleRange < Exception; end
|
4
|
+
|
5
|
+
def initialize(opts={})
|
6
|
+
from_h, from_m = parse_time(opts[:from] || '00:00')
|
7
|
+
to_h, to_m = parse_time(opts[:to] || '23:59')
|
8
|
+
now_h, now_m = parse_time(Time.now.strftime('%H:%M'))
|
9
|
+
|
10
|
+
if now_h >= from_h
|
11
|
+
from_h = now_h
|
12
|
+
if now_m > from_m
|
13
|
+
from_m = now_m
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if now_h > to_h || (now_h == to_h && now_m > to_m)
|
18
|
+
raise ImpossibleRange, 'Asked for :to sooner than now'
|
19
|
+
end
|
20
|
+
|
21
|
+
@hour = rand(to_h - from_h) + from_h
|
22
|
+
@minute = rand(to_m - from_m) + from_m
|
23
|
+
end
|
24
|
+
|
25
|
+
def time_s
|
26
|
+
format("%02d:%02d", @hour, @minute)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def parse_time(time_s)
|
31
|
+
time_s.split(':').map(&:to_i)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/at-random.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'at-random/app'
|
4
|
+
|
5
|
+
describe AtRandom::App do
|
6
|
+
let!(:mock_picked_time) { mock('PickTime') }
|
7
|
+
let!(:mock_at_cmd) { mock('AtCmd') }
|
8
|
+
|
9
|
+
before do
|
10
|
+
$stderr.stubs(:puts)
|
11
|
+
Kernel.stubs(:srand)
|
12
|
+
|
13
|
+
AtRandom::AtCmd.stubs(:new).returns(mock_at_cmd)
|
14
|
+
mock_at_cmd.stubs(:exec)
|
15
|
+
AtRandom::PickTime.stubs(:new).returns(mock_picked_time)
|
16
|
+
mock_picked_time.stubs(:time_s)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#run' do
|
20
|
+
def run_with_good_args
|
21
|
+
argv = %w[--random-seed=20 --from=12:34 --to=13 -q q -m]
|
22
|
+
AtRandom::App.new(argv).run
|
23
|
+
end
|
24
|
+
|
25
|
+
shared_examples_for 'successful run' do
|
26
|
+
it 'picks a time to pass to `at`' do
|
27
|
+
picked_time = '12:35'
|
28
|
+
mock_picked_time.expects(:time_s).returns(picked_time)
|
29
|
+
AtRandom::AtCmd.expects(:new).with(picked_time, any_parameters)
|
30
|
+
subject
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'calls AtCmd#exec' do
|
34
|
+
mock_at_cmd.expects(:exec)
|
35
|
+
subject
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with good arguments' do
|
40
|
+
subject { run_with_good_args }
|
41
|
+
|
42
|
+
context 'when successful' do
|
43
|
+
it_behaves_like 'successful run'
|
44
|
+
|
45
|
+
it 'passes appropriate arguments' do
|
46
|
+
Kernel.expects(:srand).with(20)
|
47
|
+
AtRandom::PickTime.expects(:new).
|
48
|
+
with(:from => '12:34', :to => '13:59').
|
49
|
+
returns(mock_picked_time)
|
50
|
+
AtRandom::AtCmd.expects(:new).with(anything, ['-q', 'q', '-m'])
|
51
|
+
subject
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when AtCmd raises an exception' do
|
56
|
+
before do
|
57
|
+
AtRandom::AtCmd.stubs(:new).raises(Exception, 'boom')
|
58
|
+
end
|
59
|
+
|
60
|
+
it { lambda { subject }.should_not raise_error }
|
61
|
+
|
62
|
+
it 'prints an error message to stderr' do
|
63
|
+
$stderr.expects(:puts).with(includes('boom'))
|
64
|
+
subject
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'returns a negative number' do
|
68
|
+
subject.should be < 0
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'without arguments' do
|
74
|
+
subject { AtRandom::App.new.run }
|
75
|
+
|
76
|
+
it_behaves_like 'successful run'
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '.new' do
|
81
|
+
describe 'arguments' do
|
82
|
+
def run_with_arg(arg)
|
83
|
+
AtRandom::App.new([arg]).run
|
84
|
+
end
|
85
|
+
|
86
|
+
shared_examples_for 'parametrized argument' do |param|
|
87
|
+
it 'understands --arg=param' do
|
88
|
+
AtRandom::App.new(["#{subject}=#{param}"]).run
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'understands --arg param' do
|
92
|
+
AtRandom::App.new([subject, param]).run
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
shared_examples_for 'time argument' do
|
97
|
+
it 'accepts HH' do
|
98
|
+
run_with_arg("#{subject}=23").should eq 0
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'accepts HH:MM' do
|
102
|
+
run_with_arg("#{subject}=01:23").should eq 0
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def run_with_time_arg(arg, time_s)
|
107
|
+
AtRandom::PickTime.expects(:new).
|
108
|
+
with(arg.to_sym => time_s).
|
109
|
+
returns(mock_picked_time)
|
110
|
+
run_with_arg("--#{arg}=#{time_s}")
|
111
|
+
end
|
112
|
+
|
113
|
+
describe '--from' do
|
114
|
+
subject { '--from' }
|
115
|
+
|
116
|
+
it_behaves_like 'time argument'
|
117
|
+
|
118
|
+
it_behaves_like 'parametrized argument', '01:23' do
|
119
|
+
before do
|
120
|
+
AtRandom::PickTime.expects(:new).
|
121
|
+
with(:from => '01:23').
|
122
|
+
returns(mock_picked_time)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'passes valid times to PickTime' do
|
127
|
+
run_with_time_arg 'from', '10:00'
|
128
|
+
|
129
|
+
run_with_time_arg 'from', '22:33'
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'expands "HH" to "HH:00"' do
|
133
|
+
AtRandom::PickTime.expects(:new).
|
134
|
+
with(:from => '11:00').
|
135
|
+
returns(mock_picked_time)
|
136
|
+
run_with_arg("--from=11")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe '--to' do
|
141
|
+
subject { '--to' }
|
142
|
+
|
143
|
+
it_behaves_like 'time argument'
|
144
|
+
|
145
|
+
it_behaves_like 'parametrized argument', '01:23' do
|
146
|
+
before do
|
147
|
+
AtRandom::PickTime.expects(:new).
|
148
|
+
with(:to => '01:23').
|
149
|
+
returns(mock_picked_time)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'passes to PickTime' do
|
154
|
+
run_with_time_arg 'to', '11:00'
|
155
|
+
|
156
|
+
run_with_time_arg 'to', '23:59'
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'expands "HH" to "HH:59"' do
|
160
|
+
AtRandom::PickTime.expects(:new).
|
161
|
+
with(:to => '12:59').
|
162
|
+
returns(mock_picked_time)
|
163
|
+
run_with_arg("--to=12")
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '--from and --to' do
|
168
|
+
specify 'both get passed to PickTime' do
|
169
|
+
AtRandom::PickTime.expects(:new).
|
170
|
+
with(:from => '23:05', :to => '23:04').
|
171
|
+
returns(mock_picked_time)
|
172
|
+
AtRandom::App.new(%w[--from=23:05 --to=23:04]).run
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe '--random-seed' do
|
177
|
+
subject { '--random-seed' }
|
178
|
+
|
179
|
+
it_behaves_like 'parametrized argument', 1234 do
|
180
|
+
before { Kernel.expects(:srand).with(1234) }
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'seeds the rng' do
|
184
|
+
Kernel.expects(:srand).with(12345)
|
185
|
+
run_with_arg('--random-seed=12345')
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe '`at` args' do
|
190
|
+
specify 'get passed to `at`' do
|
191
|
+
AtRandom::AtCmd.expects(:new).with(anything, %w[-q a])
|
192
|
+
AtRandom::App.new(%w[-q a]).run
|
193
|
+
end
|
194
|
+
|
195
|
+
describe 'other `at-random` args' do
|
196
|
+
specify "aren't passed to `at`" do
|
197
|
+
AtRandom::AtCmd.expects(:new).with(anything, %w[-m])
|
198
|
+
AtRandom::App.new(%w[--from=10:00 --to=12:00 -m]).run
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'at-random/at_cmd'
|
4
|
+
|
5
|
+
describe AtRandom::AtCmd do
|
6
|
+
let!(:frozen_now) { Time.local(2015, 05, 25) }
|
7
|
+
before do
|
8
|
+
Time.stubs(:now).returns(frozen_now)
|
9
|
+
Process.stubs(:exec)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:timespec) { '12:30' }
|
13
|
+
let(:at_args) { [] }
|
14
|
+
|
15
|
+
let(:at_with_args) { AtRandom::AtCmd.new(timespec, at_args) }
|
16
|
+
|
17
|
+
describe '.new' do
|
18
|
+
subject { at_with_args }
|
19
|
+
|
20
|
+
describe 'timespec argument' do
|
21
|
+
context 'a valid time string' do
|
22
|
+
let(:timespec) { '12:34' }
|
23
|
+
|
24
|
+
context 'after now' do
|
25
|
+
let(:frozen_now) { Time.local(2012, 05, 25, 12, 33) }
|
26
|
+
|
27
|
+
it { lambda { subject }.should_not raise_error }
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'before now' do
|
31
|
+
let(:frozen_now) { Time.local(2012, 05, 25, 12, 35) }
|
32
|
+
|
33
|
+
it { lambda { subject }.
|
34
|
+
should raise_error AtRandom::AtCmd::InvalidTime }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'a non-time string' do
|
39
|
+
let(:timespec) { 'as:df' }
|
40
|
+
|
41
|
+
it { lambda { subject }.should raise_error ArgumentError }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'a non-string' do
|
45
|
+
let(:timespec) { Time.local(2012, 05, 25, 12, 32) }
|
46
|
+
|
47
|
+
it { lambda { subject }.should raise_error ArgumentError }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'at_args argument' do
|
52
|
+
context 'an array of `at` args' do
|
53
|
+
let(:at_args) { ['-f', 'foo', '-mv'] }
|
54
|
+
|
55
|
+
it { lambda { subject }.should_not raise_error }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#exec' do
|
61
|
+
subject { at_with_args.exec }
|
62
|
+
|
63
|
+
it 'execs `at`' do
|
64
|
+
Process.expects(:exec).with('at', any_parameters)
|
65
|
+
subject
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'with at args' do
|
69
|
+
let(:at_args) { ['-f', 'foo'] }
|
70
|
+
|
71
|
+
it 'passes arguments to `at`' do
|
72
|
+
Process.expects(:exec).with('at', anything, '-f', 'foo')
|
73
|
+
subject
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '`at` timespec' do
|
78
|
+
it 'is the first argument to AtCmd.new' do
|
79
|
+
Process.expects(:exec).with('at', timespec, any_parameters)
|
80
|
+
subject
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'at-random/pick_time'
|
4
|
+
|
5
|
+
describe AtRandom::PickTime do
|
6
|
+
let(:frozen_now) { Time.local(1970, 1, 1, 0, 0) }
|
7
|
+
|
8
|
+
before do
|
9
|
+
Time.stubs(:now).returns(frozen_now)
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#time_s' do
|
13
|
+
it 'is a time string' do
|
14
|
+
subject.time_s.should =~ /[012][0-9]:[0-5][0-9]/
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'is a function of Kernel.rand' do
|
18
|
+
(1..20).map do |i|
|
19
|
+
Kernel.srand(i)
|
20
|
+
AtRandom::PickTime.new.time_s
|
21
|
+
end.uniq.length.should be_within(1).of(19)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'is the same every time for a given PickTime' do
|
25
|
+
subject.time_s.should eq subject.time_s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.new' do
|
30
|
+
context 'with :from => "00:34"' do
|
31
|
+
subject { AtRandom::PickTime.new :from => "00:34" }
|
32
|
+
|
33
|
+
its(:time_s) { should be > '00:34' }
|
34
|
+
|
35
|
+
context 'at 17:36pm local' do
|
36
|
+
let(:frozen_now) { Time.at(Time.local(2012, 05, 16, 17, 36)) }
|
37
|
+
|
38
|
+
its(:time_s) { should be > '17:36' }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with :to => "12:34"' do
|
43
|
+
subject { AtRandom::PickTime.new :to => '12:34' }
|
44
|
+
|
45
|
+
its(:time_s) { should be <= '12:34' }
|
46
|
+
|
47
|
+
context 'at 12:36pm local' do
|
48
|
+
let(:frozen_now) { Time.local(2012, 05, 16, 12, 36) }
|
49
|
+
|
50
|
+
it { lambda { subject }.should raise_error }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'at-random'
|
4
|
+
|
5
|
+
describe AtRandom do
|
6
|
+
it 'includes submodules' do
|
7
|
+
subject.const_defined?('App').should be_true
|
8
|
+
subject.const_defined?('PickTime').should be_true
|
9
|
+
subject.const_defined?('AtCmd').should be_true
|
10
|
+
subject.const_defined?('VERSION').should be_true
|
11
|
+
end
|
12
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: at-random
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Steve Dee
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-05-22 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: mocha
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Pick a random time subject to some constraints, and fork `at` with the
|
47
|
+
remaining args.
|
48
|
+
email:
|
49
|
+
- steve@smartercode.net
|
50
|
+
executables:
|
51
|
+
- at-random
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- .rspec
|
57
|
+
- Gemfile
|
58
|
+
- README.md
|
59
|
+
- Rakefile
|
60
|
+
- at-random.gemspec
|
61
|
+
- bin/at-random
|
62
|
+
- lib/at-random.rb
|
63
|
+
- lib/at-random/app.rb
|
64
|
+
- lib/at-random/at_cmd.rb
|
65
|
+
- lib/at-random/pick_time.rb
|
66
|
+
- lib/at-random/version.rb
|
67
|
+
- spec/at-random/app_spec.rb
|
68
|
+
- spec/at-random/at_cmd_spec.rb
|
69
|
+
- spec/at-random/pick_time_spec.rb
|
70
|
+
- spec/at-random/version_spec.rb
|
71
|
+
- spec/at_random_spec.rb
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
homepage: https://github.com/mrdomino/at-random
|
74
|
+
licenses: []
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.8.24
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: Do things at random times
|
97
|
+
test_files:
|
98
|
+
- spec/at-random/app_spec.rb
|
99
|
+
- spec/at-random/at_cmd_spec.rb
|
100
|
+
- spec/at-random/pick_time_spec.rb
|
101
|
+
- spec/at-random/version_spec.rb
|
102
|
+
- spec/at_random_spec.rb
|
103
|
+
- spec/spec_helper.rb
|