gitnesse 0.12.6 → 1.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.travis.yml +6 -0
- data/Rakefile +6 -11
- data/bin/.keep +0 -0
- data/bin/gitnesse +2 -32
- data/config/gitnesse.rb.example +2 -4
- data/gitnesse.gemspec +22 -21
- data/lib/gitnesse/cli/helpers/config_helpers.rb +13 -0
- data/lib/gitnesse/cli/helpers/feature_helpers.rb +26 -0
- data/lib/gitnesse/cli/helpers/wiki_helpers.rb +53 -0
- data/lib/gitnesse/cli/task/help.rb +42 -0
- data/lib/gitnesse/cli/task/info.rb +29 -0
- data/lib/gitnesse/cli/task/pull.rb +26 -0
- data/lib/gitnesse/cli/task/push.rb +101 -0
- data/lib/gitnesse/cli/task/run.rb +85 -0
- data/lib/gitnesse/cli/task.rb +67 -0
- data/lib/gitnesse/cli.rb +55 -0
- data/lib/gitnesse/config.rb +68 -0
- data/lib/gitnesse/config_loader.rb +36 -0
- data/lib/gitnesse/dependency_checker.rb +86 -0
- data/lib/gitnesse/dir_manager.rb +37 -0
- data/lib/gitnesse/feature.rb +63 -0
- data/lib/gitnesse/feature_extractor.rb +29 -0
- data/lib/gitnesse/feature_transform.rb +30 -0
- data/lib/gitnesse/hooks/gitnesse.rb +5 -0
- data/lib/gitnesse/hooks.rb +30 -33
- data/lib/gitnesse/railtie.rb +3 -1
- data/lib/gitnesse/rake/tasks.rake +11 -0
- data/lib/gitnesse/tasks.rb +7 -4
- data/lib/gitnesse/version.rb +1 -1
- data/lib/gitnesse/wiki/page.rb +103 -0
- data/lib/gitnesse/wiki.rb +80 -143
- data/lib/gitnesse.rb +10 -102
- data/spec/lib/cli/task/help_spec.rb +34 -0
- data/spec/lib/cli/task/info_spec.rb +22 -0
- data/spec/lib/cli/task/pull_spec.rb +24 -0
- data/spec/lib/cli/task/push_spec.rb +24 -0
- data/spec/lib/cli_spec.rb +13 -0
- data/spec/lib/config_loader_spec.rb +46 -0
- data/spec/lib/config_spec.rb +61 -0
- data/spec/lib/dependency_checker_spec.rb +193 -0
- data/spec/lib/dir_manager_spec.rb +46 -0
- data/spec/lib/feature_extractor_spec.rb +30 -0
- data/spec/lib/feature_spec.rb +53 -0
- data/spec/lib/feature_transform_spec.rb +25 -0
- data/spec/lib/hooks_spec.rb +40 -0
- data/spec/lib/version_spec.rb +9 -0
- data/spec/lib/wiki/page_spec.rb +68 -0
- data/spec/lib/wiki_spec.rb +34 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/cli.rb +20 -0
- data/spec/support/example_config/gitnesse.rb +4 -0
- data/{test/test_helper.rb → spec/support/example_features/addition.feature} +0 -16
- data/spec/support/example_features/division.feature +10 -0
- data/spec/support/example_wiki_pages/developer_can_sync_features_to_code.md +29 -0
- data/spec/support_helper.rb +79 -0
- metadata +103 -109
- data/README.md +0 -85
- data/features/step_definitions/gitnesse_steps.rb +0 -54
- data/features/support/env.rb +0 -65
- data/features/sync_wiki_features_to_code.feature +0 -29
- data/lib/gitnesse/configuration.rb +0 -54
- data/lib/gitnesse/dependencies.rb +0 -39
- data/lib/gitnesse/features.rb +0 -38
- data/lib/gitnesse/git_config.rb +0 -39
- data/lib/gitnesse/support/hook.rb +0 -11
- data/lib/gitnesse/tasks.rake +0 -34
- data/test/lib/gitnesse/build_page_content_test.rb +0 -89
- data/test/lib/gitnesse/commit_info_test.rb +0 -16
- data/test/lib/gitnesse/configuration_defaults_test.rb +0 -11
- data/test/lib/gitnesse/configuration_to_hash_test.rb +0 -25
- data/test/lib/gitnesse/custom_branch_test.rb +0 -24
- data/test/lib/gitnesse/dependencies_check_test.rb +0 -73
- data/test/lib/gitnesse/extract_features_test.rb +0 -44
- data/test/lib/gitnesse/gather_test.rb +0 -30
- data/test/lib/gitnesse/load_feature_files_into_wiki_test.rb +0 -34
- data/test/lib/gitnesse/read_git_config_test.rb +0 -33
- data/test/lib/gitnesse/strip_results_test.rb +0 -52
- data/test/lib/gitnesse/version_test.rb +0 -7
- data/test/lib/gitnesse/wiki_append_results_test.rb +0 -50
- data/test/lib/gitnesse/write_file_test.rb +0 -18
- data/test/wiki_test_helper.rb +0 -11
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
|
3
|
+
module Gitnesse
|
4
|
+
class Config
|
5
|
+
include Singleton
|
6
|
+
|
7
|
+
ConfigStruct = Struct.new :repository_url, :features_dir, :branch,
|
8
|
+
:annotate_results, :identifier
|
9
|
+
|
10
|
+
# Config Options:
|
11
|
+
#
|
12
|
+
# repository_url - URl to remote git-based wiki.
|
13
|
+
# features_dir - directory for local features. Defaults to "features"
|
14
|
+
# branch - git branch of remote git-based wiki to use. Defaults to
|
15
|
+
# 'master'
|
16
|
+
# annotate_results - boolean, determines if Gitnesse will annotate cucumber
|
17
|
+
# results to wiki pages. Defaults to false
|
18
|
+
# identifier - if annotate_results is checked, an identifier to use
|
19
|
+
# to indicate who ran the cukes.
|
20
|
+
# e.g. "Uncle Bob's MacBook Air"
|
21
|
+
|
22
|
+
@@config = ConfigStruct.new
|
23
|
+
|
24
|
+
# default config options
|
25
|
+
@@config.annotate_results = false
|
26
|
+
@@config.branch = 'master'
|
27
|
+
@@config.features_dir = 'features'
|
28
|
+
|
29
|
+
# Allows external configuration of the ConfigStruct using a block.
|
30
|
+
#
|
31
|
+
# Accepts a block for config options
|
32
|
+
#
|
33
|
+
# Returns the current configuration
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
# @config = Gitnesse::Config.instance
|
37
|
+
#
|
38
|
+
# Gitnesse::Config.config do |config|
|
39
|
+
# config.annotate_results = true
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# @config.annotate_results #=> true
|
43
|
+
def self.config
|
44
|
+
yield @@config if block_given?
|
45
|
+
Hash[@@config.each_pair.to_a]
|
46
|
+
end
|
47
|
+
|
48
|
+
# Converts the current configuration option to a hash
|
49
|
+
#
|
50
|
+
# Returns a hash
|
51
|
+
def to_h
|
52
|
+
Hash[@@config.each_pair.to_a]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Method_missing used to make it easier to access ConfigStruct values
|
56
|
+
#
|
57
|
+
# Example:
|
58
|
+
# @config = Gitnesse::Config.instance
|
59
|
+
# @config.annotate_results #=> false
|
60
|
+
def method_missing(method, *args, &block)
|
61
|
+
if @@config.respond_to?(method)
|
62
|
+
@@config.send(method, *args, &block)
|
63
|
+
else
|
64
|
+
raise NoMethodError
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Gitnesse
|
2
|
+
class ConfigLoader
|
3
|
+
class ConfigFileError < StandardError ; end
|
4
|
+
|
5
|
+
def self.find_and_load
|
6
|
+
files = Dir.glob(File.join("**", "gitnesse.rb"))
|
7
|
+
|
8
|
+
files = reject_irrelevant_files files
|
9
|
+
|
10
|
+
files_with_config = files.select do |file_name|
|
11
|
+
file_content = File.read(file_name)
|
12
|
+
file_content.match("Gitnesse::Config.config do")
|
13
|
+
end
|
14
|
+
|
15
|
+
case files_with_config.length
|
16
|
+
when 0
|
17
|
+
raise_error "Can't find a gitnesse.rb file with Gitnesse configuration."
|
18
|
+
when 1
|
19
|
+
load(File.absolute_path(files_with_config.first))
|
20
|
+
else
|
21
|
+
raise_error "Multiple configuration files found:", files_with_config
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def self.reject_irrelevant_files(files)
|
27
|
+
files.reject { |f| !!(File.absolute_path(f) =~ /.*(spec|vendor).*/) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.raise_error(message, files = nil)
|
31
|
+
puts message
|
32
|
+
files.each { |f| puts f } if files
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module Gitnesse
|
2
|
+
class DependencyChecker
|
3
|
+
attr_reader :errors
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@errors = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def check
|
10
|
+
check_git
|
11
|
+
check_cucumber
|
12
|
+
check_repository_url
|
13
|
+
check_identifier
|
14
|
+
check_features_dir_exists
|
15
|
+
|
16
|
+
display_errors if @errors.any?
|
17
|
+
end
|
18
|
+
|
19
|
+
def display_errors
|
20
|
+
puts "Configuration errors were found!"
|
21
|
+
|
22
|
+
@errors.each do |error|
|
23
|
+
puts " - #{error}"
|
24
|
+
end
|
25
|
+
|
26
|
+
exit
|
27
|
+
end
|
28
|
+
|
29
|
+
# Checks that Git is installed on the system.
|
30
|
+
#
|
31
|
+
# Returns true or raises DependencyNotMetError if git is broken
|
32
|
+
def check_git
|
33
|
+
if system("git --version &> /dev/null")
|
34
|
+
true
|
35
|
+
else
|
36
|
+
@errors << "Git not found or not working"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Checks that Cucumber is installed on the system.
|
41
|
+
#
|
42
|
+
# Returns true or raises DependencyNotMetError if Cucumber is broken
|
43
|
+
def check_cucumber
|
44
|
+
if system("cucumber --version &> /dev/null")
|
45
|
+
true
|
46
|
+
else
|
47
|
+
@errors << "Cucumber not found or not working"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Checks that repository_url is set in Gitnesse::Config.
|
52
|
+
#
|
53
|
+
# Returns true or raises DependencyNotMetError if repository_url isn't set
|
54
|
+
def check_repository_url
|
55
|
+
url = Gitnesse::Config.instance.repository_url
|
56
|
+
if url.nil? || url.empty?
|
57
|
+
@errors << "You must specify a repository_url to run Gitnesse"
|
58
|
+
else
|
59
|
+
true
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Checks that identifier is set in Gitnesse::Config, if annotate_results is
|
64
|
+
# set.
|
65
|
+
#
|
66
|
+
# Returns true or raises DependencyNotMetError if identifier isn't set
|
67
|
+
def check_identifier
|
68
|
+
return true unless Gitnesse::Config.instance.annotate_results
|
69
|
+
identifier = Gitnesse::Config.instance.identifier
|
70
|
+
if identifier.nil? || identifier.empty?
|
71
|
+
@errors << "You must specify identifier to use the annotate_results option"
|
72
|
+
else
|
73
|
+
true
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def check_features_dir_exists
|
78
|
+
dir = Gitnesse::Config.instance.features_dir
|
79
|
+
if File.directory?(dir)
|
80
|
+
true
|
81
|
+
else
|
82
|
+
@errors << "The features directory './#{dir}' does not exist."
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Gitnesse
|
4
|
+
class DirManager
|
5
|
+
# Public: Checks/Creates ~/.gitnesse/{{project_name}} dir.
|
6
|
+
# The project name is derived from the folder gitnesse is run in.
|
7
|
+
#
|
8
|
+
# Returns the path to the created project dir
|
9
|
+
def self.make_project_dir
|
10
|
+
FileUtils.mkdir_p project_dir
|
11
|
+
project_dir
|
12
|
+
end
|
13
|
+
|
14
|
+
# Public: Removes project dir, but not ~/.gitnesse dir
|
15
|
+
#
|
16
|
+
# Returns nothing
|
17
|
+
def self.remove_project_dir
|
18
|
+
FileUtils.rm_rf project_dir
|
19
|
+
end
|
20
|
+
|
21
|
+
# Public: Checks that project directory is present
|
22
|
+
#
|
23
|
+
# Returns a boolean indicating if the dir exists or not
|
24
|
+
def self.project_dir_present?
|
25
|
+
File.directory? project_dir
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
# Private: Constructs project dir path in ~/.gitnesse folder
|
30
|
+
#
|
31
|
+
# Returns a string path
|
32
|
+
def self.project_dir
|
33
|
+
project_name = File.basename Dir.pwd
|
34
|
+
"#{Dir.home}/.gitnesse/#{project_name}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Gitnesse
|
2
|
+
class Feature
|
3
|
+
attr_accessor :filename
|
4
|
+
|
5
|
+
def initialize(filename)
|
6
|
+
if filename =~ /^\.\/features\/(.+)/
|
7
|
+
@filename = filename.scan(/^\.?\/?features\/(.+)/).flatten.first
|
8
|
+
else
|
9
|
+
@filename = filename
|
10
|
+
end
|
11
|
+
|
12
|
+
@config = Gitnesse::Config.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
# Public: Converts feature filename into the filename used on the remote
|
16
|
+
# git-based wiki
|
17
|
+
#
|
18
|
+
# Returns the converted filename
|
19
|
+
def wiki_filename
|
20
|
+
"features/#{@filename}.md".gsub('/', ' > ')
|
21
|
+
end
|
22
|
+
|
23
|
+
# Public: Reads the feature's contents. Caches result so only reads from FS
|
24
|
+
# first time it's called.
|
25
|
+
#
|
26
|
+
# Returns a string
|
27
|
+
def read
|
28
|
+
@content ||= File.read("#{@config.features_dir}/#{@filename}")
|
29
|
+
end
|
30
|
+
|
31
|
+
# Public: Writes updated content to the feature, or creates a new feature if
|
32
|
+
# it doesn't exist.
|
33
|
+
#
|
34
|
+
# content - The new/updated content to write to the file
|
35
|
+
#
|
36
|
+
# Returns the passed content
|
37
|
+
def write(content)
|
38
|
+
File.open("#{@config.features_dir}/#{@filename}", 'w') do |f|
|
39
|
+
f.write content
|
40
|
+
end
|
41
|
+
|
42
|
+
@content = nil
|
43
|
+
|
44
|
+
content
|
45
|
+
end
|
46
|
+
|
47
|
+
# Public: Generates the path to the index page the feature would appear on.
|
48
|
+
# Used to group Features for creating index pages.
|
49
|
+
#
|
50
|
+
# Returns a string indicating the index page.
|
51
|
+
def index_page
|
52
|
+
p = wiki_filename.scan(/^(features\ \>\ .+) >/).flatten[0] || 'features'
|
53
|
+
p + ".md"
|
54
|
+
end
|
55
|
+
|
56
|
+
# Public: Generates relative link for wiki index pages.
|
57
|
+
#
|
58
|
+
# Returns a string containing the relative link as markdown
|
59
|
+
def relative_link
|
60
|
+
"[[#{wiki_filename.gsub('.md', '')}]]"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Gitnesse
|
2
|
+
class FeatureExtractor
|
3
|
+
|
4
|
+
# Extracts Cucumber features from a Markdown-formatted string
|
5
|
+
#
|
6
|
+
# string - Markdown-formatted string to find Cucumber features in
|
7
|
+
#
|
8
|
+
# Returns an array of matches
|
9
|
+
def self.extract!(string)
|
10
|
+
matches = string.scan(/\u0060{3}gherkin\s*(.+?)\u0060{3}/im).flatten
|
11
|
+
|
12
|
+
if matches.any?
|
13
|
+
# Remove newline characters from beginning/end of each feature
|
14
|
+
matches.map { |m| m.lstrip! ; m.chomp! }
|
15
|
+
else
|
16
|
+
[]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Checks if a string contains a Cucumber feature
|
21
|
+
#
|
22
|
+
# string - Markdown-formatted string to check for Cucumber features in
|
23
|
+
#
|
24
|
+
# Returns true if there are features, false otherwise
|
25
|
+
def self.contains_features?(string)
|
26
|
+
string.scan(/\u0060{3}gherkin\s*(.+?)\u0060{3}/im).flatten.any?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Gitnesse
|
2
|
+
class FeatureTransform
|
3
|
+
|
4
|
+
# Converts a Cucumber feature into a Markdown string compatible with
|
5
|
+
# Github's Wiki system
|
6
|
+
#
|
7
|
+
# feature - Cucumber feature to convert to Markdown
|
8
|
+
#
|
9
|
+
# Returns a string
|
10
|
+
def self.convert(feature)
|
11
|
+
unless feature.scan(/^\s*?Feature\:(.+?)\n/).flatten.any?
|
12
|
+
return <<-EOS.chomp
|
13
|
+
# Undefined Feature
|
14
|
+
|
15
|
+
This feature hasn't been added yet.
|
16
|
+
EOS
|
17
|
+
end
|
18
|
+
|
19
|
+
title = feature.scan(/^\s*?Feature\:(.+?)\n/).flatten.first.lstrip.chomp
|
20
|
+
|
21
|
+
<<-EOS.chomp
|
22
|
+
# #{title}
|
23
|
+
|
24
|
+
```gherkin
|
25
|
+
#{feature.chomp}
|
26
|
+
```
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/gitnesse/hooks.rb
CHANGED
@@ -1,52 +1,49 @@
|
|
1
1
|
module Gitnesse
|
2
2
|
class Hooks
|
3
|
-
@
|
3
|
+
@config = Gitnesse::Config.instance
|
4
4
|
|
5
|
-
|
5
|
+
DIR = File.expand_path("./#{@config.features_dir}/support")
|
6
|
+
PATH = File.expand_path("./#{@config.features_dir}/support/gitnesse.rb")
|
7
|
+
|
8
|
+
# Public: Copies Gitnesse Cucumber hooks to Cucumber's support dir.
|
6
9
|
#
|
7
10
|
# Returns nothing
|
8
|
-
def self.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
Wiki.new(@dir).remove_past_results
|
11
|
+
def self.create!
|
12
|
+
FileUtils.mkdir_p DIR unless File.directory?(DIR)
|
13
|
+
|
14
|
+
file = File.expand_path("#{File.dirname(__FILE__)}/hooks/gitnesse.rb")
|
15
|
+
FileUtils.cp file, PATH
|
14
16
|
end
|
15
17
|
|
16
|
-
# Public: Removes
|
18
|
+
# Public: Removes existing Gitnesse hooks in Cucumber's support dir
|
17
19
|
#
|
18
20
|
# Returns nothing
|
19
|
-
def self.
|
20
|
-
|
21
|
-
Dir.chdir(@dir) do
|
22
|
-
`git push origin master &> /dev/null`
|
23
|
-
end
|
24
|
-
|
25
|
-
FileUtils.rm_rf(@dir)
|
26
|
-
FileUtils.rm(File.absolute_path("#{Gitnesse.configuration.target_directory}/support/gitnesse_hooks.rb"))
|
27
|
-
puts " Done."
|
21
|
+
def self.destroy!
|
22
|
+
FileUtils.rm PATH, force: true
|
28
23
|
end
|
29
24
|
|
30
|
-
# Public:
|
25
|
+
# Public: Used by Gitnesse hook to append results to wiki page for feature
|
26
|
+
#
|
27
|
+
# scenario - Cucumber scenario passed by post-scenario hook
|
31
28
|
#
|
32
29
|
# Returns nothing
|
33
|
-
def self.
|
34
|
-
|
35
|
-
|
36
|
-
target_file = File.join(support_dir, "gitnesse_hooks.rb")
|
30
|
+
def self.append_results(scenario)
|
31
|
+
Gitnesse::ConfigLoader.find_and_load
|
32
|
+
dir = Gitnesse::DirManager.project_dir
|
37
33
|
|
38
|
-
|
34
|
+
file = scenario.file.gsub(/^#{@config.features_dir}\//, '')
|
39
35
|
|
40
|
-
|
41
|
-
|
36
|
+
page = file.gsub("/", " > ")
|
37
|
+
name = scenario.name
|
38
|
+
status = scenario.status
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
40
|
+
@wiki = Gitnesse::Wiki.new(@config.repository_url, dir, clone: false)
|
41
|
+
page = @wiki.pages.find { |f| f.wiki_path.include?(page) }
|
42
|
+
|
43
|
+
return unless page
|
44
|
+
|
45
|
+
page.append_result name, status
|
46
|
+
@wiki.repo.add(page.wiki_path)
|
50
47
|
end
|
51
48
|
end
|
52
49
|
end
|
data/lib/gitnesse/railtie.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'gitnesse'
|
2
|
+
require 'gitnesse/cli/task'
|
3
|
+
|
2
4
|
require 'rails'
|
3
5
|
|
4
6
|
module Gitnesse
|
@@ -6,7 +8,7 @@ module Gitnesse
|
|
6
8
|
railtie_name :gitnesse
|
7
9
|
|
8
10
|
rake_tasks do
|
9
|
-
load File.dirname(__FILE__) + '/tasks.rake'
|
11
|
+
load File.dirname(__FILE__) + '/rake/tasks.rake'
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
data/lib/gitnesse/tasks.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'gitnesse'
|
2
|
+
require 'gitnesse/cli/task'
|
3
|
+
|
4
|
+
require 'rake'
|
5
|
+
require 'rake/tasklib'
|
3
6
|
|
4
7
|
module Gitnesse
|
5
8
|
class Tasks < ::Rake::TaskLib
|
6
|
-
load File.dirname(__FILE__) +
|
9
|
+
load File.dirname(__FILE__) + "/rake/tasks.rake"
|
7
10
|
end
|
8
|
-
end
|
11
|
+
end
|
data/lib/gitnesse/version.rb
CHANGED
@@ -0,0 +1,103 @@
|
|
1
|
+
module Gitnesse
|
2
|
+
class Wiki
|
3
|
+
class Page
|
4
|
+
attr_reader :wiki_path, :path, :filename, :relative_path
|
5
|
+
|
6
|
+
# Public: Creates a new Wiki Page object. Contains references to the page
|
7
|
+
# and an easy way to access/update relevant page data.
|
8
|
+
#
|
9
|
+
# path - full path to the file
|
10
|
+
#
|
11
|
+
# Returns a Wiki::Page object
|
12
|
+
def initialize(path)
|
13
|
+
@wiki_path = path
|
14
|
+
@relative_path = get_relative_path
|
15
|
+
@filename = get_filename
|
16
|
+
@path = "#{@relative_path}/#{@filename}"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Public: Reads the file's contents. Caches result so only reads from FS
|
20
|
+
# first time it's called per page.
|
21
|
+
#
|
22
|
+
# Returns a string
|
23
|
+
def read
|
24
|
+
@content ||= File.read(@wiki_path)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Public: Writes content to the file.
|
28
|
+
#
|
29
|
+
# Returns the passed content
|
30
|
+
def write(content)
|
31
|
+
File.open(@wiki_path, 'w+') do |f|
|
32
|
+
f.write content
|
33
|
+
end
|
34
|
+
|
35
|
+
@content = nil
|
36
|
+
|
37
|
+
content
|
38
|
+
end
|
39
|
+
|
40
|
+
# Public: Removes existing results from the feature page.
|
41
|
+
#
|
42
|
+
# Returns nothing
|
43
|
+
def remove_results
|
44
|
+
write(read.gsub(/(\s+\!\[\].*)/, ''))
|
45
|
+
end
|
46
|
+
|
47
|
+
# Public: Appends the result of a Cucumber scenario to the feature's wiki
|
48
|
+
# page.
|
49
|
+
#
|
50
|
+
# scenario - feature scenario that was run
|
51
|
+
# status - return status of the scenario, e.g. :passed, :undefined,
|
52
|
+
# :failing
|
53
|
+
#
|
54
|
+
# Returns nothing
|
55
|
+
def append_result(scenario, status)
|
56
|
+
status = status.to_s
|
57
|
+
image = "![](https://s3.amazonaws.com/gitnesse/github/#{status}.png)"
|
58
|
+
string = "\n\n#{image} \`"
|
59
|
+
string << "Last Result For Scenario '#{scenario}': "
|
60
|
+
string << status.upcase
|
61
|
+
string << " (#{Time.now.strftime("%b %d, %Y, %-l:%M %p")} - "
|
62
|
+
string << "#{Gitnesse::Config.instance.identifier})\`"
|
63
|
+
|
64
|
+
write(read + string)
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
# Protected: Converts wiki-formatted filename into directories containing
|
69
|
+
# the page.
|
70
|
+
#
|
71
|
+
# Wiki filenames are formatted to accomodate nested directories, so for
|
72
|
+
# example the local feature "features/thing/thing.feature" would be given
|
73
|
+
# the filename "features > thing > thing.feature" in the wiki.
|
74
|
+
#
|
75
|
+
# path - path to convert
|
76
|
+
#
|
77
|
+
# Returns a string dir path
|
78
|
+
#
|
79
|
+
# Examples:
|
80
|
+
# @wiki_path = "features > thing > thing.feature.md"
|
81
|
+
# get_relative_path #=> "./features/thing"
|
82
|
+
#
|
83
|
+
# @wiki_path = "thing.feature"
|
84
|
+
# get_relative_path #=> "./features"
|
85
|
+
def get_relative_path
|
86
|
+
dirs = File.basename(@wiki_path).scan(/(\w+)\ \>/).flatten
|
87
|
+
dirs.shift if dirs.first == "features"
|
88
|
+
"./#{Gitnesse::Config.instance.features_dir}/#{dirs.join("/")}"
|
89
|
+
end
|
90
|
+
|
91
|
+
# Protected: Extracts the local filename for the wiki page
|
92
|
+
#
|
93
|
+
# Returns a string containing the filename
|
94
|
+
#
|
95
|
+
# Examples:
|
96
|
+
# @wiki_path = "features > thing > thing.feature.md"
|
97
|
+
# get_filename #=> "thing.feature"
|
98
|
+
def get_filename
|
99
|
+
File.basename(@wiki_path, '.md').scan(/(\w+\.feature)$/).flatten.first
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|