wlog 1.1.7 → 1.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +100 -39
  3. data/lib/wlog/commands/bootstrap_templates.rb +5 -0
  4. data/lib/wlog/commands/delete_attachment.rb +17 -0
  5. data/lib/wlog/commands/fetch_git_commits.rb +45 -0
  6. data/lib/wlog/commands/fetch_git_commits_standard.rb +29 -0
  7. data/lib/wlog/commands/innit_db.rb +3 -2
  8. data/lib/wlog/commands/write_template.rb +22 -0
  9. data/lib/wlog/domain/attachment.rb +26 -54
  10. data/lib/wlog/domain/git_commit.rb +11 -0
  11. data/lib/wlog/domain/issue.rb +14 -1
  12. data/lib/wlog/domain/key_value.rb +1 -1
  13. data/lib/wlog/domain/template_helper.rb +21 -0
  14. data/lib/wlog/migrations/fix_attachments_polymorphic_table.rb +15 -0
  15. data/lib/wlog/migrations/make_standard_tables.rb +0 -13
  16. data/lib/wlog/tech/git_commit_parser.rb +48 -0
  17. data/lib/wlog/tech/git_commit_printer.rb +19 -0
  18. data/lib/wlog/tech/uncolored_string.rb +1 -1
  19. data/lib/wlog/ui/bootstrap.rb +1 -0
  20. data/lib/wlog/ui/cli_interface.rb +2 -58
  21. data/lib/wlog/ui/edit_handler.rb +7 -0
  22. data/lib/wlog/ui/git_ui.rb +47 -0
  23. data/lib/wlog/ui/invoice_ui.rb +53 -36
  24. data/lib/wlog/ui/issue_ui.rb +57 -5
  25. data/lib/wlog/ui/template_ui.rb +2 -2
  26. data/lib/wlog/version.rb +1 -1
  27. data/spec/domain/attachment_spec.rb +49 -55
  28. data/spec/domain/commands/concat_desc_spec.rb +1 -0
  29. data/spec/domain/commands/new_entry_spec.rb +1 -0
  30. data/spec/domain/commands/replace_pattern_spec.rb +1 -0
  31. data/spec/domain/git_commits_spec.rb +85 -0
  32. data/spec/domain/invoice_spec.rb +35 -0
  33. data/spec/domain/issue_spec.rb +1 -0
  34. data/spec/domain/key_value_spec.rb +1 -0
  35. data/spec/domain/log_entry_spec.rb +1 -0
  36. data/spec/domain/sys_config_spec.rb +1 -0
  37. data/spec/spec_helper.rb +31 -0
  38. data/wlog.gemspec +3 -1
  39. metadata +40 -18
  40. data/lib/wlog/domain/session.rb +0 -17
  41. data/lib/wlog/domain/sql_modules/polymorphic_attachments_sql.rb +0 -24
  42. data/lib/wlog/domain/template_engine.rb +0 -55
  43. data/lib/wlog/sql/mono/1.sql +0 -50
  44. data/lib/wlog/sql/seq/.gitkeep +0 -0
  45. data/lib/wlog/sql/seq/2.sql +0 -4
  46. data/lib/wlog/sql/seq/3.sql +0 -3
  47. data/lib/wlog/ui/commands/ui_command.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae992bd7858ce2e08c6ad8e42d87f9473ff97eac
4
- data.tar.gz: 891ee5f0589a579dcdb31da227acb6ed8a89871c
3
+ metadata.gz: 71f501411d645d7b66bba721986ff8e913fa649c
4
+ data.tar.gz: 50a272c8617ad7c0258d765f4dd52cb586224e3e
5
5
  SHA512:
