personal-backlog 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []