personal-backlog 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f937e28de5a51a5b188138452070cca2c8cf853
4
+ data.tar.gz: ac3e80e89aec853be2ce32609a9d64421372bac4
5
+ SHA512:
6
+ metadata.gz: a2267d885e2b55ddc85548efc0a80765d2cf276b6545571fded88c2433561e7ce59fc2ee19b55bd7053dd6283d76ca0b91c9480e67d1c284e5575adbfedfb474
7
+ data.tar.gz: dbad5aa9642bd71cccbab13daf78c9223975bdc328275c474c34c9eb2a2df7dc97850ad9f0fd2e78f510473200219f91f83c7b749ca8172c1337cce816c5a3fd
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ Backlog Tool
2
+ ============
3
+
4
+ Commands
5
+ --------
6
+
7
+ ```
8
+ export BACKLOG_PATH=PATH_TO_BACKLOG || $HOME/.backlog
9
+
10
+ # call next tuesday
11
+ backlog next tuesday
12
+
13
+ # add something to today's todo list
14
+ backlog -t "Start element"
15
+
16
+ # check for a match of this task in the todo
17
+ backlog -c "Today"
18
+
19
+ # work on todays backlog - open with edtior
20
+ backlog
21
+
22
+ # archive everything previous to today
23
+ backlog a
24
+ backlog archive
25
+
26
+ # go to the current directory
27
+ backlog cd
28
+
29
+ # backlog set up the directory
30
+ backlog init
31
+
32
+
33
+ ```
34
+
data/bin/backlog ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'backlog'
4
+
5
+ # initialize CLI
6
+ Backlog::CLI.new(ARGV.dup).execute!
7
+
8
+
9
+
10
+
@@ -0,0 +1,39 @@
1
+ require 'chronic'
2
+
3
+ module Backlog
4
+
5
+ class Archive
6
+
7
+ def initialize(args, date)
8
+ @args = args
9
+ @date = date
10
+ end
11
+
12
+ def execute!
13
+ # our cli parser will always try to guess a legitimate date
14
+ if @date == nil or @date.date == Date.today
15
+ archive_all
16
+ else
17
+ archive_path @date.path
18
+ end
19
+ end
20
+
21
+ private
22
+ def archive_all
23
+ Dir.glob("#{Config.current_dir}/**md").each do |path|
24
+ date = DateFile.date_from_path(path)
25
+ if date < Date.today
26
+ archive_path(path)
27
+ end
28
+ end
29
+ end
30
+
31
+ def archive_path(path)
32
+ filename = File.basename(path)
33
+ FileUtils.mv(path, File.join(Config::archive_dir, filename))
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+
@@ -0,0 +1,12 @@
1
+ module Backlog
2
+
3
+ class Args < Array
4
+
5
+ def initialize(*args)
6
+
7
+ super
8
+
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,91 @@
1
+ module Backlog
2
+ class CLI
3
+
4
+ @@commands = {
5
+ init: Init,
6
+ help: Help,
7
+ open: Open,
8
+ archive: Archive,
9
+ save: Save,
10
+ push: Push
11
+ }
12
+
13
+ @@aliases = {
14
+
15
+ :init => :in,
16
+ :open => [:o, :edit],
17
+ :help => :h,
18
+ :archive => :a,
19
+ :save => :s,
20
+ :push => :p,
21
+ }
22
+
23
+ def self.commands
24
+ return @@commands
25
+ end
26
+
27
+ def initialize(argv, stdin=STDIN, stdout=STDOUT, stderr=STDERR, kernel=Kernel)
28
+
29
+ @argv, @stdin, @stdout, @stderr, @kernel = argv, stdin, stdout, stderr, kernel
30
+ end
31
+
32
+ def execute!
33
+
34
+ # get the method to call for this command
35
+ command_class, argv = subcommand
36
+
37
+ # run the command
38
+ command_class.new(argv, @datefile).execute!
39
+
40
+ end
41
+
42
+ # return a function pointer for the subcommand
43
+ def subcommand()
44
+
45
+ if not @argv.length > 0
46
+ @datefile = DateFile.new
47
+ return Open, nil
48
+ end
49
+ # cache the first string a symbol
50
+ keyword = @argv[0].to_sym
51
+
52
+ # loop through all commands and see if we have a match
53
+ @@commands.each do |key, command_class|
54
+
55
+ # grab a list of the aliases
56
+ aliases = nil
57
+ # check to see if aliases key exists
58
+ if @@aliases.has_key?(key)
59
+
60
+ # grab the key and then fill the aliases hash properly
61
+ value = @@aliases[key]
62
+ if value.kind_of?(Symbol)
63
+ aliases = [value]
64
+ else
65
+ aliases = value
66
+ end
67
+ end
68
+
69
+ # if alias / keywords match up then go ahead and return the correct class
70
+ if keyword == key or aliases.include? keyword
71
+ # return the correct command method
72
+ @argv = @argv[1,@argv.length]
73
+ @datefile = DateFile.new_from_argv(@argv)
74
+ return command_class, @argv
75
+ end
76
+ end
77
+
78
+ # no command matches up - check to see if this is a date
79
+ # we need to pass the date on to the next step ...
80
+ date = DateFile.new_from_argv(@argv)
81
+
82
+ if date != nil
83
+ @datefile = date
84
+ return Open, date.argv
85
+ else
86
+ @datefile = DateFile.new_from_argv(@argv)
87
+ return Open, nil
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,36 @@
1
+ module Backlog
2
+
3
+ attr_accessor :base_dir
4
+
5
+ class Config
6
+
7
+ # internal variables
8
+ @@path = nil
9
+
10
+ def self.base_dir
11
+ if @@path != nil
12
+ return @@path
13
+ end
14
+ if ENV.has_key? "BACKLOG_DIR"
15
+
16
+ if ENV['BACKLOG_DIR'].start_with? "/" or ENV['BACKLOG_DIR'].start_with? "~/" or ENV['BACKLOG_DIR'].start_with? "$HOME"
17
+ @@path = ENV['BACKLOG_DIR']
18
+ else
19
+ @@path = File.join(ENV['HOME'], ENV['BACKLOG_DIR'])
20
+ end
21
+ else
22
+ @@path = File.join(ENV['HOME'], ".backlog")
23
+ end
24
+ @@path = File.expand_path @@path
25
+ end
26
+
27
+ def self.current_dir
28
+ return File.join(Config.base_dir, "current")
29
+ end
30
+
31
+ def self.archive_dir
32
+ return File.join(Config.base_dir, "archive")
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,124 @@
1
+ require 'chronic'
2
+
3
+ module Backlog
4
+ class DateFile
5
+
6
+ attr_accessor :valid
7
+ attr_accessor :date
8
+
9
+ def initialize(date_string = nil)
10
+
11
+ @string = date_string
12
+ if date_string == nil
13
+ now
14
+ else
15
+ parse_date(date_string)
16
+ end
17
+
18
+ end
19
+
20
+ def self.date_from_path(path)
21
+
22
+ date_string = File.basename(path).sub!(".md", "").gsub!("-", " ")
23
+ return Date.parse(Chronic.parse(date_string).to_s)
24
+ end
25
+
26
+ def self.new_from_argv(argv)
27
+
28
+ if argv.length == 0
29
+ return DateFile.new
30
+ end
31
+
32
+ # return a datefile with the argv changed up properly
33
+ first_keyword = argv[0]
34
+ date = DateFile.new(first_keyword)
35
+ argv.shift
36
+
37
+ if date.valid == nil && argv.length > 0
38
+ date = DateFile.new("#{first_keyword} #{argv[0]}")
39
+ argv.shift
40
+
41
+ end
42
+
43
+ if date.valid
44
+ return date
45
+ else
46
+ return nil
47
+ end
48
+ end
49
+
50
+ def filename
51
+
52
+ code = @date.strftime("%a-%b-%d")
53
+ return "#{code.downcase}.md"
54
+ end
55
+
56
+ def argv
57
+ return @argv
58
+ end
59
+
60
+ def path
61
+ # determine path
62
+ # if a past date - check to see if the date exists
63
+ # check current/archive
64
+ # generate the correct path as needed
65
+ current_path = File.join Config.current_dir, filename
66
+ archive_path = File.join Config.archive_dir, filename
67
+
68
+ # logic to return the correct path
69
+ if @date == Date.today
70
+ return current_path
71
+
72
+ elsif @date < Date.today
73
+
74
+ if File.exist? current_path
75
+ return current_path
76
+ elsif File.exist? archive_path
77
+ return archive_path
78
+ else
79
+ return current_path
80
+ end
81
+ else
82
+ return current_path
83
+ end
84
+ end
85
+
86
+ def relative_path
87
+
88
+ # remove the base directory from the path
89
+ return path.sub "#{Config.base_dir}/", ""
90
+
91
+ end
92
+
93
+ def exists
94
+
95
+ # return whether or not the date exists
96
+ return File.exist? path
97
+
98
+ end
99
+
100
+ private
101
+ def parse_date(date_string)
102
+
103
+ # our file names are of the type - mon-mar-16
104
+ # these don't play nice with chronic
105
+ date = Chronic.parse(date_string.sub("-", " "))
106
+
107
+ # chronic couldn't create a date object from this
108
+ if date == nil
109
+ @valid = nil
110
+ @date = nil
111
+ else
112
+ @valid = true
113
+ @date = Date.parse(date.to_s)
114
+ end
115
+ end
116
+
117
+ def now
118
+ @date = Date.parse(Time.now.to_s)
119
+ @valid = true
120
+ end
121
+ end
122
+ end
123
+
124
+
@@ -0,0 +1,53 @@
1
+ module Backlog
2
+ class Entry
3
+ def initialize(date)
4
+
5
+ @date = date
6
+ @path = date.path
7
+ if not File.exists?(date.path)
8
+ @exists = nil
9
+ else
10
+ @exists = true
11
+ end
12
+
13
+ end
14
+
15
+ def exists
16
+ return @exists
17
+ end
18
+
19
+ def create
20
+
21
+ File.open(@path, "w").write content
22
+
23
+ end
24
+
25
+ private
26
+ def title
27
+
28
+ return @date.date.strftime("%A %B %d")
29
+ end
30
+
31
+ def content
32
+ return <<-eos
33
+ #{title}
34
+ #{(0..title.length).map{"="}.join}
35
+
36
+ Completed
37
+ ---------
38
+
39
+
40
+
41
+
42
+ Todo
43
+ ----
44
+
45
+
46
+
47
+
48
+ eos
49
+ end
50
+
51
+
52
+ end
53
+ end
@@ -0,0 +1,9 @@
1
+ module Backlog
2
+
3
+ class Entry
4
+
5
+
6
+
7
+ end
8
+
9
+ end
@@ -0,0 +1,36 @@
1
+ module Backlog
2
+ class Help
3
+
4
+ def initialize(cli_args, *args)
5
+
6
+ end
7
+
8
+ def execute!
9
+
10
+ # run the command as needed
11
+ CLI.commands.each do |command, command_class|
12
+ #puts command_class
13
+ puts command
14
+ ##print_help(command_class)
15
+
16
+ end
17
+
18
+ end
19
+
20
+ def self.help()
21
+
22
+ return <<-eos
23
+ Help: \tPrint this menu
24
+ eos
25
+
26
+ end
27
+
28
+ def print_help(command_class)
29
+
30
+ help = command_class.help
31
+ puts help
32
+
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ require 'fileutils'
2
+
3
+ module Backlog
4
+ class Init
5
+
6
+ def initialize(*args)
7
+
8
+ end
9
+
10
+ def execute!
11
+
12
+ create_directories
13
+ initialize_git
14
+ end
15
+
16
+ def self.help()
17
+ return <<-eos
18
+ Init:\tInitialize the backlog directory with the correct directory structures (ie: current/archive)
19
+ eos
20
+ end
21
+
22
+ private
23
+ def create_directories
24
+ [Config.base_dir, Config.archive_dir, Config.current_dir].each do |directory|
25
+ if not File.directory? directory
26
+ FileUtils.mkdir(directory)
27
+ end
28
+ end
29
+ end
30
+
31
+ def initialize_git
32
+ git_directory = File.join Config.base_dir, ".git"
33
+ if not File.directory? git_directory
34
+ system "cd #{Config.base_dir} && git init"
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+
@@ -0,0 +1,48 @@
1
+ module Backlog
2
+ class Open
3
+
4
+ def initialize(args, date)
5
+
6
+ @date = date
7
+
8
+ end
9
+
10
+ def execute!
11
+
12
+ entry = Entry.new(@date)
13
+
14
+ # make sure that the file is created
15
+ if not entry.exists
16
+ entry.create
17
+ end
18
+
19
+ if Date.today == @date.date
20
+ symlink
21
+ end
22
+
23
+ # save date as needed
24
+ Save.save_date_on_open(@date.date)
25
+
26
+ # open file
27
+ Kernel::exec "cd #{Config.base_dir} && #{ENV['EDITOR']} #{@date.relative_path}"
28
+ end
29
+
30
+ def self.help
31
+
32
+ return <<-eos
33
+ Open:\tedit backlog entries
34
+ eos
35
+
36
+ end
37
+
38
+ private
39
+ def symlink
40
+
41
+ path = File.join(Config.base_dir, "README.md")
42
+
43
+ # symlink current entry to readme
44
+ FileUtils.ln_s(@date.path, path, :force => true)
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,28 @@
1
+ module Backlog
2
+
3
+ class Push
4
+
5
+ def initialize(args, date)
6
+ # determine whether or not this is pushable
7
+ @pushable = remote_set
8
+ end
9
+
10
+ def execute!
11
+ if @pushable
12
+ push
13
+ end
14
+ end
15
+
16
+ private
17
+ def remote_set
18
+ command = "cd #{Config.base_dir} && git remote show origin 2>&1 1>/dev/null"
19
+ return Kernel::system command
20
+ end
21
+
22
+ def push
23
+ command = "cd #{Config.base_dir} && git push --force"
24
+ Kernel::system command
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,49 @@
1
+ module Backlog
2
+
3
+ class Save
4
+
5
+ def initialize(args = nil, datefile = nil)
6
+ end
7
+
8
+ def execute!
9
+ Save.save
10
+ end
11
+
12
+ def self.save_in_background
13
+
14
+ job = fork do
15
+ Kernel::exec command
16
+ end
17
+ Process.detach job
18
+
19
+ end
20
+
21
+ def self.save_date_on_open(date)
22
+
23
+ # takes in a date object and saves properly
24
+ Kernel::system command(commit_message(date))
25
+
26
+ end
27
+
28
+ def self.save
29
+ Kernel::exec command(commit_message)
30
+ end
31
+
32
+ private
33
+ def self.command(message)
34
+ command = "cd #{Config.base_dir} && git add --all . && git commit -a -m \"#{message}\""
35
+ end
36
+
37
+ def self.commit_message(date = nil)
38
+
39
+ today = Date.today.strftime("%A %B %d")
40
+ if date == nil
41
+ return today
42
+ else
43
+ entry = date.strftime("%A %B %d")
44
+ return "#{entry} (updated on #{today})"
45
+ end
46
+ end
47
+
48
+ end
49
+ end
data/lib/backlog.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'version'
2
+
3
+ # utilities
4
+ require 'backlog/args'
5
+ require 'backlog/config'
6
+ require 'backlog/datefile'
7
+
8
+ # individual commands
9
+ require 'backlog/help'
10
+ require 'backlog/entry'
11
+ require 'backlog/init'
12
+ require 'backlog/open'
13
+ require 'backlog/archive'
14
+ require 'backlog/save'
15
+ require 'backlog/push'
16
+
17
+ # cli controller
18
+ require 'backlog/cli'
19
+
20
+
data/lib/version.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Backlog
2
+
3
+ VERSION = "1.0.0"
4
+
5
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: personal-backlog
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jon Morehouse
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-30 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Personal backlog cli. Wraps a github repository and utilizes markdown
14
+ as a day to day management software
15
+ email:
16
+ - morehousej09@gmail.com
17
+ executables:
18
+ - backlog
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - README.md
23
+ - bin/backlog
24
+ - lib/backlog.rb
25
+ - lib/backlog/archive.rb
26
+ - lib/backlog/args.rb
27
+ - lib/backlog/cli.rb
28
+ - lib/backlog/config.rb
29
+ - lib/backlog/datefile.rb
30
+ - lib/backlog/entry.rb
31
+ - lib/backlog/file.rb
32
+ - lib/backlog/help.rb
33
+ - lib/backlog/init.rb
34
+ - lib/backlog/open.rb
35
+ - lib/backlog/push.rb
36
+ - lib/backlog/save.rb
37
+ - lib/version.rb
38
+ homepage: http://github.com/backlog
39
+ licenses:
40
+ - MIT
41
+ metadata: {}
42
+ post_install_message:
43
+ rdoc_options: []
44
+ require_paths:
45
+ - lib
46
+ required_ruby_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 2.2.2
59
+ signing_key:
60
+ specification_version: 4
61
+ summary: Personal Backlog manager
62
+ test_files: []