melon 0.5.0 → 0.6.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.
- data/History.txt +10 -1
- data/features/add.feature +15 -2
- data/features/help.feature +15 -0
- data/lib/melon/cli.rb +49 -41
- data/lib/melon/commands.rb +2 -2
- data/lib/melon/commands/add.rb +11 -5
- data/lib/melon/commands/base.rb +3 -0
- data/lib/melon/commands/check.rb +9 -6
- data/lib/melon/commands/common_options.rb +17 -0
- data/lib/melon/commands/help.rb +7 -1
- data/lib/melon/commands/show.rb +1 -1
- data/lib/melon/helpers.rb +4 -0
- data/lib/melon/version.rb +1 -1
- metadata +7 -4
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
=== 0.6.0 2011-02-10
|
2
|
+
* Major improvements
|
3
|
+
* melon now expands symlinks by default
|
4
|
+
* Added --preserve-symlinks option
|
5
|
+
|
6
|
+
* Minor improvements
|
7
|
+
* Fixed bug with add --update
|
8
|
+
* Fixed 'melon help'
|
9
|
+
|
1
10
|
=== 0.5.0 2011-02-09
|
2
11
|
* Major improvements:
|
3
12
|
* Added --recursive option to 'check' subcommand
|
@@ -9,7 +18,7 @@
|
|
9
18
|
|
10
19
|
=== 0.3.0 2011-01-28
|
11
20
|
* Major improvements:
|
12
|
-
* added 'help' command
|
21
|
+
* added 'help' command
|
13
22
|
|
14
23
|
=== 0.2.0 2011-01-26
|
15
24
|
* Major improvements:
|
data/features/add.feature
CHANGED
@@ -61,12 +61,25 @@ Feature: Adding files to the database
|
|
61
61
|
And the output should contain "dir/test/test3"
|
62
62
|
And the output should contain "test_file"
|
63
63
|
|
64
|
-
Scenario:
|
64
|
+
Scenario: Updating via add
|
65
65
|
Given a file named "test2" with:
|
66
66
|
"""
|
67
67
|
Also a test file
|
68
68
|
"""
|
69
69
|
And I run "melon -d test.db add -q test_file"
|
70
|
-
When I run "melon -d test.db add -u test_file
|
70
|
+
When I run "melon -d test.db add -u test2 test_file"
|
71
71
|
Then the output should contain "test2"
|
72
72
|
And the output should not contain "test_file"
|
73
|
+
|
74
|
+
Scenario: Adding a symlinked file
|
75
|
+
Given I run "ln -s test_file link"
|
76
|
+
When I run "melon -d test.db add link"
|
77
|
+
Then the output should contain "test_file"
|
78
|
+
And the output should not contain "link"
|
79
|
+
|
80
|
+
Scenario: Adding a symlinked file, preserving symlinks
|
81
|
+
Given I run "ln -s test_file link"
|
82
|
+
When I run "melon -d test.db add -p link"
|
83
|
+
Then the output should not contain "test_file"
|
84
|
+
And the output should contain "link"
|
85
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Getting help
|
2
|
+
In order to use all of melon's features correctly
|
3
|
+
As a user
|
4
|
+
I should be able to get help using melon
|
5
|
+
|
6
|
+
Scenario: General help
|
7
|
+
When I run "melon help"
|
8
|
+
Then the output should contain "Usage:"
|
9
|
+
And the output should contain "Commands:"
|
10
|
+
And the output should contain "Options:"
|
11
|
+
|
12
|
+
Scenario: Help with a particular command
|
13
|
+
When I run "melon help add"
|
14
|
+
Then the output should contain "Usage: melon add"
|
15
|
+
And the output should contain "Options:"
|
data/lib/melon/cli.rb
CHANGED
@@ -14,7 +14,7 @@ module Melon
|
|
14
14
|
new(arguments).run
|
15
15
|
end
|
16
16
|
|
17
|
-
attr_accessor :arguments
|
17
|
+
attr_accessor :arguments, :options, :parser
|
18
18
|
|
19
19
|
def initialize(arguments)
|
20
20
|
self.arguments = arguments
|
@@ -26,40 +26,8 @@ module Melon
|
|
26
26
|
options
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
31
|
-
options.database = PStore.new(File.expand_path(options.database_path))
|
32
|
-
|
33
|
-
# prepare db
|
34
|
-
options.database.transaction do
|
35
|
-
options.database[:by_hash] ||= {}
|
36
|
-
options.database[:by_path] ||= {}
|
37
|
-
end
|
38
|
-
|
39
|
-
unless arguments.empty?
|
40
|
-
run_command(options)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def run_command(options)
|
45
|
-
# look for command class in args.shift
|
46
|
-
command_name = arguments.shift
|
47
|
-
begin
|
48
|
-
c = Commands[command_name.capitalize]
|
49
|
-
rescue NameError => e
|
50
|
-
# don't swallow NoMethodErrors
|
51
|
-
raise e unless e.instance_of?(NameError)
|
52
|
-
error "unrecognized command: #{command_name}"
|
53
|
-
end
|
54
|
-
c.new(arguments, options).run
|
55
|
-
end
|
56
|
-
|
57
|
-
def parse_options
|
58
|
-
options = self.class.default_options
|
59
|
-
|
60
|
-
# TODO: empty args should be -h
|
61
|
-
|
62
|
-
parser = OptionParser.new do |p|
|
29
|
+
def parser
|
30
|
+
@parser ||= OptionParser.new do |p|
|
63
31
|
p.banner = "Usage: melon [options] COMMAND [command-options] [ARGS]"
|
64
32
|
|
65
33
|
p.separator ""
|
@@ -67,7 +35,6 @@ module Melon
|
|
67
35
|
p.separator ""
|
68
36
|
|
69
37
|
Commands.each do |command|
|
70
|
-
# help goes last
|
71
38
|
if command.command_name == 'help'
|
72
39
|
next
|
73
40
|
end
|
@@ -75,9 +42,6 @@ module Melon
|
|
75
42
|
p.separator format_command(command.command_name,
|
76
43
|
command.description)
|
77
44
|
end
|
78
|
-
# TODO: add help command back into parser helptext
|
79
|
-
# p.separator format_command(Commands::Help.command_name,
|
80
|
-
# Commands::Help.description)
|
81
45
|
p.separator ""
|
82
46
|
p.separator "Options:"
|
83
47
|
p.separator ""
|
@@ -87,17 +51,61 @@ module Melon
|
|
87
51
|
options.database_path = database
|
88
52
|
end
|
89
53
|
|
90
|
-
p.
|
54
|
+
p.on("-v", "--version", "Show version") do
|
91
55
|
puts Melon.version_string
|
92
56
|
exit 0
|
93
57
|
end
|
94
58
|
|
95
|
-
p.
|
59
|
+
p.on("-h", "--help", "This is it") do
|
96
60
|
puts p
|
97
61
|
exit 0
|
98
62
|
end
|
63
|
+
|
64
|
+
p.separator ""
|
65
|
+
p.separator "For more information on a specific command," +
|
66
|
+
" use 'melon help COMMAND'"
|
99
67
|
end
|
100
68
|
|
69
|
+
end
|
70
|
+
|
71
|
+
def run
|
72
|
+
parse_options
|
73
|
+
options.database = PStore.new(File.expand_path(options.database_path))
|
74
|
+
|
75
|
+
# prepare db
|
76
|
+
options.database.transaction do
|
77
|
+
options.database[:by_hash] ||= {}
|
78
|
+
options.database[:by_path] ||= {}
|
79
|
+
end
|
80
|
+
|
81
|
+
if arguments.empty?
|
82
|
+
puts parser
|
83
|
+
exit
|
84
|
+
else
|
85
|
+
# look for command class in args.shift
|
86
|
+
command_name = arguments.shift
|
87
|
+
|
88
|
+
run_command(command_name)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def run_command(command_name)
|
93
|
+
begin
|
94
|
+
command_class = Commands[command_name.capitalize]
|
95
|
+
rescue NameError => e
|
96
|
+
# don't swallow NoMethodErrors
|
97
|
+
raise e unless e.instance_of?(NameError)
|
98
|
+
error "unrecognized command: #{command_name}"
|
99
|
+
end
|
100
|
+
c = command_class.new(arguments, options)
|
101
|
+
(command_name == 'help' ? c.run(self) : c.run)
|
102
|
+
end
|
103
|
+
|
104
|
+
def parse_options
|
105
|
+
self.options = self.class.default_options
|
106
|
+
|
107
|
+
# TODO: empty args should be -h
|
108
|
+
|
101
109
|
begin
|
102
110
|
parser.order!(arguments)
|
103
111
|
rescue OptionParser::ParseError => e
|
data/lib/melon/commands.rb
CHANGED
@@ -7,7 +7,7 @@ module Melon
|
|
7
7
|
self.constants.sort.each do |c|
|
8
8
|
const = self.const_get(c)
|
9
9
|
|
10
|
-
if const.superclass == Base
|
10
|
+
if const.respond_to?(:superclass) && const.superclass == Base
|
11
11
|
consts << const
|
12
12
|
yield const
|
13
13
|
end
|
@@ -22,12 +22,12 @@ module Melon
|
|
22
22
|
|
23
23
|
# 1.0 list
|
24
24
|
# TODO: check needs -r
|
25
|
+
# TODO: update- a function of add, ignore files that are already present in the db
|
25
26
|
# TODO: needs a 'remove' command, or some way to deal with deletes/renames
|
26
27
|
# remove: given a tracked file, removes it
|
27
28
|
# given an untracked file, it hashes it
|
28
29
|
# and attempts to remove it by hash
|
29
30
|
# TODO: list needs --paths(only) and --hashes(only)
|
30
|
-
# TODO: update- a function of add, ignore files that are already present in the db
|
31
31
|
# TODO: handle moving a file somehow -- hopefully a function of update
|
32
32
|
# could be:
|
33
33
|
# 1. move file
|
data/lib/melon/commands/add.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'melon/hasher'
|
2
2
|
require 'melon/commands/base'
|
3
|
+
require 'melon/commands/common_options'
|
3
4
|
|
4
5
|
module Melon
|
5
6
|
module Commands
|
@@ -13,14 +14,18 @@ module Melon
|
|
13
14
|
options.quiet = true
|
14
15
|
end
|
15
16
|
|
16
|
-
|
17
|
-
options.recursive = true
|
18
|
-
end
|
17
|
+
CommonOptions.recursive(parser, options)
|
19
18
|
|
20
|
-
parser.on("-u" "--update",
|
19
|
+
parser.on("-u", "--update",
|
21
20
|
"Skip paths already present in the database") do
|
22
21
|
options.update = true
|
23
|
-
|
22
|
+
end
|
23
|
+
|
24
|
+
CommonOptions.preserve_symlinks(parser, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def usageargs
|
28
|
+
"FILE [FILE [FILE ...]]"
|
24
29
|
end
|
25
30
|
|
26
31
|
def run
|
@@ -33,6 +38,7 @@ module Melon
|
|
33
38
|
options.database.transaction do
|
34
39
|
args.each do |arg|
|
35
40
|
filename = File.expand_path(arg)
|
41
|
+
filename = resolve_symlinks(filename) unless options.preserve_symlinks
|
36
42
|
|
37
43
|
if File.directory?(filename)
|
38
44
|
error "argument is a directory: #{arg}"
|
data/lib/melon/commands/base.rb
CHANGED
data/lib/melon/commands/check.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'melon/commands/base'
|
2
|
+
require 'melon/commands/common_options'
|
2
3
|
|
3
4
|
module Melon
|
4
5
|
module Commands
|
@@ -15,13 +16,12 @@ EOS
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def usageargs
|
18
|
-
"
|
19
|
+
"FILE [FILE [FILE ...]]"
|
19
20
|
end
|
20
21
|
|
21
22
|
def parser_options(parser)
|
22
|
-
|
23
|
-
|
24
|
-
end
|
23
|
+
CommonOptions.recursive(parser, options)
|
24
|
+
CommonOptions.preserve_symlinks(parser, options)
|
25
25
|
end
|
26
26
|
|
27
27
|
def run
|
@@ -32,14 +32,17 @@ EOS
|
|
32
32
|
end
|
33
33
|
|
34
34
|
options.database.transaction do
|
35
|
-
args.each do |
|
35
|
+
args.each do |arg|
|
36
|
+
filename = File.expand_path(arg)
|
37
|
+
filename = resolve_symlinks(filename) unless options.preserve_symlinks
|
38
|
+
|
36
39
|
if File.directory?(filename)
|
37
40
|
error "argument is a directory: #{arg}"
|
38
41
|
end
|
39
42
|
|
40
43
|
hash = Hasher.digest(filename)
|
41
44
|
unless options.database[:by_hash][hash]
|
42
|
-
puts
|
45
|
+
puts filename
|
43
46
|
end
|
44
47
|
end
|
45
48
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Melon
|
2
|
+
module Commands
|
3
|
+
module CommonOptions
|
4
|
+
def self.recursive(parser, options)
|
5
|
+
parser.on("-r", "--recursive", "Recursively process directories") do
|
6
|
+
options.recursive = true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.preserve_symlinks(parser, options)
|
11
|
+
parser.on("-p", "--preserve-symlinks", "Don't expand symlinks") do
|
12
|
+
options.preserve_symlinks = true
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/melon/commands/help.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'melon/cli'
|
1
2
|
require 'melon/commands/base'
|
2
3
|
require 'melon/commands'
|
3
4
|
|
@@ -8,10 +9,15 @@ module Melon
|
|
8
9
|
"Get help with a specific command"
|
9
10
|
end
|
10
11
|
|
11
|
-
def run
|
12
|
+
def run(cli)
|
13
|
+
if args.empty?
|
14
|
+
puts cli.parser
|
15
|
+
exit
|
16
|
+
end
|
12
17
|
help = args.shift
|
13
18
|
begin
|
14
19
|
puts Commands[help.capitalize].new(args, options).parser
|
20
|
+
exit
|
15
21
|
rescue NameError => e
|
16
22
|
# don't swallow NoMethodErrors
|
17
23
|
raise e unless e.instance_of?(NameError)
|
data/lib/melon/commands/show.rb
CHANGED
data/lib/melon/helpers.rb
CHANGED
data/lib/melon/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: melon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 6
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.6.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andrew Roberts
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-10 00:00:00 -05:00
|
19
19
|
default_executable: melon
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -81,6 +81,7 @@ files:
|
|
81
81
|
- features/add.feature
|
82
82
|
- features/check.feature
|
83
83
|
- features/edges.feature
|
84
|
+
- features/help.feature
|
84
85
|
- features/list.feature
|
85
86
|
- features/show.feature
|
86
87
|
- features/step_definitions/basic_steps.rb
|
@@ -91,6 +92,7 @@ files:
|
|
91
92
|
- lib/melon/commands/add.rb
|
92
93
|
- lib/melon/commands/base.rb
|
93
94
|
- lib/melon/commands/check.rb
|
95
|
+
- lib/melon/commands/common_options.rb
|
94
96
|
- lib/melon/commands/help.rb
|
95
97
|
- lib/melon/commands/list.rb
|
96
98
|
- lib/melon/commands/show.rb
|
@@ -143,6 +145,7 @@ test_files:
|
|
143
145
|
- features/add.feature
|
144
146
|
- features/check.feature
|
145
147
|
- features/edges.feature
|
148
|
+
- features/help.feature
|
146
149
|
- features/list.feature
|
147
150
|
- features/show.feature
|
148
151
|
- features/step_definitions/basic_steps.rb
|