detom 0.0.1 → 0.0.2

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
  SHA256:
3
- metadata.gz: 27690f426f4574891be0599cf5316fd3f5c52af44f439e2a3a4081af034ae18a
4
- data.tar.gz: 16f3a7bc52f572e97d77676b0aa0c4843308fbcda9aeedf923dd90124ab8d75a
3
+ metadata.gz: 82f9459a02a471b8cd6fe1168bda3f663cff518e300668c0e1f41f455ac66fa6
4
+ data.tar.gz: b5edb03876409bb6ba73d0ffd8c9d874a7efacd541487c93ba952b98584ce135
5
5
  SHA512:
6
- metadata.gz: 7e760682f0d9b8ff4ec60c5d5aadf1ac9d4d9b5cc1f41942aa4411438f6206f0bd1d20a1b274850cc60c3b1220cb0ed95d08626c4ed39d9e8d9316e074356913
7
- data.tar.gz: 54641b2f23fd77bf4647d7fe7251e2f9cd8b906a618e8548c36756539cf26d6f0fa7527a4a98463c863f2617685e396d8a1983d3f1f2527c9ef5663c98c98613
6
+ metadata.gz: 3bbcfcbde4995ea552c708d3cc161cfcf90189a9afe22162be9f85c6d0acb4f1bab64eec7ad41b1348501fe1e8798da655b2e6ef58ba585bd5260540a4262482
7
+ data.tar.gz: d32cf43ed5452561b4c93ae743ea6b5f11a3da04c40ff6ee09719981d327d74b45d1774fefcf705231cef8cfd95c8f06f055de7720d198c0213f2cf15eb8c907
@@ -0,0 +1,2 @@
1
+ pkg
2
+ tmp
@@ -1,7 +1,41 @@
1
- # detom
1
+ # detom - A personal project
2
2
 
3
3
  _Combien de temps?_
4
4
 
5
5
  A minimal command line interface for tracking time spent against projects of clients.
6
6
 
7
7
  Time is manually logged in minutes or hours, either today or for a specified date.
