forked from aslakhellesoy/pickler
/
pickler.rb
139 lines (110 loc) · 3.01 KB
/
pickler.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
require 'yaml'
class Pickler
class Error < RuntimeError
end
autoload :Runner, 'pickler/runner'
autoload :Feature, 'pickler/feature'
autoload :Tracker, 'pickler/tracker'
def self.config
@config ||= {'api_token' => ENV["TRACKER_API_TOKEN"]}.merge(
if File.exist?(path = File.expand_path('~/.tracker.yml'))
YAML.load_file(path)
end || {}
)
end
def self.run(argv)
Runner.new(argv).run
end
attr_reader :directory
def initialize(path = '.')
@lang = 'en'
@directory = File.expand_path(path)
until File.directory?(File.join(@directory,'features'))
if @directory == File.dirname(@directory)
raise Error, 'Project not found. Make sure you have a features/ directory.', caller
end
@directory = File.dirname(@directory)
end
end
def features_path(*subdirs)
File.join(@directory,'features',*subdirs)
end
def config_file
features_path('tracker.yml')
end
def config
@config ||= File.exist?(config_file) && YAML.load_file(config_file) || {}
self.class.config.merge(@config)
end
def real_name
config["real_name"] || (require 'etc'; Etc.getpwuid.gecos.split(',').first)
end
def new_story(attributes = {}, &block)
attributes = attributes.inject('requested_by' => real_name) do |h,(k,v)|
h.update(k.to_s => v)
end
project.new_story(attributes, &block)
end
def stories(*args)
project.stories(*args)
end
def name
project.name
end
def iteration_length
project.iteration_length
end
def point_scale
project.point_scale
end
def week_start_day
project.week_start_day
end
def deliver_all_finished_stories
project.deliver_all_finished_stories
end
def parser
require 'cucumber'
Cucumber.load_language(@lang)
@parser ||= Cucumber::Parser::FeatureParser.new
end
def project_id
config["project_id"] || (self.class.config["projects"]||{})[File.basename(@directory)]
end
def project
@project ||= Dir.chdir(@directory) do
unless token = config['api_token']
raise Error, 'echo api_token: ... > ~/.tracker.yml'
end
unless id = project_id
raise Error, 'echo project_id: ... > features/tracker.yml'
end
ssl = config['ssl']
Tracker.new(token, ssl).project(id)
end
end
def scenario_word
parser
Cucumber.keyword_hash['scenario']
end
def format
(config['format'] || :comment).to_sym
end
def local_features
Dir[features_path('**','*.feature')].map {|f|feature(f)}.select {|f|f.pushable?}
end
def scenario_features(excluded_states = %w(unscheduled unstarted))
project.stories(scenario_word, :includedone => true).reject do |s|
Array(excluded_states).map {|s| s.to_s}.include?(s.current_state)
end.select do |s|
s.to_s =~ /^\s*#{Regexp.escape(scenario_word)}:/ && parser.parse(s.to_s)
end
end
def feature(string)
string.kind_of?(Feature) ? string : Feature.new(self,string)
end
def story(string)
feature(string).story
end
protected
end