git-blame-game 0.0.1

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/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ .idea
6
+ test/fixtures/sample_git_repo
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use ruby-1.9.3
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'rake'
4
+
5
+ # Specify your gem's dependencies in git-blame-game.gemspec
6
+ gemspec
data/README.md ADDED
@@ -0,0 +1,136 @@
1
+ # git-blame-game
2
+
3
+ <img src="https://github.com/charleseff/git-blame-game/raw/master/public/pensive-kanye.png" />
4
+
5
+ git-blame-game is an interactive command-line tool for chaining 'git blame' calls to drill-down to the real culprit for the line of code you care about. When one `git blame` does not tell the whole story.
6
+
7
+ ## Installation:
8
+
9
+ gem install git-blame-game
10
+
11
+ ## Usage:
12
+
13
+ git-blame-game --help
14
+
15
+ ## Example:
16
+
17
+ $ git-blame-game add.rb
18
+
19
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 1) module Add
20
+ 5087eab5 (Danny Dover 2012-01-14 14:50:06 -0800 2) def add_4(y)
21
+ 5087eab5 (Danny Dover 2012-01-14 14:50:06 -0800 3) y + 5
22
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 4) end
23
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 5) end
24
+
25
+ Which line are you concerned with? (1 to 5) > 3
26
+
27
+ commit 5087eab56af9b0901a1b190de14f29867307c140 (HEAD, master)
28
+ Author: Danny Dover <developers+danny@foo.com>
29
+ Date: Sat Jan 14 14:50:06 2012 -0800
30
+
31
+ I like y's better
32
+
33
+ diff --git a/add.rb b/add.rb
34
+ index 44be98f..898a812 100644
35
+ --- a/add.rb
36
+ +++ b/add.rb
37
+ @@ -1,5 +1,5 @@
38
+ module Add
39
+ - def add_4(x)
40
+ - x + 5
41
+ + def add_4(y)
42
+ + y + 5
43
+ end
44
+ end
45
+
46
+
47
+ Do you need to git blame chain further (y/n) > y
48
+
49
+ 1) add.rb
50
+
51
+ Enter the number (from 1 to 1) of the file to git blame chain into > 1
52
+
53
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 1) module Add
54
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 2) def add_4(x)
55
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 3) x + 5
56
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 4) end
57
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 5) end
58
+
59
+ Which line are you concerned with? (1 to 5) > 3
60
+
61
+ commit de2a1d78f80e02a515cdd3aa0420dd6ee35b510b
62
+ Author: Carmen Cummings <developers+carmen@foo.com>
63
+ Date: Sat Jan 14 14:49:00 2012 -0800
64
+
65
+ moving add_4 to module
66
+
67
+ diff --git a/add.rb b/add.rb
68
+ new file mode 100644
69
+ index 0000000..44be98f
70
+ --- /dev/null
71
+ +++ b/add.rb
72
+ @@ -0,0 +1,5 @@
73
+ +module Add
74
+ + def add_4(x)
75
+ + x + 5
76
+ + end
77
+ +end
78
+
79
+ diff --git a/blah.rb b/blah.rb
80
+ index 0424947..38b7511 100644
81
+ --- a/blah.rb
82
+ +++ b/blah.rb
83
+ @@ -1,5 +1,5 @@
84
+ -def add_4(x)
85
+ - x + 5
86
+ -end
87
+ +$:.unshift(File.dirname(__FILE__))
88
+ +require 'add'
89
+ +include Add
90
+
91
+ puts add_4(9) # should be 13
92
+
93
+
94
+ Do you need to git blame chain further (y/n) > y
95
+
96
+ 1) add.rb
97
+ 2) blah.rb
98
+
99
+ Enter the number (from 1 to 2) of the file to git blame chain into > 2
100
+
101
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 1) def add_4(x)
102
+ 63b41ee4 (Bob Barker 2012-01-14 14:46:53 -0800 2) x + 5
103
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 3) end
104
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 4)
105
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 5) puts add_4(9) # should be 13
106
+
107
+ Which line are you concerned with? (1 to 5) > 2
108
+
109
+ commit 63b41ee41653991aa00ce9687e3f403efd4c29d4
110
+ Author: Bob Barker <developers+bob@foo.com>
111
+ Date: Sat Jan 14 14:46:53 2012 -0800
112
+
113
+ being bad
114
+
115
+ diff --git a/blah.rb b/blah.rb
116
+ index 626a42b..0424947 100644
117
+ --- a/blah.rb
118
+ +++ b/blah.rb
119
+ @@ -1,5 +1,5 @@
120
+ def add_4(x)
121
+ - x + 4
122
+ + x + 5
123
+ end
124
+
125
+ puts add_4(9) # should be 13
126
+
127
+
128
+ Do you need to git blame chain further (y/n) > n
129
+
130
+ The responsible commit is:
131
+
132
+ commit 63b41ee41653991aa00ce9687e3f403efd4c29d4
133
+ Author: Bob Barker <developers+bob@foo.com>
134
+ Date: Sat Jan 14 14:46:53 2012 -0800
135
+
136
+ being bad
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
3
+
4
+ require "rubygems"
5
+ require 'colorize'
6
+ require 'optparse'
7
+ require 'git-blame-game/git_blame_game'
8
+
9
+ options = {}
10
+ OptionParser.new do |opts|
11
+ opts.banner = <<-END.gsub(/^[ \t]+/m, '')
12
+ Usage: git-blame-game [options] path/to/filename
13
+ END
14
+
15
+ opts.separator ""
16
+ opts.separator "Options:"
17
+
18
+ opts.on("-s", "--sha", "--SHA [SHA]", String, "Set initial SHA (defaults to HEAD)") do |sha|
19
+ options[:sha] = sha
20
+ end
21
+
22
+ opts.on_tail("-h", "--help", "Show this message") do
23
+ puts opts
24
+ exit
25
+ end
26
+
27
+ end.parse!
28
+
29
+ path_to_file = ARGV[0]
30
+ raise OptionParser::MissingArgument.new("You must specify a path to a file ") if not path_to_file
31
+
32
+ GitBlameGame.new(path_to_file, options).run
@@ -0,0 +1,195 @@
1
+ Feature: Blaming
2
+
3
+ Scenario: Getting help
4
+ When I run `bin/git-blame-game --help`
5
+ Then it should pass with:
6
+ """
7
+ Usage: git-blame-game [options] path/to/filename
8
+ """
9
+
10
+ Scenario: Without a filepath:
11
+ When I run `bin/git-blame-game`
12
+ Then it should fail with:
13
+ """
14
+ missing argument: You must specify a path to a file
15
+ """
16
+
17
+ Scenario: Specifying a file that doesn't exist:
18
+ When I run `bin/git-blame-game file/that/doesnt/exist.rb`
19
+ Then it should fail with:
20
+ """
21
+ fatal: no such path file/that/doesnt/exist.rb in HEAD
22
+ """
23
+
24
+ Scenario: Without a SHA:
25
+ Given I cd to "test/fixtures/sample_git_repo"
26
+ When I run `../../../bin/git-blame-game add.rb` interactively
27
+ When I type "foobar"
28
+ When I type "3"
29
+ When I type "blah"
30
+ When I type "y"
31
+ When I type "1"
32
+ When I type "3"
33
+ When I type "y"
34
+ When I type "2"
35
+ When I type "2"
36
+ When I type "n"
37
+ Then the output should contain, ignoring spaces:
38
+ """
39
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 1) module Add
40
+ 5087eab5 (Danny Dover 2012-01-14 14:50:06 -0800 2) def add_4(y)
41
+ 5087eab5 (Danny Dover 2012-01-14 14:50:06 -0800 3) y + 5
42
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 4) end
43
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 5) end
44
+
45
+ Which line are you concerned with? (1 to 5) >
46
+ Invalid input. Enter a number from 1 to 5 >
47
+ commit 5087eab56af9b0901a1b190de14f29867307c140 (HEAD, master)
48
+ Author: Danny Dover <developers+danny@foo.com>
49
+ Date: Sat Jan 14 14:50:06 2012 -0800
50
+
51
+ I like y's better
52
+
53
+ diff --git a/add.rb b/add.rb
54
+ index 44be98f..898a812 100644
55
+ --- a/add.rb
56
+ +++ b/add.rb
57
+ @@ -1,5 +1,5 @@
58
+ module Add
59
+ - def add_4(x)
60
+ - x + 5
61
+ + def add_4(y)
62
+ + y + 5
63
+ end
64
+ end
65
+
66
+
67
+ Do you need to git blame chain further (y/n) >
68
+ Invalid input. Enter y or n >
69
+ 1) add.rb
70
+
71
+ Enter the number (from 1 to 1) of the file to git blame chain into >
72
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 1) module Add
73
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 2) def add_4(x)
74
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 3) x + 5
75
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 4) end
76
+ de2a1d78 (Carmen Cummings 2012-01-14 14:49:00 -0800 5) end
77
+
78
+ Which line are you concerned with? (1 to 5) >
79
+ commit de2a1d78f80e02a515cdd3aa0420dd6ee35b510b
80
+ Author: Carmen Cummings <developers+carmen@foo.com>
81
+ Date: Sat Jan 14 14:49:00 2012 -0800
82
+
83
+ moving add_4 to module
84
+
85
+ diff --git a/add.rb b/add.rb
86
+ new file mode 100644
87
+ index 0000000..44be98f
88
+ --- /dev/null
89
+ +++ b/add.rb
90
+ @@ -0,0 +1,5 @@
91
+ +module Add
92
+ + def add_4(x)
93
+ + x + 5
94
+ + end
95
+ +end
96
+
97
+ diff --git a/blah.rb b/blah.rb
98
+ index 0424947..38b7511 100644
99
+ --- a/blah.rb
100
+ +++ b/blah.rb
101
+ @@ -1,5 +1,5 @@
102
+ -def add_4(x)
103
+ - x + 5
104
+ -end
105
+ +$:.unshift(File.dirname(__FILE__))
106
+ +require 'add'
107
+ +include Add
108
+
109
+ puts add_4(9) # should be 13
110
+
111
+
112
+ Do you need to git blame chain further (y/n) >
113
+ 1) add.rb
114
+ 2) blah.rb
115
+
116
+ Enter the number (from 1 to 2) of the file to git blame chain into >
117
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 1) def add_4(x)
118
+ 63b41ee4 (Bob Barker 2012-01-14 14:46:53 -0800 2) x + 5
119
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 3) end
120
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 4)
121
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 5) puts add_4(9) # should be 13
122
+
123
+ Which line are you concerned with? (1 to 5) >
124
+ commit 63b41ee41653991aa00ce9687e3f403efd4c29d4
125
+ Author: Bob Barker <developers+bob@foo.com>
126
+ Date: Sat Jan 14 14:46:53 2012 -0800
127
+
128
+ being bad
129
+
130
+ diff --git a/blah.rb b/blah.rb
131
+ index 626a42b..0424947 100644
132
+ --- a/blah.rb
133
+ +++ b/blah.rb
134
+ @@ -1,5 +1,5 @@
135
+ def add_4(x)
136
+ - x + 4
137
+ + x + 5
138
+ end
139
+
140
+ puts add_4(9) # should be 13
141
+
142
+
143
+ Do you need to git blame chain further (y/n) >
144
+ The responsible commit is:
145
+
146
+ commit 63b41ee41653991aa00ce9687e3f403efd4c29d4
147
+ Author: Bob Barker <developers+bob@foo.com>
148
+ Date: Sat Jan 14 14:46:53 2012 -0800
149
+
150
+ being bad
151
+
152
+ """
153
+
154
+ Scenario: With a SHA:
155
+ Given I cd to "test/fixtures/sample_git_repo"
156
+ When I run `../../../bin/git-blame-game blah.rb --sha=63b41ee41653991aa00ce9687e3f403efd4c29d4` interactively
157
+ When I type "2"
158
+ When I type "n"
159
+ Then the output should contain, ignoring spaces:
160
+ """
161
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 1) def add_4(x)
162
+ 63b41ee4 (Bob Barker 2012-01-14 14:46:53 -0800 2) x + 5
163
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 3) end
164
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 4)
165
+ ^f603a9a (Alice Amos 2012-01-14 14:46:18 -0800 5) puts add_4(9) # should be 13
166
+
167
+ Which line are you concerned with? (1 to 5) >
168
+ commit 63b41ee41653991aa00ce9687e3f403efd4c29d4
169
+ Author: Bob Barker <developers+bob@foo.com>
170
+ Date: Sat Jan 14 14:46:53 2012 -0800
171
+
172
+ being bad
173
+
174
+ diff --git a/blah.rb b/blah.rb
175
+ index 626a42b..0424947 100644
176
+ --- a/blah.rb
177
+ +++ b/blah.rb
178
+ @@ -1,5 +1,5 @@
179
+ def add_4(x)
180
+ - x + 4
181
+ + x + 5
182
+ end
183
+
184
+ puts add_4(9) # should be 13
185
+
186
+
187
+ Do you need to git blame chain further (y/n) >
188
+ The responsible commit is:
189
+
190
+ commit 63b41ee41653991aa00ce9687e3f403efd4c29d4
191
+ Author: Bob Barker <developers+bob@foo.com>
192
+ Date: Sat Jan 14 14:46:53 2012 -0800
193
+
194
+ being bad
195
+ """
@@ -0,0 +1,3 @@
1
+ Then /^the output should contain, ignoring spaces:$/ do |expected|
2
+ assert_partial_output(expected.gsub("\s",''), all_output.gsub("\s",''))
3
+ end
@@ -0,0 +1,20 @@
1
+ require 'aruba/cucumber'
2
+
3
+ def unzip_git_repo_if_needed!
4
+ fixtures_dir = File.expand_path(File.dirname(__FILE__)) + '/../../test/fixtures'
5
+ unless File.directory? fixtures_dir + '/sample_git_repo'
6
+ `unzip #{fixtures_dir}/sample_git_repo.zip -d #{fixtures_dir}`
7
+ end
8
+ end
9
+
10
+ # for some reason Aruba sets the default dir to 'tmp/aruba'. Override this:
11
+ def set_relative_dir_for_aruba!
12
+ root_dir = File.expand_path("../../../", __FILE__)
13
+ self.instance_variable_set('@dirs', [root_dir])
14
+ end
15
+
16
+ Before do
17
+ unzip_git_repo_if_needed!
18
+
19
+ set_relative_dir_for_aruba!
20
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "git-blame-game/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "git-blame-game"
7
+ s.version = Git::Blame::Game::VERSION
8
+ s.authors = ["Charles Finkel"]
9
+ s.email = ["charles.finkel@gmail.com"]
10
+ s.homepage = "https://github.com/charleseff/git-blame-game"
11
+ s.summary = %q{git-blame-game is an interactive command for chaining 'git blame' calls to get to the real culprit for the line of code you care about, when one `git blame` does not tell the whole story.}
12
+ s.description = %q{When one `git blame` is not enough}
13
+
14
+ s.rubyforge_project = "git-blame-game"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_development_dependency 'aruba'
22
+ s.add_runtime_dependency 'colorize'
23
+ end
@@ -0,0 +1,80 @@
1
+ class GitBlameGame
2
+ def initialize(path_to_file, opts={})
3
+ @path_to_file = path_to_file
4
+ @sha = !opts[:sha].nil? ? opts[:sha] : 'HEAD'
5
+ end
6
+
7
+ def run
8
+ while loop;
9
+ end
10
+ end
11
+
12
+ GIT_BLAME_REGEX = /(.+?) /
13
+
14
+ def loop
15
+ puts
16
+ out = run_idempotent_git_command("git blame #{@sha} -- #{@path_to_file}")
17
+ exit $?.exitstatus unless $?.success?
18
+
19
+ lines = out.split("\n")
20
+ count = lines.count
21
+
22
+ line = prompt_for_line(count)
23
+ sha_to_show = lines[line-1][GIT_BLAME_REGEX, 1]
24
+
25
+ puts
26
+ system "git show #{sha_to_show}"
27
+ files_changed = `git show --pretty="format:" --name-only #{sha_to_show}`.split("\n")[1..-1]
28
+
29
+ @path_to_file = prompt_for_file(files_changed,sha_to_show)
30
+ @sha = "#{sha_to_show}^"
31
+
32
+ true
33
+ end
34
+
35
+ def prompt_for_file(files_changed,sha)
36
+ print "\n" + gbc_color("Do you need to git blame chain further (y/n) >") + ' '
37
+ input = $stdin.gets.strip.downcase
38
+ until %w{y n}.include?(input)
39
+ print "\n" + gbc_color("Invalid input. Enter y or n >") + ' '
40
+ input = $stdin.gets.strip.downcase
41
+ end
42
+
43
+ if input == 'n'
44
+ print "\n" + gbc_color("The responsible commit is:") + "\n\n"
45
+ system "git log #{sha} -n 1"
46
+ exit 0
47
+ end
48
+
49
+ puts
50
+ files_changed.each_with_index do |file,index|
51
+ "%-10s %-12s %-15s %-48s %-s\n"
52
+ printf("%3d) #{file}\n", index+1)
53
+ end
54
+
55
+ print "\n" + gbc_color("Enter the number (from 1 to #{files_changed.size}) of the file to git blame chain into >") + ' '
56
+ until (input = $stdin.gets.strip.to_i) >= 1 && input <= files_changed.size
57
+ print "\n" + gbc_color("Invalid input. Enter a number from 1 to #{files_changed.size} >") + ' '
58
+ end
59
+
60
+ return files_changed[input-1]
61
+
62
+ end
63
+
64
+ def prompt_for_line(count)
65
+ print "\n" + gbc_color("Which line are you concerned with? (1 to #{count}) >") + ' '
66
+ until (input = $stdin.gets.strip.to_i) >= 1 && input <= count
67
+ print "\n" + gbc_color("Invalid input. Enter a number from 1 to #{count} >") + ' '
68
+ end
69
+ input
70
+ end
71
+
72
+ def run_idempotent_git_command(cmd)
73
+ system cmd
74
+ `#{cmd}`
75
+ end
76
+
77
+ def gbc_color(s)
78
+ s.colorize(:color => :light_white, :background => :magenta)
79
+ end
80
+ end
@@ -0,0 +1,7 @@
1
+ module Git
2
+ module Blame
3
+ module Game
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ # Load nothing - just keep the file here to keep bundler happy.
2
+
Binary file
Binary file
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-blame-game
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Charles Finkel
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-01-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aruba
16
+ requirement: &18572720 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *18572720
25
+ - !ruby/object:Gem::Dependency
26
+ name: colorize
27
+ requirement: &18572180 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *18572180
36
+ description: When one `git blame` is not enough
37
+ email:
38
+ - charles.finkel@gmail.com
39
+ executables:
40
+ - git-blame-game
41
+ extensions: []
42
+ extra_rdoc_files: []
43
+ files:
44
+ - .gitignore
45
+ - .rvmrc
46
+ - Gemfile
47
+ - README.md
48
+ - Rakefile
49
+ - bin/git-blame-game
50
+ - features/blaming.feature
51
+ - features/step_definitions/gbc_steps.rb
52
+ - features/support/env.rb
53
+ - git-blame-game.gemspec
54
+ - lib/git-blame-game.rb
55
+ - lib/git-blame-game/git_blame_game.rb
56
+ - lib/git-blame-game/version.rb
57
+ - public/pensive-kanye.png
58
+ - test/fixtures/sample_git_repo.zip
59
+ homepage: https://github.com/charleseff/git-blame-game
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project: git-blame-game
79
+ rubygems_version: 1.8.10
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: git-blame-game is an interactive command for chaining 'git blame' calls to
83
+ get to the real culprit for the line of code you care about, when one `git blame`
84
+ does not tell the whole story.
85
+ test_files: []