githug 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -12
- data/levels/bisect.rb +1 -1
- data/levels/checkout_tag_over_branch.rb +46 -0
- data/levels/contribute.rb +1 -1
- data/levels/log.rb +2 -2
- data/levels/push_tags.rb +63 -0
- data/levels/rename_commit.rb +1 -1
- data/levels/repack.rb +19 -0
- data/levels/rm_cached.rb +1 -1
- data/lib/githug/level.rb +5 -4
- data/lib/githug/version.rb +1 -1
- data/spec/githug/game_spec.rb +40 -40
- data/spec/githug_spec.rb +15 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e9bf4cc4edb1340324308e6962db57c4f3d3d15
|
4
|
+
data.tar.gz: 88179cc894098286f09d5c0e9f4abedab122c7ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b799abc8c24919db796761438a082c5c71698a5bce8e382795fd67a3864bcad2b1822f1f9b394d39b3655348cdf60a862b4f7679a63ec2b04df5ea73e80d561
|
7
|
+
data.tar.gz: eed02fe344c91defe7f5406733cd4ee6f4fb7930eb43d1d5dfde91af9e3fd981138a293236e860d13c82bcb67fde40f6962fa671851d7c94ca86d66fbf5f87dd
|
data/README.md
CHANGED
@@ -61,6 +61,7 @@ end
|
|
61
61
|
solution do
|
62
62
|
return false unless repo.status.files.keys.include?("README")
|
63
63
|
return false if repo.status.files["README"].untracked
|
64
|
+
|
64
65
|
true
|
65
66
|
end
|
66
67
|
|
@@ -79,16 +80,6 @@ hints [
|
|
79
80
|
"Check the man for `git add`"]
|
80
81
|
```
|
81
82
|
|
82
|
-
**note** Because `solution` is a Proc, you cannot prematurely return out of it and as a result, must put an explicit return on the last line of the solution block.
|
83
|
-
|
84
|
-
```ruby
|
85
|
-
solution do
|
86
|
-
solved = false
|
87
|
-
solved = true if repo.valid?
|
88
|
-
solved
|
89
|
-
end
|
90
|
-
```
|
91
|
-
|
92
83
|
By default, `setup` will remove all files from the game folder. You do not need to include a setup method if you don't want an initial git repository (if you are testing `git init` or only checking an answer.)
|
93
84
|
|
94
85
|
You can call `repo.init` to initialize an empty repository.
|
@@ -121,9 +112,9 @@ After doing this, your level should be able to copy the contents from that git r
|
|
121
112
|
The easiest way to test a level is:
|
122
113
|
|
123
114
|
* change into your git_hug repository
|
124
|
-
* Run `githug reset PATH_TO_YOUR_LEVEL
|
115
|
+
* Run `githug reset PATH_TO_YOUR_LEVEL`
|
125
116
|
* Solve the level
|
126
|
-
* Run `githug test PATH_TO_YOUR_LEVEL
|
117
|
+
* Run `githug test PATH_TO_YOUR_LEVEL`
|
127
118
|
|
128
119
|
Please note that the `githug test` command can be run as `githug test --errors` to get an error stacktrace from your solve method.
|
129
120
|
|
data/levels/bisect.rb
CHANGED
@@ -7,7 +7,7 @@ setup do
|
|
7
7
|
end
|
8
8
|
|
9
9
|
solution do
|
10
|
-
"18ed2ac" == request("What are the first 7 characters of the hash of the commit that introduced the bug?")
|
10
|
+
"18ed2ac" == request("What are the first 7 characters of the hash of the commit that introduced the bug?")[0..6]
|
11
11
|
end
|
12
12
|
|
13
13
|
hint do
|
@@ -0,0 +1,46 @@
|
|
1
|
+
difficulty 2
|
2
|
+
|
3
|
+
description "You need to fix a bug in the version 1.2 of your app. Checkout the tag v1.2 (Note: There is also a branch named v1.2)"
|
4
|
+
|
5
|
+
setup do
|
6
|
+
repo.init
|
7
|
+
FileUtils.touch("app.rb")
|
8
|
+
repo.add("app.rb")
|
9
|
+
repo.commit_all("Initial commit")
|
10
|
+
|
11
|
+
`echo "Some code" >> app.rb`
|
12
|
+
repo.add("app.rb")
|
13
|
+
repo.commit_all("Some changes")
|
14
|
+
repo.git.tag( { 'f' => true }, "v1.0" )
|
15
|
+
|
16
|
+
`echo "Buggy code" >> app.rb`
|
17
|
+
repo.add("app.rb")
|
18
|
+
repo.commit_all("Some more changes")
|
19
|
+
repo.git.tag( { 'f' => true }, "v1.2" )
|
20
|
+
|
21
|
+
`echo "More code" >> app.rb`
|
22
|
+
repo.add("app.rb")
|
23
|
+
repo.commit_all("Yet more changes")
|
24
|
+
|
25
|
+
`echo "Some more code" >> app.rb`
|
26
|
+
repo.add("app.rb")
|
27
|
+
repo.commit_all("Changes galore")
|
28
|
+
repo.git.tag( { 'f' => true }, "v1.5" )
|
29
|
+
|
30
|
+
repo.git.native :checkout, {"b" => true}, 'v1.2'
|
31
|
+
File.open("file3", 'w') { |f| f << "some feature\n" }
|
32
|
+
repo.add "file3"
|
33
|
+
repo.commit_all "Developing new features"
|
34
|
+
|
35
|
+
repo.git.native :checkout, {}, 'master'
|
36
|
+
end
|
37
|
+
|
38
|
+
solution do
|
39
|
+
return false unless repo.commits.length == 5
|
40
|
+
return false unless `git show HEAD` =~ /Some more changes/
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
hint do
|
45
|
+
puts "You should think about specifying you're after the tag named v1.2 (think tags/)"
|
46
|
+
end
|
data/levels/contribute.rb
CHANGED
data/levels/log.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
difficulty 2
|
2
2
|
|
3
|
-
description "You will be asked for the
|
3
|
+
description "You will be asked for the hash of most recent commit. You will need to investigate the logs of the repository for this."
|
4
4
|
|
5
5
|
setup do
|
6
6
|
repo.init
|
@@ -10,7 +10,7 @@ setup do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
solution do
|
13
|
-
repo.commits.last.id_abbrev == request("What
|
13
|
+
repo.commits.last.id_abbrev == request("What is the hash of the most recent commit?")[0..6]
|
14
14
|
end
|
15
15
|
|
16
16
|
hint do
|
data/levels/push_tags.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
difficulty 2
|
2
|
+
description "There are tags in the repository that aren't pushed into remote repository. Push them now."
|
3
|
+
|
4
|
+
setup do
|
5
|
+
# remember the working directory so we can come back to it later
|
6
|
+
cwd = Dir.pwd
|
7
|
+
# initialize another git repo to be used as a "remote"
|
8
|
+
tmpdir = Dir.mktmpdir
|
9
|
+
|
10
|
+
# local repo
|
11
|
+
repo.init
|
12
|
+
|
13
|
+
FileUtils.touch "file1"
|
14
|
+
repo.add "file1"
|
15
|
+
repo.commit_all "First commit"
|
16
|
+
repo.git.tag({'f' => true}, "tag_to_be_pushed")
|
17
|
+
|
18
|
+
FileUtils.touch "file2"
|
19
|
+
repo.add "file2"
|
20
|
+
repo.commit_all "Second commit"
|
21
|
+
|
22
|
+
# copy the repo to remote
|
23
|
+
FileUtils.cp_r ".", tmpdir
|
24
|
+
|
25
|
+
# remote repo
|
26
|
+
Dir.chdir tmpdir
|
27
|
+
repo.init
|
28
|
+
# make a 'non-bare' repo accept pushes
|
29
|
+
`git config receive.denyCurrentBranch ignore`
|
30
|
+
|
31
|
+
# change back to original repo to set up a remote
|
32
|
+
Dir.chdir cwd
|
33
|
+
`git remote add origin #{tmpdir}/.git`
|
34
|
+
`git fetch origin`
|
35
|
+
|
36
|
+
# delete tags from remote
|
37
|
+
Dir.chdir tmpdir
|
38
|
+
repo.git.tag({'d' => true}, "tag_to_be_pushed")
|
39
|
+
|
40
|
+
# change back to local repo
|
41
|
+
Dir.chdir cwd
|
42
|
+
end
|
43
|
+
|
44
|
+
solution do
|
45
|
+
solved = false
|
46
|
+
|
47
|
+
# a bit hacky solution to get tags from remote
|
48
|
+
remote_tags=
|
49
|
+
repo.git.raw_git_call("git ls-remote --tags -q", repo.git.git_file_index).
|
50
|
+
first.
|
51
|
+
split("\n")
|
52
|
+
|
53
|
+
# see if we have the correct tag in the remote
|
54
|
+
remote_tags.each do |t|
|
55
|
+
solved=true if t.include?("refs/tags/tag_to_be_pushed")
|
56
|
+
end
|
57
|
+
|
58
|
+
solved
|
59
|
+
end
|
60
|
+
|
61
|
+
hint do
|
62
|
+
puts "Take a look at '--tags' flag of 'git push'"
|
63
|
+
end
|
data/levels/rename_commit.rb
CHANGED
data/levels/repack.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
difficulty 2
|
2
|
+
description "Optimise how your repository is packaged ensuring that redundant packs are removed"
|
3
|
+
|
4
|
+
setup do
|
5
|
+
repo.init
|
6
|
+
FileUtils.touch("foo")
|
7
|
+
repo.add("foo")
|
8
|
+
repo.commit_all("Added foo")
|
9
|
+
end
|
10
|
+
|
11
|
+
solution do
|
12
|
+
result = `git count-objects -v`
|
13
|
+
required = ["count: 0", "prune-packable: 0"];
|
14
|
+
required.all? { |r| result.include?(r) }
|
15
|
+
end
|
16
|
+
|
17
|
+
hint do
|
18
|
+
puts "You want to research the `git repack` command"
|
19
|
+
end
|
data/levels/rm_cached.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
difficulty 2
|
2
2
|
|
3
|
-
description "A file
|
3
|
+
description "A file has accidentally been added to your staging area, find out which file and remove it from the staging area. *NOTE* Do not remove the file from the file system, only from git."
|
4
4
|
|
5
5
|
setup do
|
6
6
|
repo.init
|
data/lib/githug/level.rb
CHANGED
@@ -4,10 +4,10 @@ module Githug
|
|
4
4
|
|
5
5
|
LEVELS = [nil, "init", "add", "commit", "config", "clone",
|
6
6
|
"clone_to_folder", "ignore", "status", "rm", "rm_cached",
|
7
|
-
"stash", "rename", "log", "tag",
|
7
|
+
"stash", "rename", "log", "tag", "push_tags", "commit_amend", "reset",
|
8
8
|
"reset_soft", "checkout_file", "remote", "remote_url", "pull",
|
9
9
|
"remote_add", "push", "diff", "blame", "branch", "checkout",
|
10
|
-
"checkout_tag", "branch_at", "merge", "cherry-pick",
|
10
|
+
"checkout_tag", "checkout_tag_over_branch", "branch_at", "merge", "repack", "cherry-pick",
|
11
11
|
"rename_commit", "squash", "merge_squash", "reorder", "bisect",
|
12
12
|
"stage_lines", "find_old_branch", "revert", "restore",
|
13
13
|
"conflict", "contribute"]
|
@@ -55,7 +55,8 @@ module Githug
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def solution(&block)
|
58
|
-
|
58
|
+
singleton = class << self; self end
|
59
|
+
singleton.send :define_method, :_solution, &block
|
59
60
|
end
|
60
61
|
|
61
62
|
def setup(&block)
|
@@ -89,7 +90,7 @@ module Githug
|
|
89
90
|
end
|
90
91
|
|
91
92
|
def solve
|
92
|
-
|
93
|
+
_solution
|
93
94
|
rescue
|
94
95
|
false
|
95
96
|
end
|
data/lib/githug/version.rb
CHANGED
data/spec/githug/game_spec.rb
CHANGED
@@ -2,61 +2,61 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Githug::Game do
|
4
4
|
|
5
|
+
let(:profile) { mock(:level => 1,
|
6
|
+
:current_attempts => 0).as_null_object }
|
7
|
+
let(:game) { Githug::Game.new }
|
8
|
+
let(:level) { mock(:full_description => nil, :setup_level => nil) }
|
9
|
+
|
5
10
|
before(:each) do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@profile.stub(:save)
|
11
|
-
@profile.stub(:level_bump)
|
12
|
-
@profile.stub(:current_attempts).and_return(0)
|
13
|
-
@level = mock
|
14
|
-
@level.stub(:full_description)
|
15
|
-
@level.stub(:setup_level)
|
11
|
+
Githug::Profile.stub(:new).and_return(profile)
|
12
|
+
profile.stub(:save)
|
13
|
+
profile.stub(:level_bump)
|
14
|
+
|
16
15
|
Githug::UI.stub(:puts)
|
17
|
-
|
16
|
+
|
17
|
+
Githug::Level.stub(:load).and_return(level)
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should have a profile" do
|
21
|
-
|
21
|
+
game.profile.should eql(profile)
|
22
22
|
end
|
23
23
|
|
24
24
|
it "should show a description if the level is 0" do
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
level.should_not_receive(:solve)
|
26
|
+
profile.stub(:level).and_return(nil)
|
27
|
+
profile.should_receive(:level_bump)
|
28
28
|
Githug::UI.should_receive(:puts).with("Welcome to Githug")
|
29
|
-
|
29
|
+
game.play_level
|
30
30
|
end
|
31
31
|
|
32
32
|
describe "play_level" do
|
33
33
|
|
34
34
|
it "should echo congratulations if the level is solved" do
|
35
|
-
|
36
|
-
|
35
|
+
level.stub(:solve).and_return(true)
|
36
|
+
profile.should_receive(:level_bump)
|
37
37
|
Githug::UI.should_receive(:success).with("Congratulations, you have solved the level")
|
38
|
-
|
38
|
+
game.play_level
|
39
39
|
end
|
40
40
|
|
41
41
|
it "should echo the solution is not right" do
|
42
|
-
|
42
|
+
level.stub(:solve).and_return(false)
|
43
43
|
Githug::UI.should_receive(:error).with("Sorry, this solution is not quite right!")
|
44
|
-
|
44
|
+
game.play_level
|
45
45
|
end
|
46
46
|
|
47
47
|
it "should increment the number of failed attempts" do
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
level.stub(:solve).and_return(false)
|
49
|
+
profile.should_receive(:current_attempts=).with(1)
|
50
|
+
profile.should_receive(:save)
|
51
|
+
game.play_level
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should prompt for a hint if the user has failed 3 times." do
|
55
|
-
|
56
|
-
|
55
|
+
profile.stub(:current_attempts).and_return(3)
|
56
|
+
level.stub(:solve).and_return(false)
|
57
57
|
Githug::UI.should_receive(:error).with("Sorry, this solution is not quite right!")
|
58
58
|
Githug::UI.should_receive(:error).with("Don't forget you can type `githug hint` for a hint and `githug reset` to reset the current level")
|
59
|
-
|
59
|
+
game.play_level
|
60
60
|
end
|
61
61
|
|
62
62
|
end
|
@@ -64,33 +64,33 @@ describe Githug::Game do
|
|
64
64
|
|
65
65
|
describe "test_level" do
|
66
66
|
it "Should output Valid solution if the solution is valid" do
|
67
|
-
|
67
|
+
level.stub(:solve).and_return(true)
|
68
68
|
Githug::UI.should_receive(:success).with("Valid solution")
|
69
|
-
|
69
|
+
game.test_level(level)
|
70
70
|
end
|
71
71
|
|
72
72
|
it "Should output Invalid solution if the solution is invalid" do
|
73
|
-
|
73
|
+
level.stub(:solve).and_return(false)
|
74
74
|
Githug::UI.should_receive(:error).with("Invalid solution")
|
75
|
-
|
75
|
+
game.test_level(level)
|
76
76
|
end
|
77
77
|
|
78
78
|
it "should call test when errors is true" do
|
79
|
-
|
80
|
-
|
79
|
+
level.should_receive(:test)
|
80
|
+
game.test_level(level, true)
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
84
|
it "should output the description of the next level" do
|
85
|
-
|
86
|
-
|
87
|
-
|
85
|
+
level.should_receive(:full_description)
|
86
|
+
profile.stub(:level=)
|
87
|
+
game.level_bump
|
88
88
|
end
|
89
89
|
|
90
90
|
it "should call setup_level for the next level" do
|
91
|
-
|
92
|
-
|
93
|
-
|
91
|
+
level.should_receive(:setup_level)
|
92
|
+
profile.stub(:level=)
|
93
|
+
game.level_bump
|
94
94
|
end
|
95
95
|
|
96
96
|
end
|
data/spec/githug_spec.rb
CHANGED
@@ -104,6 +104,11 @@ describe "The Game" do
|
|
104
104
|
`githug`.should be_solved
|
105
105
|
end
|
106
106
|
|
107
|
+
it "should complete the push_tags level" do
|
108
|
+
`git push origin master --tags`
|
109
|
+
`githug`.should be_solved
|
110
|
+
end
|
111
|
+
|
107
112
|
it "should complete the commit_amend level" do
|
108
113
|
`git add forgotten_file.rb`
|
109
114
|
`git commit --amend -C HEAD`
|
@@ -172,6 +177,11 @@ describe "The Game" do
|
|
172
177
|
`githug`.should be_solved
|
173
178
|
end
|
174
179
|
|
180
|
+
it "should complete the checkout_tag_over_branch level" do
|
181
|
+
`git checkout tags/v1.2`
|
182
|
+
`githug`.should be_solved
|
183
|
+
end
|
184
|
+
|
175
185
|
it "should complete the branch_at level" do
|
176
186
|
commit = `git log HEAD~1 --pretty=short | head -1 | cut -d " " -f 2`
|
177
187
|
`git branch test_branch #{commit}`
|
@@ -183,6 +193,11 @@ describe "The Game" do
|
|
183
193
|
`githug`.should be_solved
|
184
194
|
end
|
185
195
|
|
196
|
+
it "should complete the repack level" do
|
197
|
+
`git repack -d`
|
198
|
+
`githug`.should be_solved
|
199
|
+
end
|
200
|
+
|
186
201
|
it "should complete the cherry-pick level" do
|
187
202
|
commit = `git log new-feature --oneline -n 3 | tail -1 | cut -d " " -f 1`
|
188
203
|
`git cherry-pick #{commit}`
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: githug
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gary Rennie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -154,6 +154,7 @@ files:
|
|
154
154
|
- levels/checkout.rb
|
155
155
|
- levels/checkout_file.rb
|
156
156
|
- levels/checkout_tag.rb
|
157
|
+
- levels/checkout_tag_over_branch.rb
|
157
158
|
- levels/cherry-pick.rb
|
158
159
|
- levels/cherry-pick/.githug/COMMIT_EDITMSG
|
159
160
|
- levels/cherry-pick/.githug/HEAD
|
@@ -337,12 +338,14 @@ files:
|
|
337
338
|
- levels/merge_squash.rb
|
338
339
|
- levels/pull.rb
|
339
340
|
- levels/push.rb
|
341
|
+
- levels/push_tags.rb
|
340
342
|
- levels/remote.rb
|
341
343
|
- levels/remote_add.rb
|
342
344
|
- levels/remote_url.rb
|
343
345
|
- levels/rename.rb
|
344
346
|
- levels/rename_commit.rb
|
345
347
|
- levels/reorder.rb
|
348
|
+
- levels/repack.rb
|
346
349
|
- levels/reset.rb
|
347
350
|
- levels/reset_soft.rb
|
348
351
|
- levels/restore.rb
|
@@ -412,7 +415,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
412
415
|
version: '0'
|
413
416
|
requirements: []
|
414
417
|
rubyforge_project: githug
|
415
|
-
rubygems_version: 2.0.
|
418
|
+
rubygems_version: 2.0.6
|
416
419
|
signing_key:
|
417
420
|
specification_version: 4
|
418
421
|
summary: An interactive way to learn git.
|