8
+
9
+ This project is a small, personal project that I don't expect anyone else to use seriously.
10
+ If you do think this is something that you might use, please [let me know on Twitter](https://twitter.com/njpearman).
11
+
12
+ Installation is as one would expect:
13
+
14
+ ```
15
+ gem install detom
16
+ ```
17
+
18
+ ## Motivation
19
+ This is a toy project that allows me to practice a few different things:
20
+
21
+ * Think about the design of command line apps.
22
+ * Practice the topics covered in Build Awesome Command Line Applications in Ruby 2 by David Copeland, published by The Pragmatic Bookshelf but seemingly now out of print (which is a great shame because it's a great book)
23
+ * Think about what's important when recording time spent on projects and clients.
24
+ * Practice writing and testing Ruby code.
25
+
26
+ ## Commands
27
+
28
+ For detailed instructions on commands, use `detom --help` and `detom <command> --help`.
29
+
30
+ `detom clients`
31
+
32
+ Lists all clients that have time recorded against them, and the total amount of time in minutes.
33
+
34
+ `detom record`
35
+
36
+ Allows an amount of time in minutes to be added to a client / project. Optionally can be set to a different date of the same year.
37
+
38
+ ## Commands to implement
39
+
40
+ * `archive`
41
+ * `mark`
data/bin/detom CHANGED
@@ -34,15 +34,15 @@ class App
34
34
  end
35
35
 
36
36
  desc "Record some time spent on a client. <client> and <time> are required. <client> is the name of the client and <time> is an amount of time in minutes, e.g. 39m, or hours, e.g. 3h"
37
- arg_name "<client> <time>"
37
+ arg_name "<time> <client>"
38
38
  command :record do |c|
39
39
  c.flag [:d, :"day-month"]
40
40
  c.action do |global_options, options, args|
41
- help_now! "You must provide record with <client> and <time> as arguments" if args.length < 2
42
-
43
41
  begin
44
42
  store = YamlFileStore.new
45
- Commands::Record.new(store).call args[0], args[1], options[:d]
43
+ local_config = Detom::LocalConfig.new
44
+ Commands::Record.new(store, local_config)
45
+ .call args[0], args[1], options[:d]
46
46
  rescue StandardError => e
47
47
  STDERR.puts e.message
48
48
  STDERR.puts e.backtrace
@@ -50,6 +50,23 @@ class App
50
50
  end
51
51
  end
52
52
 
53
+ desc "Sets a default client and project for the current folder, by creating or updating a .detom file. Run in the root of a project directory"
54
+ arg_name "<client> [project]"
55
+ command :set do |c|
56
+ c.action do |global_options, options, args|
57
+ Commands::Set.new.call args[0], args[1]
58
+ end
59
+ end
60
+
61
+ desc "Outputs time tracked against one client in detail."
62
+ arg_name "<client>"
63
+ command :client do |c|
64
+ c.action do |global_options, options, args|
65
+ store = YamlFileStore.new
66
+ Commands::Client.new(store).call args[0]
67
+ end
68
+ end
69
+
53
70
  desc "Archive tracking for a client or a project. Literally copies the client file into ~/.detom/archive/client-<today>.json"
54
71
  arg_name "client"
55
72
  command :archive do |c|
@@ -1,8 +1,12 @@
1
1
  require "detom/version.rb"
2
2
 
3
3
  require "detom/yaml_file_store"
4
+ require "detom/local_config"
5
+
6
+ require "detom/commands/client"
4
7
  require "detom/commands/clients"
5
8
  require "detom/commands/record"
9
+ require "detom/commands/set"
6
10
 
7
11
  # Add requires for other files you add to your project here, so
8
12
  # you just need to require this one file in your bin file
@@ -0,0 +1,38 @@
1
+ module Commands
2
+ class Client
3
+ CLIENT_REQUIRED_MESSAGE = "You must provide a client name to detom client."
4
+
5
+ def initialize(store)
6
+ @store = store
7
+ end
8
+
9
+ def call(client_name)
10
+ raise CLIENT_REQUIRED_MESSAGE if client_name.nil? || client_name.empty?
11
+
12
+ client = @store[client_name]
13
+
14
+ if client
15
+ output = client.sort.map do |day, times|
16
+ "#{day}: #{format times}"
17
+ end.join "\n"
18
+ $stdout.puts output
19
+ else
20
+ $stdout.puts "No time logged against #{client_name}"
21
+ end
22
+ end
23
+
24
+ private
25
+ def format(times)
26
+ total_time = times.inject(0, &:+)
27
+
28
+ parts = []
29
+ hours = (total_time / 60).floor
30
+ parts << "#{hours}h" if hours > 0
31
+
32
+ minutes = total_time % 60
33
+ parts << "#{minutes}m" if minutes > 0
34
+
35
+ parts.join
36
+ end
37
+ end
38
+ end
@@ -1,35 +1,55 @@
1
1
  module Commands
2
2
  class Record
3
- def initialize(store)
3
+ CLIENT_REQUIRED_MESSAGE = "Cannot log time without a client. Either provide <client> to detom record, or configure a value for client in this directory using detom set."
4
+ DATE_FORMAT_MESSAGE = "Day/month is an unrecognised format. Use `%d-%m` format"
5
+ TIME_TO_LOG_FORMAT_MESSAGE = "Time must be provided in minutes or hours, e,g 40m or 3h"
6
+
7
+ def initialize(store, local_config)
4
8
  @store = store
9
+ @local_config = local_config
5
10
  end
6
11
 
7
- def call(client_name, time_to_log, day_month = nil)
8
- if day_month
9
- raise "Day/month is an unrecognised format. Use `%d-%m` format" unless day_month =~ /\d\d-\d\d/
10
-
11
- day = day_month.split("-").first
12
- month = day_month.split("-").last
13
-
14
- # parse
15
- day_month = [Time.now.year.to_s, month, day].join "-"
16
- else
17
- day_month = Time.now.strftime("%Y-%m-%d")
18
- end
12
+ def call(time_to_log, client_name=nil, day_month=nil)
13
+ client = client_for client_name
14
+
15
+ date_stamp = format(day_month)
16
+
17
+ client[date_stamp] = [] unless client[date_stamp]
18
+
19
+ client[date_stamp] << minutes_from(time_to_log)
20
+
21
+ @store.save!
22
+ $stdout.puts "Logged #{time_to_log} for #{client_name}"
23
+ end
24
+
25
+ private
26
+ def format(day_month)
27
+ return Time.now.strftime("%Y-%m-%d") if day_month.nil?
28
+
29
+ raise DATE_FORMAT_MESSAGE unless day_month =~ /\d\d-\d\d/
30
+
31
+ splits = day_month.split "-"
32
+ [Time.now.year.to_s, splits.last, splits.first].join "-"
33
+ end
34
+
35
+ def client_for(client_name)
36
+ raise CLIENT_REQUIRED_MESSAGE if client_name.nil? && @local_config.client.nil?
37
+
38
+ client_name = client_name || @local_config.client
19
39
 
20
40
  @store[client_name] = {} if @store[client_name].nil?
21
41
 
22
- client = @store[client_name]
42
+ @store[client_name]
43
+ end
23
44
 
24
- if client[day_month]
25
- client[day_month] << time_to_log.to_i
26
- else
27
- client[day_month] = [ time_to_log.to_i ]
45
+ def minutes_from(time_to_log)
46
+ multiplier = case time_to_log
47
+ when /\d+m/ then 1
48
+ when /\d+h/ then 60
49
+ else raise TIME_TO_LOG_FORMAT_MESSAGE
28
50
  end
29
51
 
30
- @store.save!
31
- puts "Logged #{time_to_log} for #{client_name}"
52
+ multiplier * time_to_log.to_i
32
53
  end
33
54
  end
34
55
  end
35
-
@@ -0,0 +1,16 @@
1
+ module Commands
2
+ class Set
3
+ def initialize(local_config=Detom::LocalConfig.new)
4
+ @local_config = local_config
5
+ end
6
+
7
+ def call(client, project=nil)
8
+ @local_config.load!
9
+
10
+ @local_config.client = client
11
+ @local_config.project = project
12
+
13
+ @local_config.save!
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,54 @@
1
+ require 'yaml'
2
+
3
+ module Detom
4
+ class LocalConfig
5
+ def load!
6
+ return if @store
7
+
8
+ if Dir.exist? ".detom"
9
+ raise "Found .detom but it is a directory. Are you running `detom set` in your home directory?\n`detom set` should be run in the root of a project folder"
10
+ end
11
+
12
+ if File.exist? ".detom"
13
+ @store = YAML.load File.read(".detom")
14
+ else
15
+ @store = {}
16
+ end
17
+ end
18
+
19
+ def load_from!(config)
20
+ @store ||= {}
21
+ @store.merge! config
22
+ end
23
+
24
+ def save!
25
+ @store.keys.each {|key| @store.delete(key) if @store[key].nil? }
26
+
27
+ File.open(".detom", "w") {|file| file.write YAML.dump(@store) }
28
+ puts "New config: #{@store}"
29
+ end
30
+
31
+ def method_missing(name, *args, &block)
32
+ super unless handle?(name)
33
+
34
+ handle(name, *args)
35
+ end
36
+
37
+ private
38
+ def handle?(name)
39
+ %i(client client= project=).include? name
40
+ end
41
+
42
+ def handle(name, *args)
43
+ self.load!
44
+
45
+ setter_match = name.match /(.*)=\B/
46
+
47
+ if setter_match && setter_match[1]
48
+ @store[setter_match[1].to_sym] = args.shift
49
+ else
50
+ @store[name]
51
+ end
52
+ end
53
+ end
54
+ end
@@ -1,3 +1,3 @@
1
1
  module Detom
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -0,0 +1,69 @@
1
+ require "detom/commands/client"
2
+
3
+ describe Commands::Client do
4
+ describe "#call" do
5
+ subject { described_class.new(store).call(client_name) }
6
+
7
+ let(:store) { {} }
8
+ let(:today) { Time.now.strftime("%Y-%m-%d") }
9
+
10
+ context "with a nil client" do
11
+ let(:client_name) { nil }
12
+ it do
13
+ expect { subject }.to raise_error Commands::Client::CLIENT_REQUIRED_MESSAGE
14
+ end
15
+ end
16
+
17
+ context "with no client given" do
18
+ let(:client_name) { "" }
19
+ it do
20
+ expect { subject }.to raise_error Commands::Client::CLIENT_REQUIRED_MESSAGE
21
+ end
22
+ end
23
+
24
+ context "with a client that has no time logged" do
25
+ let(:client_name) { "foo_client" }
26
+ it do
27
+ expect { subject }.to output("No time logged against foo_client\n").to_stdout
28
+ end
29
+ end
30
+
31
+ context "with a client that has one entry today" do
32
+ let(:client_name) { "foo_client" }
33
+
34
+ let(:store) { { "foo_client" => { today => [50] } } }
35
+ it do
36
+ expected_output = <<OUT
37
+ #{today}: 50m
38
+ OUT
39
+ expect { subject }.to output(expected_output).to_stdout
40
+ end
41
+ end
42
+
43
+ context "with a client that has two entries today" do
44
+ let(:client_name) { "foo_client" }
45
+
46
+ let(:store) { { "foo_client" => { today => [50, 5] } } }
47
+ it do
48
+ expected_output = <<OUT
49
+ #{today}: 55m
50
+ OUT
51
+ expect { subject }.to output(expected_output).to_stdout
52
+ end
53
+ end
54
+
55
+ context "with a client that has two entries today and one in the past" do
56
+ let(:client_name) { "foo_client" }
57
+ let(:time_before) { (Time.now - (60*60*24*10)).strftime("%Y-%m-%d") }
58
+
59
+ let(:store) { { "foo_client" => { today => [50, 5], time_before => [130] } } }
60
+ it do
61
+ expected_output = <<OUT
62
+ #{time_before}: 2h10m
63
+ #{today}: 55m
64
+ OUT
65
+ expect { subject }.to output(expected_output).to_stdout
66
+ end
67
+ end
68
+ end
69
+ end
@@ -2,8 +2,16 @@ require "detom/commands/record"
2
2
  require "detom/yaml_file_store"
3
3
 
4
4
  describe Commands::Record do
5
- subject { described_class.new(store) }
5
+ subject { described_class.new(store, local_config) }
6
6
  let(:store) { YamlFileStore.new(test_filepath) }
7
+ let(:local_config) { Detom::LocalConfig.new }
8
+
9
+ before(:all) do
10
+ @the_stdout = $stdout
11
+ $stdout = File.open(File::NULL, 'w')
12
+ end
13
+
14
+ after(:all) { $stdout = @the_stdout }
7
15
 
8
16
  describe "#call" do
9
17
  let(:test_filepath) { File.join(File.dirname(__FILE__), "..", "..", "..", "tmp", "record_test") }
@@ -13,22 +21,60 @@ describe Commands::Record do
13
21
  after { FileUtils.rm_rf test_filepath if Dir.exists? test_filepath }
14
22
 
15
23
  context "when recording time today" do
24
+ context "for project with a configured client" do
25
+ before { local_config.load_from! client: "faa" }
26
+
27
+ it do
28
+ subject.call("12m")
29
+ expect(store["faa"]).to eq({ today => [12] })
30
+ end
31
+
32
+ context "and explicitly providing a client" do
33
+ it do
34
+ subject.call("50m", "bloo")
35
+ expect(store["bloo"]).to eq({ today => [50] })
36
+ expect(store["faa"]).to be_nil
37
+ end
38
+ end
39
+ end
40
+
16
41
  context "once for one client" do
17
- it "stores the time spent on the client" do
18
- subject.call("foo_client", "6m")
19
- expect(store["foo_client"]).to eq({ today => [6] })
20
- expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
42
+ context "in minutes" do
43
+ it "stores the time spent on the client" do
44
+ subject.call("6m", "foo_client")
45
+ expect(store["foo_client"]).to eq({ today => [6] })
46
+ expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
21
47
  ---
22
48
  '#{today}':
23
49
  - 6
24
50
  JSON
51
+ end
52
+ end
53
+
54
+ context "in hours" do
55
+ it "stores the time spent on the client in minutes" do
56
+ subject.call("6h", "foo_client")
57
+ expect(store["foo_client"]).to eq({ today => [360] })
58
+ expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
59
+ ---
60
+ '#{today}':
61
+ - 360
62
+ JSON
63
+ end
64
+ end
65
+
66
+ context "in an unrecognised format" do
67
+ it "raises an error" do
68
+ expect { subject.call("700s", "foo_client") }.to raise_error Commands::Record::TIME_TO_LOG_FORMAT_MESSAGE
69
+
70
+ end
25
71
  end
26
72
  end
27
73
 
28
74
  context "twice for one client" do
29
75
  it "stores the time spent on the client" do
30
- subject.call("foo_client", "6m")
31
- subject.call("foo_client", "39m")
76
+ subject.call("6m", "foo_client")
77
+ subject.call("39m", "foo_client")
32
78
  expect(store["foo_client"]).to eq({ today => [6, 39] })
33
79
  expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
34
80
  ---
@@ -41,9 +87,9 @@ JSON
41
87
 
42
88
  context "three times for one client" do
43
89
  it "stores the time spent on the client" do
44
- subject.call("foo_client", "6m")
45
- subject.call("foo_client", "39m")
46
- expect { subject.call("foo_client", "92m") }.to output("Logged 92m for foo_client\n").to_stdout
90
+ subject.call("6m", "foo_client")
91
+ subject.call("39m", "foo_client")
92
+ expect { subject.call("92m", "foo_client") }.to output("Logged 92m for foo_client\n").to_stdout
47
93
  expect(store["foo_client"]).to eq({ today => [6, 39, 92] })
48
94
  expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
49
95
  ---
@@ -57,9 +103,9 @@ JSON
57
103
 
58
104
  context "once each for two clients" do
59
105
  it "stores the time spent on the clients" do
60
- record_command = described_class.new(store)
61
- record_command.call("foo_client", "6m")
62
- record_command.call("raa_client", "39m")
106
+ record_command = described_class.new(store, local_config)
107
+ record_command.call("6m", "foo_client")
108
+ record_command.call("39m", "raa_client")
63
109
  expect(store["foo_client"]).to eq({ today => [6] })
64
110
  expect(store["raa_client"]).to eq({ today => [39] })
65
111
  expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
@@ -77,9 +123,9 @@ JSON
77
123
 
78
124
  context "once each for three clients" do
79
125
  it "stores the time spent on the clients" do
80
- subject.call("foo_client", "6m")
81
- subject.call("raa_client", "39m")
82
- subject.call("gii_client", "72m")
126
+ subject.call("6m", "foo_client")
127
+ subject.call("39m", "raa_client")
128
+ subject.call("72m", "gii_client")
83
129
  expect(store["foo_client"]).to eq({ today => [6] })
84
130
  expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
85
131
  ---
@@ -108,7 +154,7 @@ JSON
108
154
 
109
155
  context "once for one client" do
110
156
  it "stores the time spent on the client" do
111
- subject.call("foo_client", "6m", five_days_ago.strftime("%d-%m"))
157
+ subject.call("6m", "foo_client", five_days_ago.strftime("%d-%m"))
112
158
  expect(store["foo_client"]).to eq({ expected_formatted_date => [6] })
113
159
  expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
114
160
  ---
@@ -127,8 +173,8 @@ JSON
127
173
 
128
174
  context "once for one client" do
129
175
  it "stores the time spent on the client" do
130
- subject.call("foo_client", "6m", five_days_ago.strftime("%d-%m"))
131
- subject.call("foo_client", "45m", ten_days_ago.strftime("%d-%m"))
176
+ subject.call("6m", "foo_client", five_days_ago.strftime("%d-%m"))
177
+ subject.call("45m", "foo_client", ten_days_ago.strftime("%d-%m"))
132
178
  expect(store["foo_client"]).to eq({ expected_formatted_date_1 => [6], expected_formatted_date_2 => [45] })
133
179
  expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
134
180
  ---
@@ -150,7 +196,7 @@ JSON
150
196
  context "once for one client" do
151
197
  it "stores the time spent on the client" do
152
198
  File.open(File.join(test_filepath, "foo_client"), "w") {|f| f.write YAML.dump(expected_formatted_date_1 => [6]) }
153
- subject.call("foo_client", "45m", ten_days_ago.strftime("%d-%m"))
199
+ subject.call("45m", "foo_client", ten_days_ago.strftime("%d-%m"))
154
200
  expect(store["foo_client"]).to eq({ expected_formatted_date_1 => [6], expected_formatted_date_2 => [45] })
155
201
  expect(File.read(File.join(test_filepath, "foo_client"))).to eq <<-JSON
156
202
  ---
@@ -0,0 +1,11 @@
1
+ require "detom/local_config"
2
+
3
+ describe Detom::LocalConfig do
4
+ describe "a dynamic setter" do
5
+ it do
6
+ config = described_class.new
7
+ config.client = "a value"
8
+ expect(config.client).to eq "a value"
9
+ end
10
+ end
11
+ end
@@ -44,6 +44,12 @@ RSpec.configure do |config|
44
44
  # triggering implicit auto-inclusion in groups with matching metadata.
45
45
  config.shared_context_metadata_behavior = :apply_to_host_groups
46
46
 
47
+ config.order = :random
48
+
49
+ # Runs and outputs all assertions in a test regardless of failures.
50
+ config.define_derived_metadata do |meta|
51
+ meta[:aggregate_failures] = true
52
+ end
47
53
  # The settings below are suggested to provide a good initial experience
48
54
  # with RSpec, but feel free to customize to your heart's content.
49
55
  =begin
@@ -0,0 +1,32 @@
1
+ require "open3"
2
+
3
+ describe "detom record" do
4
+ subject { Open3.capture3(command) }
5
+
6
+ let(:stdout) { subject[0] }
7
+ let(:stderr) { subject[1] }
8
+
9
+ before do
10
+ @original_dir = Dir.pwd
11
+ Dir.chdir File.join(File.dirname(__FILE__), "..", "..", "tmp")
12
+ %x(rm -rf .detom)
13
+ end
14
+
15
+ after do
16
+ Dir.chdir @original_dir
17
+ end
18
+
19
+ let(:command) { "bundle exec ../bin/detom record 90m" }
20
+ let(:expected_stdout) do
21
+ <<OUT
22
+ Logged 90m for foofoo
23
+ OUT
24
+ end
25
+
26
+ it do
27
+ %x(bundle exec ../bin/detom set foofoo)
28
+
29
+ expect(stdout).to eq expected_stdout
30
+ expect(stderr).to eq ""
31
+ end
32
+ end
@@ -0,0 +1,91 @@
1
+ require "open3"
2
+
3
+ describe "detom set" do
4
+ subject { Open3.capture3(command) }
5
+
6
+ let(:stdout) { subject[0] }
7
+ let(:stderr) { subject[1] }
8
+
9
+ before do
10
+ @original_dir = Dir.pwd
11
+ Dir.chdir File.join(File.dirname(__FILE__), "..", "..", "tmp")
12
+ %x(rm -rf .detom)
13
+ end
14
+
15
+ after do
16
+ Dir.chdir @original_dir
17
+ end
18
+
19
+ context "when no args are provided" do
20
+ let(:command) { "bundle exec ../bin/detom set" }
21
+ let(:expected_stderr) do
22
+ <<ERR
23
+ error: Found .detom but it is a directory. Are you running `detom set` in your home directory?
24
+ `detom set` should be run in the root of a project folder
25
+ ERR
26
+ end
27
+
28
+ before { %x(mkdir .detom) }
29
+
30
+ it do
31
+ expect(stderr).to eq expected_stderr
32
+ expect(Dir.exist? ".detom").to be_truthy
33
+ end
34
+ end
35
+
36
+ context "when a client is provided" do
37
+ let(:command) { "bundle exec ../bin/detom set foo" }
38
+ let(:expected_stdout) do
39
+ <<OUT
40
+ New config: {:client=>"foo"}
41
+ OUT
42
+ end
43
+
44
+ it do
45
+ expect(stdout).to eq expected_stdout
46
+ expect(File.exist? ".detom").to be_truthy
47
+ end
48
+
49
+ context "and config already exists" do
50
+ before { %x(bundle exec ../bin/detom set faa) }
51
+ let(:expected_stdout) do
52
+ <<OUT
53
+ New config: {:client=>"foo"}
54
+ OUT
55
+ end
56
+
57
+ it do
58
+ expect(stdout).to eq expected_stdout
59
+ expect(File.exist? ".detom").to be_truthy
60
+ end
61
+ end
62
+ end
63
+
64
+ context "when a client and project are provided" do
65
+ let(:command) { "bundle exec ../bin/detom set foo project_tree" }
66
+ let(:expected_stdout) do
67
+ <<OUT
68
+ New config: {:client=>"foo", :project=>"project_tree"}
69
+ OUT
70
+ end
71
+
72
+ it do
73
+ expect(stdout).to eq expected_stdout
74
+ expect(File.exist? ".detom").to be_truthy
75
+ end
76
+
77
+ context "and config already exists" do
78
+ before { %x(bundle exec ../bin/detom set faa) }
79
+ let(:expected_stdout) do
80
+ <<OUT
81
+ New config: {:client=>"foo", :project=>"project_tree"}
82
+ OUT
83
+ end
84
+
85
+ it do
86
+ expect(stdout).to eq expected_stdout
87
+ expect(File.exist? ".detom").to be_truthy
88
+ end
89
+ end
90
+ end
91
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: detom
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - NJ Pearman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-05 00:00:00.000000000 Z
11
+ date: 2020-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -75,6 +75,7 @@ extra_rdoc_files:
75
75
  - README.rdoc
76
76
  - detom.rdoc
77
77
  files:
78
+ - ".gitignore"
78
79
  - ".rspec"
79
80
  - Gemfile
80
81
  - Gemfile.lock
@@ -85,13 +86,20 @@ files:
85
86
  - detom.gemspec
86
87
  - detom.rdoc
87
88
  - lib/detom.rb
89
+ - lib/detom/commands/client.rb
88
90
  - lib/detom/commands/clients.rb
89
91
  - lib/detom/commands/record.rb
92
+ - lib/detom/commands/set.rb
93
+ - lib/detom/local_config.rb
90
94
  - lib/detom/version.rb
91
95
  - lib/detom/yaml_file_store.rb
96
+ - spec/detom/commands/client_spec.rb
92
97
  - spec/detom/commands/clients_spec.rb
93
98
  - spec/detom/commands/record_spec.rb
99
+ - spec/detom/local_config_spec.rb
94
100
  - spec/spec_helper.rb
101
+ - spec/system/record_spec.rb
102
+ - spec/system/set_spec.rb
95
103
  - tmp/record_test.json
96
104
  homepage: https://github.com/njpearman/detom
97
105
  licenses: []