|
require 'gherkin/parser' |
|
require 'gherkin/pickles/compiler' |
|
|
|
module RelishNav |
|
class Collector |
|
def initialize(feature_dir) |
|
@feature_dir = feature_dir |
|
@parser = Gherkin::Parser.new |
|
end |
|
|
|
def collect_features(initial_entries = {}) |
|
dirs = initial_entries |
|
Dir["#{feature_dir}/**/*.feature"].each do |file| |
|
dir = relative(File.dirname(file), feature_dir) |
|
|
|
(dirs[dir] ||= []).tap do |nodes| |
|
node = extract_gherkin_info(file) |
|
|
|
feature_file = relative(file, "#{feature_dir}/#{dir}") |
|
node = node.merge(file: feature_file) |
|
nodes << node |
|
end |
|
end |
|
dirs |
|
end |
|
|
|
private |
|
|
|
attr_reader :parser |
|
attr_reader :feature_dir |
|
|
|
def relative(path, base_dir) |
|
path = path.sub("#{base_dir}", '') |
|
path = path[1..-1] if path.start_with?('/') |
|
path |
|
end |
|
|
|
def extract_gherkin_info(file) |
|
document = parser.parse(IO.read(file)) |
|
feature = document.fetch(:feature) |
|
name = feature.fetch(:name) |
|
tags = feature.fetch(:tags).map { |taginfo| taginfo[:name]} |
|
|
|
# NOTE: neither name nor tags are used yet |
|
{ name: name, tags: tags } |
|
end |
|
end |
|
|
|
class Generator |
|
def generate(data, output_file) |
|
dirs = data |
|
|
|
File.open(output_file, "w") do |file| |
|
dirs.each_pair do |dir, nodes| |
|
if dir.empty? |
|
dump_nodes(file, nodes, level: 0) |
|
else |
|
file.puts "- #{dir}:" |
|
dump_nodes(file, nodes, level: 1) |
|
end |
|
end |
|
end |
|
end |
|
|
|
def dump_nodes(file, nodes, options) |
|
indent = ' ' * options.fetch(:level) |
|
nodes.each do |node| |
|
file.puts "#{indent}- #{node.fetch(:file)}" |
|
end |
|
end |
|
end |
|
end |
|
|
|
|
|
initial_entries = { |
|
'' => [ |
|
{ name: '', file: "Changelog.md", tags: [] }, |
|
{ name: '', file: "Autotest.md", tags: [] } |
|
] |
|
} |
|
|
|
feature_dir = '/home/me/github.com/rspec-core/features' |
|
output_file = ".nav.new" |
|
collector = RelishNav::Collector.new(feature_dir) |
|
data = collector.collect_features(initial_entries) |
|
|
|
generator = RelishNav::Generator.new |
|
generator.generate(data, output_file) |