githug 0.3.2 → 0.3.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/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.
|