nit 0.0.2 → 0.0.3
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 +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
|