nit 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +4 -0
- data/README.md +27 -3
- data/Thorfile +1 -0
- data/lib/nit/app.rb +18 -24
- data/lib/nit/command.rb +38 -0
- data/lib/nit/{commit.rb → command/commit.rb} +3 -3
- data/lib/nit/command/dynamic.rb +14 -0
- data/lib/nit/command/ignore.rb +38 -0
- data/lib/nit/command/pull.rb +8 -0
- data/lib/nit/command/push.rb +20 -0
- data/lib/nit/command/status.rb +90 -0
- data/lib/nit/config.rb +1 -1
- data/lib/nit/files.rb +1 -1
- data/lib/nit/version.rb +1 -1
- data/test/commands_test.rb +53 -0
- data/test/config_test.rb +1 -1
- data/test/ignore_test.rb +9 -10
- data/test/nit_test.rb +3 -1
- data/test/status_test.rb +5 -36
- data/test/test_helper.rb +21 -0
- metadata +12 -5
- data/lib/nit/ignore.rb +0 -36
- data/lib/nit/status.rb +0 -94
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad661b2510762a5a197158e53996a4b5c48443dc
|
4
|
+
data.tar.gz: c7a40b75bb9e2e1a0f15929fd478f08637ee635f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a53d6fcaee8a35a8c37614e211179e6b9c1c56d7501e21a6ae4a07e2bcf8b6175ea6520476eeeb964d788996e5a56177faf65a334d8a3505104ffcf6b59f304
|
7
|
+
data.tar.gz: 2a9103e438303f1cdeb3e46fd1f01d1fa8c3bef9c38766e499db0c53325d3ac5c7b9c268c3267425dcad071e50f59283957ffbbd60faec657fbff153833c085a
|
data/CHANGES.md
ADDED
data/README.md
CHANGED
@@ -46,9 +46,25 @@ First of all, it shows you the current branch in bold.
|
|
46
46
|
|
47
47
|
Secondly, the status screen renders a file index for each file which can be used on the command-line.
|
48
48
|
|
49
|
-
Indexes per default are characters on the right-hand side of the filename.
|
49
|
+
Indexes per default are characters on the right-hand side of the filename.
|
50
50
|
|
51
|
-
|
51
|
+
```shell
|
52
|
+
# modified: on_stage.rb [a]
|
53
|
+
```
|
54
|
+
|
55
|
+
This can be configured, in case you prefer digits.
|
56
|
+
|
57
|
+
```shell
|
58
|
+
# modified: on_stage.rb [0]
|
59
|
+
```
|
60
|
+
|
61
|
+
You can also have the indexes prepended to the filename.
|
62
|
+
|
63
|
+
```shell
|
64
|
+
# modified: [a] on_stage.rb
|
65
|
+
```
|
66
|
+
|
67
|
+
Learn [more](https://github.com/apotonick/nit#alternative-indexing).
|
52
68
|
|
53
69
|
## Commit
|
54
70
|
|
@@ -154,6 +170,12 @@ Will figure out the current branch and run
|
|
154
170
|
git push origin <current branch>
|
155
171
|
```
|
156
172
|
|
173
|
+
Note that `pull` and `push` accept command-line options, so this will push your tags as well, if you're releasing.
|
174
|
+
|
175
|
+
```shell
|
176
|
+
nit push --tags
|
177
|
+
```
|
178
|
+
|
157
179
|
## Pull
|
158
180
|
|
159
181
|
The same works for `nit pull`.
|
@@ -165,7 +187,7 @@ You can use nit's index interpolation for any git command.
|
|
165
187
|
|
166
188
|
```shell
|
167
189
|
nit diff ab
|
168
|
-
|
190
|
+
```
|
169
191
|
|
170
192
|
|
171
193
|
## Manual Configuration
|
@@ -202,6 +224,8 @@ Nap in the park.
|
|
202
224
|
index_renderer = "PrependIndexRenderer"
|
203
225
|
```
|
204
226
|
|
227
|
+
However, scientific studies with `nit` over the last 18 years have proven that characters instead of digits are faster to reach when typing. Also, indexes _appended_ to the filename make them easier to read when deciding what to commit.
|
228
|
+
|
205
229
|
## Extending Nit
|
206
230
|
|
207
231
|
Extending nit with your own commands can be done either with gems or by placing the extensions into your `.nit` directory. This will be implemented and documented soon.
|
data/Thorfile
CHANGED
data/lib/nit/app.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "nit/files"
|
3
3
|
require "nit/lines"
|
4
|
-
require "nit/status"
|
5
|
-
require "nit/commit"
|
6
4
|
require "nit/config"
|
7
|
-
require "nit/
|
8
|
-
|
5
|
+
require "nit/command"
|
6
|
+
require "nit/command/status"
|
7
|
+
require "nit/command/commit"
|
8
|
+
require "nit/command/ignore"
|
9
|
+
require "nit/command/push"
|
10
|
+
require "nit/command/pull"
|
11
|
+
require "nit/command/dynamic"
|
9
12
|
|
10
13
|
|
11
14
|
# TODO:
|
@@ -23,42 +26,36 @@ module Nit
|
|
23
26
|
default_command(:status)
|
24
27
|
|
25
28
|
desc "status", "bla"
|
26
|
-
def status
|
27
|
-
puts Status.new(config).call
|
29
|
+
def status(*args)
|
30
|
+
puts Command::Status.new(config).call(args)
|
28
31
|
end
|
29
32
|
|
30
33
|
desc "commit", "blubb"
|
31
34
|
def commit(*args)
|
32
|
-
puts Commit.new(config).call(
|
35
|
+
puts Command::Commit.new(config).call(args)
|
33
36
|
end
|
34
37
|
|
35
38
|
desc "ignore", "blubb"
|
36
39
|
def ignore(*args)
|
37
|
-
puts Ignore.new(config).call(
|
40
|
+
puts Command::Ignore.new(config).call(args)
|
38
41
|
end
|
39
42
|
|
40
43
|
desc "unignore", "blubb"
|
41
44
|
def unignore(*args)
|
42
|
-
puts Unignore.new(config).call(
|
45
|
+
puts Command::Unignore.new(config).call(args)
|
43
46
|
end
|
44
47
|
|
45
|
-
|
46
48
|
desc "pull", "pull from current branch at origin"
|
47
|
-
def pull
|
48
|
-
|
49
|
+
def pull(*args)
|
50
|
+
puts Command::Pull.new(config).call(args)
|
49
51
|
end
|
50
52
|
|
51
53
|
desc "push", "push to current branch at origin"
|
52
|
-
def push
|
53
|
-
|
54
|
+
def push(*args)
|
55
|
+
puts Command::Push.new(config).call(args)
|
54
56
|
end
|
55
57
|
|
56
58
|
private
|
57
|
-
def current_branch
|
58
|
-
output = `git branch`
|
59
|
-
branch = output.match(/\* (.+)/)[1].strip
|
60
|
-
end
|
61
|
-
|
62
59
|
def config
|
63
60
|
@config ||= Config.new # TODO: eventually pass path.
|
64
61
|
end
|
@@ -69,11 +66,8 @@ module Nit
|
|
69
66
|
|
70
67
|
#class DynamicCommand < Thor::DynamicCommand
|
71
68
|
Thor::DynamicCommand.class_eval do # see https://github.com/erikhuda/thor/pull/358
|
72
|
-
def run(app,
|
73
|
-
|
74
|
-
state = Status::State.new(`git status`, app.send(:config))
|
75
|
-
|
76
|
-
puts `git #{command} #{state.files.list(indexes)}`
|
69
|
+
def run(app, args)
|
70
|
+
puts Command::Dynamic.new(app.send(:config), name).call(args)
|
77
71
|
end
|
78
72
|
end
|
79
73
|
end
|
data/lib/nit/command.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Nit
|
2
|
+
class Command
|
3
|
+
def initialize(config)
|
4
|
+
@config = config
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(args, original=`git status`)
|
8
|
+
state = Status::State.new(original, @config)
|
9
|
+
|
10
|
+
indexes, args = process_args(args)
|
11
|
+
|
12
|
+
process(state, indexes, args)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def process_args(args)
|
17
|
+
ArgsProcessor.new(@config).call(args)
|
18
|
+
end
|
19
|
+
|
20
|
+
class ArgsProcessor
|
21
|
+
def initialize(config)
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(thor_args)
|
25
|
+
args = []
|
26
|
+
indexes = []
|
27
|
+
|
28
|
+
thor_args.reverse.each do |arg|
|
29
|
+
next unless arg.size == 1 or arg =~ /^\w+$/
|
30
|
+
indexes << arg
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
[indexes.reverse, thor_args-indexes]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
|
1
|
+
class Nit::Command
|
2
2
|
class Commit < Status
|
3
|
-
def process(state, indexes)
|
4
|
-
system "git add #{state.files.list(indexes)} && git commit"
|
3
|
+
def process(state, indexes, args)
|
4
|
+
system "git add #{state.files.list(indexes)} && git commit #{args.join(" ")}"
|
5
5
|
end
|
6
6
|
end
|
7
7
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Nit
|
2
|
+
class Command
|
3
|
+
class Dynamic < Command
|
4
|
+
def initialize(config, name)
|
5
|
+
super(config)
|
6
|
+
@command = name
|
7
|
+
end
|
8
|
+
|
9
|
+
def process(state, indexes, args)
|
10
|
+
`git #{@command} #{args.join(" ")} #{state.files.list(indexes)}`
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Nit
|
2
|
+
class Command
|
3
|
+
class Ignore < Status
|
4
|
+
def initialize(*)
|
5
|
+
super
|
6
|
+
@ignores = Files.new(@config.ignored_files, @config.indexer)
|
7
|
+
end
|
8
|
+
attr_reader :ignores
|
9
|
+
|
10
|
+
private
|
11
|
+
def process(state, indexes, args)
|
12
|
+
return show if indexes.size == 0
|
13
|
+
|
14
|
+
file_list = state.files.evaluate(indexes).compact
|
15
|
+
|
16
|
+
@config.ignored_files=(@config.ignored_files + file_list)
|
17
|
+
end
|
18
|
+
|
19
|
+
def show
|
20
|
+
return if ignores.size == 0
|
21
|
+
|
22
|
+
output = "Ignored files:\n"
|
23
|
+
ignores.each { |f| output << "[#{ignores.index(f)}] #{f}\n" }
|
24
|
+
|
25
|
+
output
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class Unignore < Ignore
|
30
|
+
private
|
31
|
+
def process(state, indexes, args)
|
32
|
+
file_list = state.ignored.evaluate(indexes).compact
|
33
|
+
|
34
|
+
@config.ignored_files=(@config.ignored_files - file_list.map(&:to_s)) # FIXME: make this work with strings and File instances.
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Nit
|
2
|
+
class Command
|
3
|
+
class Push < Command
|
4
|
+
def call(args, original=`git branch`)
|
5
|
+
branch = current_branch_for(original)
|
6
|
+
|
7
|
+
system("git #{command} origin #{branch} #{args.join(" ")}")
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def command
|
12
|
+
"push"
|
13
|
+
end
|
14
|
+
|
15
|
+
def current_branch_for(screen)
|
16
|
+
screen.match(/\* (.+)/)[1].strip
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Nit
|
2
|
+
class Command
|
3
|
+
class Status < Command
|
4
|
+
# Encapsulates the process of computing the file index from `git status`.
|
5
|
+
class State # DISCUSS: alternative names: Screen, ScreenState, FileIndexes?
|
6
|
+
# TODO: test me.
|
7
|
+
def initialize(screen_state, config)
|
8
|
+
@screen = Lines.new(screen_state)
|
9
|
+
|
10
|
+
@files, @ignored = files_for(screen, config)
|
11
|
+
end
|
12
|
+
attr_reader :files, :ignored, :screen
|
13
|
+
|
14
|
+
private
|
15
|
+
def files_for(screen, config)
|
16
|
+
files = screen.files
|
17
|
+
|
18
|
+
ignored = [] # TODO: that must be implemented by Files.
|
19
|
+
files.delete_if { |f| config.ignored_files.include?(f.path) ? ignored << f : false }
|
20
|
+
|
21
|
+
[Files.new(files, config.indexer), Files.new(ignored, config.indexer)]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def initialize(config)
|
27
|
+
super
|
28
|
+
extend config.index_renderer
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def process(state, indexes, args)
|
33
|
+
files, screen, ignored = state.files, state.screen, state.ignored
|
34
|
+
|
35
|
+
files.each do |file| # TODO: should we have redundant file patterns here? it is better readable, thou.
|
36
|
+
ln = file.line
|
37
|
+
i = files.index(file)
|
38
|
+
|
39
|
+
if ln.match(screen.file_patterns[:modified])
|
40
|
+
process_modified(i, file, ln)
|
41
|
+
elsif ln.match(screen.file_patterns[:new])
|
42
|
+
process_new(i, file, ln)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# TODO: should be pluggable:
|
47
|
+
ignore_files(screen, ignored)
|
48
|
+
bold_branch(screen)
|
49
|
+
|
50
|
+
screen.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
module AppendIndexRenderer
|
54
|
+
def process_modified(i, file, line)
|
55
|
+
line << " [#{i}]"
|
56
|
+
end
|
57
|
+
|
58
|
+
def process_new(*args)
|
59
|
+
process_modified(*args)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module PrependIndexRenderer
|
64
|
+
def process_modified(i, file, line)
|
65
|
+
line.sub!("#\tmodified:", "#\tmodified: [#{i}] ")
|
66
|
+
end
|
67
|
+
|
68
|
+
def process_new(i, file, line)
|
69
|
+
line.sub!("#\t", "#\t [#{i}] ")
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def bold_branch(lines)
|
75
|
+
lines.find(/# On branch (.+)/) do |ln, matches|
|
76
|
+
line = "# On branch \033[1m#{matches[1]}\033[22m"
|
77
|
+
ln.replace(line)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def ignore_files(screen, ignored)
|
82
|
+
return unless ignored.size > 0
|
83
|
+
|
84
|
+
ignored.each { |f| f.line.delete }
|
85
|
+
screen << "#"
|
86
|
+
screen << "# Ignored files: #{ignored.size}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/lib/nit/config.rb
CHANGED
data/lib/nit/files.rb
CHANGED
data/lib/nit/version.rb
CHANGED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class CommandsTest < MiniTest::Spec
|
4
|
+
let (:config) { Nit::Config.new }
|
5
|
+
let (:cmd_obj) { Nit::Command.const_get(klass).new(config) }
|
6
|
+
let (:cmd) { cmd_obj.tap do |obj|
|
7
|
+
obj.instance_eval do
|
8
|
+
def system(string); string; end
|
9
|
+
end
|
10
|
+
end }
|
11
|
+
|
12
|
+
|
13
|
+
describe "push" do
|
14
|
+
let (:klass) { "Push" }
|
15
|
+
let (:screen) { "* master\n" }
|
16
|
+
|
17
|
+
it { cmd.call([], screen).must_equal("git push origin master ") }
|
18
|
+
it { cmd.call(["--tags"], screen).must_equal("git push origin master --tags") }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "pull" do
|
22
|
+
let (:klass) { "Pull" }
|
23
|
+
let (:screen) { "* master\n" }
|
24
|
+
|
25
|
+
it { cmd.call([], screen).must_equal("git pull origin master ") }
|
26
|
+
it { cmd.call(["--tags"], screen).must_equal("git pull origin master --tags") }
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "commit" do
|
30
|
+
let (:klass) { "Commit" }
|
31
|
+
let (:screen) { output }
|
32
|
+
|
33
|
+
it "also ignores files when commiting" do
|
34
|
+
config.ignored_files = ["new.rb", "brandnew.rb", "staged.rb"] # TODO: make this more generic.
|
35
|
+
|
36
|
+
cmd.call(["b"], output).must_equal "git add ../lib/new.rb && git commit "
|
37
|
+
end
|
38
|
+
|
39
|
+
it { cmd.call(["-m", '"awesome work"', "b"], output).must_equal "git add ../lib/new.rb && git commit -m \"awesome work\"" }
|
40
|
+
|
41
|
+
# TODO: test nit commit -a
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class ArgsProcessorTest < MiniTest::Spec
|
46
|
+
let (:config) { Nit::Config.new }
|
47
|
+
subject { Nit::Command::ArgsProcessor.new(config) }
|
48
|
+
|
49
|
+
it { subject.call([]).must_equal [[], []] }
|
50
|
+
it { subject.call(["-a"]).must_equal [[], ["-a"]] }
|
51
|
+
it { subject.call(["-a", "-m", '"message"', "abc"]).must_equal [["abc"], ["-a", "-m", '"message"']] }
|
52
|
+
it { subject.call(["-m", '"message"', "a", "b"]).must_equal [["a", "b"], ["-m", '"message"']] }
|
53
|
+
end
|
data/test/config_test.rb
CHANGED
@@ -11,5 +11,5 @@ class ConfigTest < MiniTest::Spec
|
|
11
11
|
subject.indexer.must_equal Nit::Files::CharIndexer
|
12
12
|
end
|
13
13
|
|
14
|
-
it { subject.index_renderer.must_equal Nit::Status::AppendIndexRenderer }
|
14
|
+
it { subject.index_renderer.must_equal Nit::Command::Status::AppendIndexRenderer }
|
15
15
|
end
|
data/test/ignore_test.rb
CHANGED
@@ -1,36 +1,35 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class IgnoreTest < StatusTest
|
4
|
-
let (:config) {
|
5
|
-
|
4
|
+
let (:config) { Nit::Config.new }
|
6
5
|
after do
|
7
6
|
config.send(:file).rm!
|
8
7
|
end
|
9
8
|
|
10
9
|
it "ignores invalid indexes" do
|
11
|
-
Nit::Ignore.new(config).call(
|
10
|
+
Nit::Command::Ignore.new(config).call(["z"], output)
|
12
11
|
config.ignored_files.must_equal []
|
13
12
|
end
|
14
13
|
|
15
14
|
it "what" do
|
16
15
|
config.ignored_files.must_equal []
|
17
16
|
|
18
|
-
Nit::Ignore.new(config).call(
|
17
|
+
Nit::Command::Ignore.new(config).call(["ab"], output)
|
19
18
|
|
20
19
|
config.ignored_files.must_equal ["on_stage.rb", "staged.rb"]
|
21
20
|
end
|
22
21
|
|
23
22
|
describe "ignore (no arguments)" do
|
24
23
|
it "blanks when nothing ignored" do
|
25
|
-
Nit::Ignore.new(config).call(
|
24
|
+
Nit::Command::Ignore.new(config).call([], output).must_equal nil
|
26
25
|
end
|
27
26
|
|
28
27
|
it "shows ignored files" do
|
29
|
-
Nit::Ignore.new(config).call(
|
28
|
+
Nit::Command::Ignore.new(config).call(["b"], output)
|
30
29
|
|
31
|
-
Nit::Ignore.new(config).call(
|
30
|
+
Nit::Command::Ignore.new(config).call([], output).must_equal <<-EOF
|
32
31
|
Ignored files:
|
33
|
-
[
|
32
|
+
[a] staged.rb
|
34
33
|
EOF
|
35
34
|
# FIXME: why is <<- not working?
|
36
35
|
end
|
@@ -38,8 +37,8 @@ EOF
|
|
38
37
|
|
39
38
|
describe "unignore 1 2" do
|
40
39
|
it "what" do
|
41
|
-
Nit::Ignore.new(config).call(
|
42
|
-
Nit::Unignore.new(config).call(
|
40
|
+
Nit::Command::Ignore.new(config).call(["ab"], output)
|
41
|
+
Nit::Command::Unignore.new(config).call(["b"], output)
|
43
42
|
config.ignored_files.must_equal ["on_stage.rb"]
|
44
43
|
end
|
45
44
|
end
|
data/test/nit_test.rb
CHANGED
@@ -35,8 +35,10 @@ class DynamicCommandTest < NitTest
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
class
|
38
|
+
class ArbitraryGitCommandsTest < NitTest
|
39
39
|
it { nit(" diff b").must_match "a\/staged.rb" }
|
40
|
+
|
41
|
+
it { nit(" diff --raw b").must_equal ":100644 100644 e69de29... 0000000... M\tstaged.rb\n" }
|
40
42
|
end
|
41
43
|
|
42
44
|
class NitWithCharIndexerTest < NitTest
|
data/test/status_test.rb
CHANGED
@@ -8,30 +8,12 @@ class StatusTest < MiniTest::Spec
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
# On branch master
|
13
|
-
# Changes not staged for commit:
|
14
|
-
# (use "git add <file>..." to update what will be committed)
|
15
|
-
# (use "git checkout -- <file>..." to discard changes in working directory)
|
16
|
-
#
|
17
|
-
#\tmodified: on_stage.rb
|
18
|
-
#\tmodified: staged.rb
|
19
|
-
#
|
20
|
-
# Untracked files:
|
21
|
-
# (use "git add <file>..." to include in what will be committed)
|
22
|
-
#
|
23
|
-
#\tbrandnew.rb
|
24
|
-
#\tnew.rb
|
25
|
-
#\t../lib/new.rb
|
26
|
-
no changes added to commit (use "git add" and/or "git commit -a")
|
27
|
-
EOF
|
28
|
-
end
|
29
|
-
subject { Nit::Status.new(config) }
|
11
|
+
subject { Nit::Command::Status.new(config) }
|
30
12
|
|
31
13
|
|
32
14
|
describe "indexing" do
|
33
15
|
it "numbers files" do
|
34
|
-
console = subject.call(output)
|
16
|
+
console = subject.call([], output)
|
35
17
|
console.must_match "modified: [0] on_stage.rb"
|
36
18
|
console.must_match "modified: [1] staged.rb"
|
37
19
|
console.must_match "[2] brandnew.rb"
|
@@ -43,7 +25,7 @@ class StatusTest < MiniTest::Spec
|
|
43
25
|
it "indexes files" do
|
44
26
|
config.indexer = "CharIndexer"
|
45
27
|
|
46
|
-
console = subject.call(output)
|
28
|
+
console = subject.call([], output)
|
47
29
|
console.must_match "modified: [a] on_stage.rb"
|
48
30
|
console.must_match "modified: [b] staged.rb"
|
49
31
|
console.must_match "[c] brandnew.rb"
|
@@ -57,13 +39,13 @@ class StatusTest < MiniTest::Spec
|
|
57
39
|
end
|
58
40
|
|
59
41
|
it "doesn't show ignored files count per default" do
|
60
|
-
subject.call(output).wont_match(/Ignored files:/)
|
42
|
+
subject.call([], output).wont_match(/Ignored files:/)
|
61
43
|
end
|
62
44
|
|
63
45
|
it "shows ignored files when ignoring" do
|
64
46
|
config.ignored_files = ["new.rb", "brandnew.rb", "staged.rb"] # TODO: make this more generic.
|
65
47
|
|
66
|
-
console = subject.call(output)
|
48
|
+
console = subject.call([], output)
|
67
49
|
console.must_match "[1] ../lib/new.rb" # this file has a new index since all other ignored.
|
68
50
|
console.must_match "Ignored files: 3"
|
69
51
|
console.wont_match " staged.rb"
|
@@ -71,18 +53,5 @@ class StatusTest < MiniTest::Spec
|
|
71
53
|
console.wont_match " brandnew.rb"
|
72
54
|
console.must_match " ../lib/new.rb"
|
73
55
|
end
|
74
|
-
|
75
|
-
it "also ignores files when commiting" do
|
76
|
-
config.ignored_files = ["new.rb", "brandnew.rb", "staged.rb"] # TODO: make this more generic.
|
77
|
-
|
78
|
-
commit = Nit::Commit.new(config)
|
79
|
-
commit.instance_eval do
|
80
|
-
def system(command)
|
81
|
-
command
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
commit.call(output, [1]).must_equal "git add ../lib/new.rb && git commit"
|
86
|
-
end
|
87
56
|
end
|
88
57
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,2 +1,23 @@
|
|
1
1
|
require 'minitest/autorun'
|
2
2
|
require 'nit/app'
|
3
|
+
|
4
|
+
MiniTest::Spec.class_eval do
|
5
|
+
let (:output) do <<-EOF
|
6
|
+
# On branch master
|
7
|
+
# Changes not staged for commit:
|
8
|
+
# (use "git add <file>..." to update what will be committed)
|
9
|
+
# (use "git checkout -- <file>..." to discard changes in working directory)
|
10
|
+
#
|
11
|
+
#\tmodified: on_stage.rb
|
12
|
+
#\tmodified: staged.rb
|
13
|
+
#
|
14
|
+
# Untracked files:
|
15
|
+
# (use "git add <file>..." to include in what will be committed)
|
16
|
+
#
|
17
|
+
#\tbrandnew.rb
|
18
|
+
#\tnew.rb
|
19
|
+
#\t../lib/new.rb
|
20
|
+
no changes added to commit (use "git add" and/or "git commit -a")
|
21
|
+
EOF
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -75,6 +75,7 @@ extensions: []
|
|
75
75
|
extra_rdoc_files: []
|
76
76
|
files:
|
77
77
|
- .gitignore
|
78
|
+
- CHANGES.md
|
78
79
|
- Gemfile
|
79
80
|
- LICENSE.txt
|
80
81
|
- README.md
|
@@ -84,14 +85,19 @@ files:
|
|
84
85
|
- lib/nit.rb
|
85
86
|
- lib/nit/CHANGES.mk
|
86
87
|
- lib/nit/app.rb
|
87
|
-
- lib/nit/
|
88
|
+
- lib/nit/command.rb
|
89
|
+
- lib/nit/command/commit.rb
|
90
|
+
- lib/nit/command/dynamic.rb
|
91
|
+
- lib/nit/command/ignore.rb
|
92
|
+
- lib/nit/command/pull.rb
|
93
|
+
- lib/nit/command/push.rb
|
94
|
+
- lib/nit/command/status.rb
|
88
95
|
- lib/nit/config.rb
|
89
96
|
- lib/nit/files.rb
|
90
|
-
- lib/nit/ignore.rb
|
91
97
|
- lib/nit/lines.rb
|
92
|
-
- lib/nit/status.rb
|
93
98
|
- lib/nit/version.rb
|
94
99
|
- nit.gemspec
|
100
|
+
- test/commands_test.rb
|
95
101
|
- test/config_test.rb
|
96
102
|
- test/dummies/stage/.gitignore
|
97
103
|
- test/dummies/stage/brandnew.rb
|
@@ -152,6 +158,7 @@ signing_key:
|
|
152
158
|
specification_version: 4
|
153
159
|
summary: Nit improves your git workflows.
|
154
160
|
test_files:
|
161
|
+
- test/commands_test.rb
|
155
162
|
- test/config_test.rb
|
156
163
|
- test/dummies/stage/.gitignore
|
157
164
|
- test/dummies/stage/brandnew.rb
|
data/lib/nit/ignore.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
module Nit
|
2
|
-
class Ignore < Status
|
3
|
-
def initialize(*)
|
4
|
-
super
|
5
|
-
@ignores = Files.new(@config.ignored_files)
|
6
|
-
end
|
7
|
-
attr_reader :ignores
|
8
|
-
|
9
|
-
private
|
10
|
-
def process(state, indexes)
|
11
|
-
return show if indexes.size == 0
|
12
|
-
|
13
|
-
file_list = state.files.evaluate(indexes).compact
|
14
|
-
|
15
|
-
@config.ignored_files=(@config.ignored_files + file_list)
|
16
|
-
end
|
17
|
-
|
18
|
-
def show
|
19
|
-
return if ignores.size == 0
|
20
|
-
|
21
|
-
output = "Ignored files:\n"
|
22
|
-
ignores.each { |f| output << "[#{ignores.index(f)}] #{f}\n" }
|
23
|
-
|
24
|
-
output
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class Unignore < Ignore
|
29
|
-
private
|
30
|
-
def process(state, indexes)
|
31
|
-
file_list = state.ignored.evaluate(indexes).compact
|
32
|
-
|
33
|
-
@config.ignored_files=(@config.ignored_files - file_list.map(&:to_s)) # FIXME: make this work with strings and File instances.
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/lib/nit/status.rb
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
module Nit
|
2
|
-
class Status
|
3
|
-
# Encapsulates the process of computing the file index from `git status`.
|
4
|
-
class State # DISCUSS: alternative names: Screen, ScreenState, FileIndexes?
|
5
|
-
# TODO: test me.
|
6
|
-
def initialize(screen_state, config)
|
7
|
-
@screen = Lines.new(screen_state)
|
8
|
-
|
9
|
-
@files, @ignored = files_for(screen, config)
|
10
|
-
end
|
11
|
-
attr_reader :files, :ignored, :screen
|
12
|
-
|
13
|
-
private
|
14
|
-
def files_for(screen, config)
|
15
|
-
files = screen.files
|
16
|
-
|
17
|
-
ignored = [] # TODO: that must be implemented by Files.
|
18
|
-
files.delete_if { |f| config.ignored_files.include?(f.path) ? ignored << f : false }
|
19
|
-
|
20
|
-
[Files.new(files, config.indexer), Files.new(ignored, config.indexer)]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
def initialize(config)
|
26
|
-
@config = config
|
27
|
-
extend config.index_renderer
|
28
|
-
end
|
29
|
-
|
30
|
-
def call(original=`git status`, *args)
|
31
|
-
state = State.new(original, @config)
|
32
|
-
|
33
|
-
process(state, *args)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
def process(state)
|
38
|
-
files, screen, ignored = state.files, state.screen, state.ignored
|
39
|
-
|
40
|
-
files.each do |file| # TODO: should we have redundant file patterns here? it is better readable, thou.
|
41
|
-
ln = file.line
|
42
|
-
i = files.index(file)
|
43
|
-
|
44
|
-
if ln.match(screen.file_patterns[:modified])
|
45
|
-
process_modified(i, file, ln)
|
46
|
-
elsif ln.match(screen.file_patterns[:new])
|
47
|
-
process_new(i, file, ln)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# TODO: should be pluggable:
|
52
|
-
ignore_files(screen, ignored)
|
53
|
-
bold_branch(screen)
|
54
|
-
|
55
|
-
screen.to_s
|
56
|
-
end
|
57
|
-
|
58
|
-
module AppendIndexRenderer
|
59
|
-
def process_modified(i, file, line)
|
60
|
-
line << " [#{i}]"
|
61
|
-
end
|
62
|
-
|
63
|
-
def process_new(*args)
|
64
|
-
process_modified(*args)
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
module PrependIndexRenderer
|
69
|
-
def process_modified(i, file, line)
|
70
|
-
line.sub!("#\tmodified:", "#\tmodified: [#{i}] ")
|
71
|
-
end
|
72
|
-
|
73
|
-
def process_new(i, file, line)
|
74
|
-
line.sub!("#\t", "#\t [#{i}] ")
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
|
79
|
-
def bold_branch(lines)
|
80
|
-
lines.find(/# On branch (.+)/) do |ln, matches|
|
81
|
-
line = "# On branch \033[1m#{matches[1]}\033[22m"
|
82
|
-
ln.replace(line)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def ignore_files(screen, ignored)
|
87
|
-
return unless ignored.size > 0
|
88
|
-
|
89
|
-
ignored.each { |f| f.line.delete }
|
90
|
-
screen << "#"
|
91
|
-
screen << "# Ignored files: #{ignored.size}"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|