6
- metadata.gz: bb4a653989d05da8a524e19d72ad8948eb7e3c9c980934459d5ffd52fb261a24a4a2bfeacbc9300d9141a8602b3d021707652a1f15691a247e47b49712006e10
7
- data.tar.gz: 56611ff5b80c771185646b24ccb9594945c3bf17c6283a33b9dfb5d07db5eed75b5e828218d3bad162067850574ff93e6c7a8a30ecc7614b76c9e91366a73a69
6
+ metadata.gz: ccca541ffc78b943ca4736db5c7bd1cc4c4024dee7a830cd431405e9536b5e1f0831f6ca8a9fb774ef67caa57f1c6bb89eff116fed6feb578f7e9871d28b38b7
7
+ data.tar.gz: 9e0cc96690d82932c28ebb6a85f80c5413f23ef71fcbee516b3ae34bfc785c94b3bf51a5dc91fb2da94d91c39302f407b1bc7b4f2e420494fbe2cd253c8b6567
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # wlog [![Code Climate](https://codeclimate.com/github/psyomn/wlog.png)](https://codeclimate.com/github/psyomn/wlog) [![Build Status](https://travis-ci.org/psyomn/wlog.png?branch=v1.1.0)](https://travis-ci.org/psyomn/wlog)
1
+ # wlog [![Code Climate](https://codeclimate.com/github/psyomn/wlog.png)](https://codeclimate.com/github/psyomn/wlog) [![Build Status](https://travis-ci.org/psyomn/wlog.png?branch=v1.1.0)](https://travis-ci.org/psyomn/wlog) [![Inline docs](http://inch-ci.org/github/psyomn/wlog.svg?branch=master)](http://inch-ci.org/github/psyomn/wlog) [![Gem Version](https://badge.fury.io/rb/wlog.svg)](http://badge.fury.io/rb/wlog) [![Coverage Status](https://img.shields.io/coveralls/psyomn/wlog.svg)](https://coveralls.io/r/psyomn/wlog?branch=v1.2.0)
2
2
 
3
3
  wlog (worklog) is a small utility to track tasks in command line. I use this
4
4
  for things I work on and need to submit a list of stuff done on a particular
@@ -116,19 +116,48 @@ the command `desc`.
116
116
  Description
117
117
  But this is an ever longer desc
118
118
 
119
+ File
120
+ N/A
121
+
122
+ ### Attachments
123
+
124
+ You can also attach files to issues while being within issue scope:
125
+
126
+ [issue #1] attach
127
+ Attach to which issue? : 1
128
+ Absolute file location : /tmp/derp.txt
129
+ Alias name for file (optional) :
130
+ Attached file.
131
+
132
+ There's two commands you can use to list attachments within issue scope:
133
+ `attachls`, `desc`. `desc` will print all the issue information, and show
134
+ the attachments in the end.
135
+
136
+ You can output attachments to a location:
137
+
138
+ [issue #1] attachls
139
+ [1] - become-a-killer-cook.pdf
140
+ [2] - very-boring-doc.pdf
141
+ [issue #1] attachout
142
+ Which attachment to output? : 1
143
+ Output where (abs dir) ? : /tmp/
144
+
145
+ *Warn*: This is a somewhat nice feature, though it might be axed in the future
146
+ if storing files is too problematic.
147
+
119
148
  ## Logging Time
120
149
 
121
150
  It's possible to log time within issue scope with the following commands:
122
151
 
123
- lt 10m
152
+ [issue #1] lt 10m
124
153
 
125
154
  To log 10 minutes
126
155
 
127
- lt 1h20m
156
+ [issue #1] lt 1h20m
128
157
 
129
158
  To log 1 hour 20 minutes
130
159
 
131
- lt 1d 1s
160
+ [issue #1] lt 1d 1s
132
161
 
133
162
  To log one day, one second. (A day is 8 hours). The total time is stored on the
134
163
  issue.
@@ -157,34 +186,6 @@ To exit the scope of an issue, you can use the `forget` command:
157
186
  [issue #1] forget
158
187
  [wlog]
159
188
 
160
- *NOTE*: Attachments don't currently work in v1.1.5 - they might be back in the
161
- future.
162
-
163
- You can also attach files to issues (you have to be outside the scope of an
164
- issue for this - this feature is experimental at the momment so don't rely too
165
- much on it):
166
-
167
- [wlog] attach
168
- Attach to which issue? : 1
169
- Absolute file location : /tmp/derp.txt
170
- Alias name for file (optional) :
171
- Attached file.
172
-
173
- And then you can output them to a location:
174
-
175
- [wlog] show
176
- finished [1]
177
- [2] This is yet another issue
178
- started work [1]
179
- [1] This is my issue
180
- [wlog] showattach
181
- Which issue : 1
182
- [1] - derp.txt (alias: )
183
- [2] - derp.txt (alias: )
184
- [wlog] outattach
185
- Which attachment to output? : 1
186
- Output where (abs dir) : /tmp/
187
-
188
189
  # Generating Invoices
189
190
 
190
191
  You can generate invoices. You need to create an invoice first. To do that,
@@ -212,23 +213,41 @@ month of September:
212
213
  break you of the input for the invoice.
213
214
 
214
215
 
215
-
216
-
217
-
218
-
219
- [invoice]
216
+
217
+ [invoices] new
218
+ From (dd-mm-yyyy) 01-09-2014
219
+ To (dd-mm-yyyy) 30-09-2014
220
+ > I start writing this it is a
221
+ > very nice paragraph. I can break
222
+ > lines and do whatever. And continue
223
+ > writing and do whatever.
224
+ >
225
+ > Two lines can separate a paragraph
226
+ > And if you notice you can have many
227
+ > paragraphs in the invoice.
228
+ >
229
+ > And another. But if we hit return 3
230
+ > times, then it will stop recording
231
+ > our lines.
232
+ >
233
+ >
234
+ [invoices]
220
235
 
221
236
  So now you should have your first invoice:
222
237
 
223
238
  [invoice] show
224
- [1] 01-09-2014 -> 30-09-2014 I
239
+ [1] 01-10-2014 -> 30-10-2014 This is some text I'm currently writing and I'm no...
240
+
241
+ [invoice] ls
242
+ [1] 01-10-2014 -> 30-10-2014 This is some text I'm currently writing and I'm no...
225
243
 
226
244
  And now you can generate your invoice with the following command:
227
245
 
228
246
  [invoice] generate 1
229
247
 
230
248
  This will write the output in `~/Documents/wlog/`. Will create dirs if not
231
- exist.
249
+ exist. The outputs are generated from templates which exist in
250
+ _$HOME/.config/wlog/templates_. You can write your own.
232
251
 
233
252
  ## Templates
234
253
 
@@ -248,6 +267,48 @@ commands:
248
267
  Also, worth to note that you should verify any template you get off the
249
268
  internet to use as your own.
250
269
 
270
+ Templates are set per database. So if you want to use different templates (1 at
271
+ a time) per database, it's possible. You can take a look at an example template
272
+ that exploits all the currently available template variables [here]().
273
+
274
+ ## Git Integration
275
+
276
+ There's some very loose (and probably crappy) integration with git repos. What
277
+ you do is point `wlog` to your project directory + .git/. So for example, if we
278
+ were tracking this repo with `wlog`, we would do the following:
279
+
280
+ [wlog] git
281
+ [git] ls
282
+ repo:
283
+ auth:
284
+ [git] set
285
+ Path to git repo (eg: project/.git/): /home/psyomn/programming/ruby/wlog/.git/
286
+ git author: psyomn
287
+ [git] ls
288
+ repo: /home/psyomn/programming/ruby/wlog/.git/
289
+ auth: psyomn
290
+
291
+ So now, when you're generating invoices, you can add your commits as well. If
292
+ you want to simply list a bunch of commits for a particular invoice, you can
293
+ invoke the `commits` command. The commits between the two dates of that invoice
294
+ will be printed on screen.
295
+
296
+ [invoices] ls
297
+ [1] 01-10-2014 -> 30-10-2014 This is some text I'm currently writing and I'm no...
298
+ [2] 01-09-2014 -> 30-09-2014 I start writing this it is a...
299
+ [invoices] commits 2
300
+
301
+ git commits for psyomn
302
+
303
+ 5a46cf61dd6471f22731b7cbf1d21d1d0f79f7a2 wlog.gemspec: set version of AR to 4.1.6 ...
304
+ 8ca561e3412fde1828f983b79ee47a158d16bbf6 README.md: update usage instructions ...
305
+ fcb5adbba04c22ef931147b8acbf641d9d26bb33 template/ui: niceify template selection ...
306
+ e10bdee3cd8ae2f12ae55aef5cef249433459397 invoices/issues/entries: fix timezone issue ...
307
+ 8ef9a823da2d80bba510838dd591703baad2c9ac invoices: generating works. ...
308
+ cf1627259cc7d278084f90559efa75d1fe4f60ba staticconfig: add template output dir ...
309
+ 22d760f881e613a30d3b722dd9b26f4f46c1cf4c domain/log_entry: add belongs_to issue ...
310
+ 79d1e3393587b02c328a454d5cfe301d3f80aee8 invoices: select date range for log entries ...
311
+
251
312
  ## Contributing
252
313
 
253
314
  1. Fork it
@@ -26,6 +26,11 @@ private
26
26
  def write_default_template!
27
27
  fh = File.open(TemplateSampleFile, 'w')
28
28
  data = "A list of issues:
29
+ <p> Invoice: <%= @invoice.description %> </p>
30
+ <p> From: <%= @invoice.from.strftime(\"%A %d %B \") %> </p>
31
+ <p> To: <%= @invoice.to.strftime(\"%A %d %B\") %> </p>
32
+ <p> Work Items to report: <%= @log_entries.count %> </p>
33
+
29
34
  <% @issues.each do |issue| %>
30
35
  <%= \"\#{issue.id} \#{issue.description}\" %>
31
36
  <% end %>"
@@ -0,0 +1,17 @@
1
+ require 'wlog/commands/commandable'
2
+ module Wlog
3
+ # Delete an attachment, given its id (in the context of an issue)
4
+ # @author Simon Symeonidis
5
+ class DeleteAttachment < Commandable
6
+ def initialize(issue, att_id)
7
+ @issue = issue
8
+ @att_id = att_id
9
+ end
10
+
11
+ def execute
12
+ end
13
+
14
+ private
15
+ end
16
+ end
17
+
@@ -0,0 +1,45 @@
1
+ require 'wlog/commands/commandable'
2
+ require 'wlog/tech/git_commit_parser'
3
+ module Wlog
4
+ # Given two dates, extract the git commits.
5
+ # @author Simon Symeonidis
6
+ class FetchGitCommits < Commandable
7
+
8
+ # Configuration to query the git repo for the required commits. You can
9
+ # specify a date range and an author. You need to provide a path to the
10
+ # git repository.
11
+ # @param from date start
12
+ # @param to date end
13
+ # @param repo location to the git repo
14
+ # @param author only show logs of that author. If none is given, fetch all
15
+ # authors
16
+ # @example
17
+ # from_date = DateTime.now - 15
18
+ # to_date = DateTime.now + 5
19
+ # repo = '/home/jon/wlog/.git/'
20
+ # cmd = FetchGitCommits.new(from_date, to_date, repo, 'jon')
21
+ def initialize(from, to, repo, author=nil)
22
+ @from, @to, @repo, @author = from, to, repo, author
23
+ end
24
+
25
+ # Run the parser on the repo; yield commits
26
+ def execute
27
+ result = `#{run_git_cmd}`
28
+ @commits = GitCommitParser.parse(result)
29
+ nil end
30
+
31
+ attr_accessor :commits
32
+
33
+ private
34
+
35
+ # git --git-dir <thedir> log --since=... --until=... --author=...
36
+ def run_git_cmd
37
+ base = "git --git-dir #{@repo} log "
38
+ base.concat("--since=\"#{@from}\" ")
39
+ base.concat("--until=\"#{@to}\" ")
40
+ base.concat("--author=\"#{@author}\"") if @author
41
+ base end
42
+
43
+ end
44
+ end
45
+
@@ -0,0 +1,29 @@
1
+ require 'wlog/commands/commandable'
2
+ require 'wlog/commands/fetch_git_commits'
3
+ require 'wlog/tech/git_commit_parser'
4
+ module Wlog
5
+ # We don't set the repo and author - get it directly from keyvalue
6
+ # Use the other git fetcher if you want something more configurable
7
+ # @author Simon Symeonidis
8
+ class FetchGitCommitsStandard < Commandable
9
+
10
+ # @param from date start
11
+ # @param to date end
12
+ # authors
13
+ def initialize(from, to)
14
+ @from, @to = from, to
15
+ @author = KeyValue.get('author')
16
+ @repo = KeyValue.get('git')
17
+ end
18
+
19
+ # Run the parser on the repo; yield commits
20
+ def execute
21
+ cmd = FetchGitCommits.new(@from, @to, @repo, @author)
22
+ cmd.execute
23
+ @commits = cmd.commits
24
+ nil end
25
+
26
+ attr_accessor :commits
27
+ end
28
+ end
29
+
@@ -2,6 +2,7 @@ require 'wlog/commands/commandable'
2
2
  require 'wlog/domain/static_configurations'
3
3
 
4
4
  require 'wlog/migrations/make_standard_tables'
5
+ require 'wlog/migrations/fix_attachments_polymorphic_table'
5
6
 
6
7
  require 'active_record'
7
8
  require 'sqlite3'
@@ -35,7 +36,7 @@ class InnitDb < Commandable
35
36
  # to test. Once tests are ok again, then I'm going to refactor this somewhere
36
37
  # else so it's more sane.
37
38
  def execute_migrations!
38
- migrations = [MakeStandardTables]
39
+ migrations = [MakeStandardTables, FixAttachmentsPolymorphicTable]
39
40
  existing = SchemaMigration.all.collect{ |el| el.version }
40
41
 
41
42
  migrations.reject!{ |e| existing.include? e.to_s}
@@ -51,12 +52,12 @@ private
51
52
 
52
53
  # Checks to see if versioning table is there. Create if not.
53
54
  def make_schema_migrations!
55
+ ActiveRecord::Migration.verbose = false
54
56
  ActiveRecord::Base.configurations = dbconfig
55
57
  ActiveRecord::Base.establish_connection(:development)
56
58
  ActiveRecord::Base.default_timezone = :local
57
59
 
58
60
  unless SchemaMigration.table_exists?
59
- ActiveRecord::Migration.verbose = false
60
61
  ActiveRecord::Migration.run(MakeSchemaMigration)
61
62
  end
62
63
  end
@@ -0,0 +1,22 @@
1
+ require 'wlog/domain/static_configurations'
2
+ require 'wlog/commands/commandable'
3
+ module Wlog
4
+ # After the template is processed, write out the results to standard file.
5
+ # @author Simon Symeonidis
6
+ class WriteTemplate < Commandable
7
+ include StaticConfigurations
8
+
9
+ def initialize(template_output, invoice)
10
+ @template_output = template_output
11
+ @invoice = invoice
12
+ end
13
+
14
+ def execute
15
+ FileUtils.mkdir_p TemplateOutputDir
16
+ template_ext = File.extname TemplateHelper.template_file || '.txt'
17
+ filename = TemplateOutputDir + "#{@invoice.id}-invoice#{template_ext}"
18
+ File.write(filename, @template_output)
19
+ nil end
20
+
21
+ end
22
+ end
@@ -1,62 +1,34 @@
1
1
  require 'active_record'
2
+ require 'zlib'
3
+ require 'wlog/domain/sys_config'
4
+
2
5
  module Wlog
3
6
  # Following the Active Record pattern
4
7
  # OO way of handling blobs of data, to be stored in memory or in db.
5
8
  class Attachment < ActiveRecord::Base
6
-
7
- # Can only initialize with a caller name and id, since relations to
8
- # attachments are polymorphic.
9
- # def initialize(dbhandle, caller_name, caller_id)
10
- # @caller_name, @caller_id, @db = caller_name, caller_id, dbhandle
11
- # end
12
-
13
- # Find an attachment given an id
14
- # @param id is the attachment id to find
15
- # def self.find_all_by_discriminator(db, name, id)
16
- # arr = Array.new
17
- # rows = db.execute(
18
- # PolymorphicAttachmentsSql::SelectSql, name, id)
19
-
20
- # rows.each do |row|
21
- # arr.push self.find(db, name, row[2])
22
- # end
23
- # arr end
24
-
25
- # # Delete an attachment
26
- # # @param id the attachment with the id to delete
27
- # def delete_by_discriminator(name, id)
28
- # @db.execute(DeleteSql, id)
29
- # end
30
-
31
- # # Find an attachment by an identifier and polymorphic name
32
- # # @param id is the identifier of the attachment to find
33
- # # @param name is the name of the polymorphic thing
34
- # def self.find(db, name, id)
35
- # row = db.execute(AttachmentSql::SelectSql, id).first
36
- # att = nil
37
- # if row && !row.empty?
38
- # att = Attachment.new(db, name, id)
39
- # att.quick_assign!(row)
40
- # end
41
- # att end
42
-
43
- # # Insert an attachment. This also creates the relation in the polymorphic
44
- # # table.
45
- # def insert
46
- # unless @id
47
- # @db.execute(
48
- # AttachmentSql::InsertSql, @filename, @given_name, @data)
49
- # ret = @db.last_row_from(AttachmentSql::TableName)
50
- # @id = ret.first[0].to_i
51
- # @db.execute(
52
- # PolymorphicAttachmentsSql::InsertSql, @caller_name, @caller_id, @id)
53
- # end
54
- # end
55
-
56
- # # Assign a row of data to self
57
- # def quick_assign!(row)
58
- # @id, @filename, @given_name, @data = row[0], row[1], row[2], row[3]
59
- # nil end
9
+ before_save :compress_string
10
+ after_initialize :uncompress_string
11
+ belongs_to :attachable, polymorphic: true
12
+
13
+ def to_s
14
+ @strmaker = SysConfig.string_decorator
15
+ str = ''
16
+ str.concat(" [").concat(@strmaker.green(self.id)).concat("] ")
17
+ str.concat(@strmaker.red(self.filename)).concat($/)
18
+ str end
19
+
20
+ private
21
+
22
+ def compress_string
23
+ self.data = Zlib::Deflate.deflate self.data
24
+ end
25
+
26
+ def uncompress_string
27
+ if self.data
28
+ # did we just init something with previous data? yes; we can uncompress
29
+ self.data = Zlib::Inflate.inflate self.data
30
+ end
31
+ end
60
32
 
61
33
  end
62
34
  end # module Wlog