cuki 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,13 +2,11 @@
2
2
 
3
3
  Cuki provides an easy way to import acceptance criteria from a Confluence wiki into Cucumber feature files
4
4
 
5
- - Supports a mapping between Confluence pages and feature files
6
5
  - Converts Confluence tables to Cucumber tables
7
6
  - Strips out unnecessary Confluence formatting (headers, etc.)
8
7
  - Includes a link back to the original Confluence page
9
8
  - Formats the feature using Cucumber's auto-formatter (optional)
10
9
  - Support client SSL certificates for use within an organisation's secure intranet
11
- - Assign tags to a feature based on the wiki page content
12
10
 
13
11
  It can be used as part of a CI process or just for ad-hoc imports.
14
12
 
@@ -45,6 +43,11 @@ You can also pull a single feature:
45
43
 
46
44
  cuki pull features/add_product.feature
47
45
 
46
+ == Tags
47
+
48
+ You can add tags to a feature based on the wiki page content. See the sample configuration file.
49
+
50
+
48
51
  == Options
49
52
 
50
53
  - --skip--autoformat to avoid reformatting features (runs over the whole features directory)
@@ -60,8 +63,6 @@ If your Confluence installation requires a client certificate, you can supply th
60
63
 
61
64
  - Will only work with Confluence setups which have no password, or use client certificates for authentication
62
65
  - Only provides one-way sync, i.e. you can't edit a file locally and push it to Confluence
63
- - Fails if the AC block is the last h1. section of the page
64
- - Should fail if no features found in container block
65
66
 
66
67
  == TODO
67
68
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.10
1
+ 0.0.11
data/cuki.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cuki"
8
- s.version = "0.0.10"
8
+ s.version = "0.0.11"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Andy Waite"]
12
- s.date = "2011-10-22"
12
+ s.date = "2011-10-23"
13
13
  s.description = ""
14
14
  s.email = "andy@andywaite.com"
15
15
  s.executables = ["cuki"]
@@ -44,7 +44,6 @@ Gem::Specification.new do |s|
44
44
  "features/step_defs/pull_steps.rb",
45
45
  "features/step_defs/push_steps.rb",
46
46
  "features/support/env.rb",
47
- "lib/cleaner.rb",
48
47
  "lib/confluence_page.rb",
49
48
  "lib/cuki.rb",
50
49
  "lib/feature_file.rb",
data/cuki.yaml.sample CHANGED
@@ -2,10 +2,10 @@
2
2
  # the mappings associate the page IDs on Confluence with local feature files
3
3
  ---
4
4
  host: http://mywiki
5
+ container: "h1. Acceptance Criteria"
5
6
  tags:
6
7
  draft: "{info:title=Draft version}"
7
8
  signed_off: "{info:title=Signed-off}"
8
9
  mappings:
9
- 123: features/products/add_product.feature # single file mapping
10
- 124: features/products/remove_product.feature # single file mapping
11
- 125: features/admin # folder mapping
10
+ 123: features/products
11
+ 124: features/admin
@@ -13,4 +13,26 @@ Feature: Error Handling
13
13
  Then it should fail with:
14
14
  """
15
15
  No config file found at config/cuki.yaml
16
- """
16
+ """
17
+
18
+ Scenario: Missing scenarios
19
+ Given a file named "config/cuki.yaml" with:
20
+ """
21
+ ---
22
+ host: http://example.com
23
+ mappings:
24
+ 123: features/products
25
+ """
26
+ And a Confluence page on "example.com" with id 123:
27
+ """
28
+ <input id="content-title" value="Add Product">
29
+ <div id="markupTextarea">
30
+ h1. Acceptance Criteria
31
+ </div>
32
+ """
33
+ When I run `cuki pull --skip-autoformat`
34
+ Then it should fail with:
35
+ """
36
+ No scenarios found in doc 123
37
+ """
38
+
@@ -1,55 +1,56 @@
1
- Feature: Pull
2
-
3
- Scenario: Pull all features
4
- Given a file named "config/cuki.yaml" with:
5
- """
6
- ---
7
- host: http://example.com
8
- mappings:
9
- 123: features/products/add_product.feature
10
- 456: features/products/remove_product.feature
11
- """
12
- And a Confluence page on "example.com" with id 123:
13
- """
14
- <input id="content-title" value="Add Product">
15
- <div id="markupTextarea">
16
- This feature describes adding a product
17
-
18
- # Some comment
19
-
20
- Blah
21
- </div>
22
- """
23
- And a Confluence page on "example.com" with id 456:
24
- """
25
- <input id="content-title" value="Remove Product">
26
- <div id="markupTextarea">
27
- This feature describes removing a product
28
- </div>
29
- """
30
- When I run `cuki pull --skip-autoformat --skip-header`
31
- Then the file "features/products/add_product.feature" should contain exactly:
32
- """
33
- Feature: Add Product
34
-
35
- http://example.com/pages/viewpage.action?pageId=123
36
-
37
-
38
- This feature describes adding a product
39
-
40
- - Some comment
41
-
42
- Blah
43
-
44
- """
45
- And the file "features/products/remove_product.feature" should contain exactly:
46
- """
47
- Feature: Remove Product
48
-
49
- http://example.com/pages/viewpage.action?pageId=456
50
-
51
-
52
- This feature describes removing a product
53
-
54
- """
55
-
1
+ # Feature: Pull
2
+ #
3
+ # @focus @announc
4
+ # Scenario: Pull all features
5
+ # Given a file named "config/cuki.yaml" with:
6
+ # """
7
+ # ---
8
+ # host: http://example.com
9
+ # mappings:
10
+ # 123: features/products/add_product.feature
11
+ # 456: features/products/remove_product.feature
12
+ # """
13
+ # And a Confluence page on "example.com" with id 123:
14
+ # """
15
+ # <input id="content-title" value="Add Product">
16
+ # <div id="markupTextarea">
17
+ # This feature describes adding a product
18
+ #
19
+ # # Some comment
20
+ #
21
+ # Blah
22
+ # </div>
23
+ # """
24
+ # And a Confluence page on "example.com" with id 456:
25
+ # """
26
+ # <input id="content-title" value="Remove Product">
27
+ # <div id="markupTextarea">
28
+ # This feature describes removing a product
29
+ # </div>
30
+ # """
31
+ # When I run `cuki pull --skip-autoformat`
32
+ # Then the file "features/products/add_product.feature" should contain exactly:
33
+ # """
34
+ # Feature: Add Product
35
+ #
36
+ # http://example.com/pages/viewpage.action?pageId=123
37
+ #
38
+ #
39
+ # This feature describes adding a product
40
+ #
41
+ # - Some comment
42
+ #
43
+ # Blah
44
+ #
45
+ # """
46
+ # And the file "features/products/remove_product.feature" should contain exactly:
47
+ # """
48
+ # Feature: Remove Product
49
+ #
50
+ # http://example.com/pages/viewpage.action?pageId=456
51
+ #
52
+ #
53
+ # This feature describes removing a product
54
+ #
55
+ # """
56
+ #
@@ -1,29 +1,34 @@
1
1
  Feature: Pull single
2
2
 
3
- Scenario: Pull all features
3
+ @focus @announce
4
+ Scenario: Pull single feature
4
5
  Given a file named "config/cuki.yaml" with:
5
6
  """
6
7
  ---
7
8
  host: http://example.com
8
9
  mappings:
9
- 123: features/products/add_product.feature
10
- 456: features/products/remove_product.feature
10
+ 123: features/products
11
+ 456: features/admin
11
12
  """
12
13
  And a Confluence page on "example.com" with id 123:
13
14
  """
14
- <input id="content-title" value="Add Product">
15
+ <input id="content-title" value="Products">
15
16
  <div id="markupTextarea">
16
- This feature describes adding a product
17
+ h1. Acceptance Criteria
18
+ h2. Add Product
19
+ h6. Scenario
17
20
  </div>
18
21
  """
19
22
  And a Confluence page on "example.com" with id 456:
20
23
  """
21
- <input id="content-title" value="Remove Product">
24
+ <input id="content-title" value="Admin">
22
25
  <div id="markupTextarea">
23
- This feature describes removing a product
26
+ h1. Acceptance Criteria
27
+ h2. Edit User
28
+ h6. Scenario
24
29
  </div>
25
30
  """
26
- When I run `cuki pull features/products/add_product.feature --skip-autoformat --skip-header`
31
+ When I run `cuki pull features/products --skip-autoformat`
27
32
  Then a file named "features/products/add_product.feature" should exist
28
- But the file "features/products/remove_product.feature" should not exist
33
+ But the file "features/admin/edit_user.feature" should not exist
29
34
 
@@ -36,7 +36,7 @@ Feature: Splitting
36
36
  h1. Next Section
37
37
  </div>
38
38
  """
39
- When I run `cuki pull --skip-autoformat --skip-header`
39
+ When I run `cuki pull --skip-autoformat`
40
40
  Then the file "features/products/add_product.feature" should contain exactly:
41
41
  """
42
42
  Feature: Add Product
@@ -62,7 +62,7 @@ Feature: Splitting
62
62
 
63
63
  """
64
64
 
65
- @announce @focus
65
+ @announce
66
66
  Scenario: Pull all features (specified container)
67
67
  Given a file named "config/cuki.yaml" with:
68
68
  """
@@ -89,7 +89,7 @@ Feature: Splitting
89
89
  h1. Next Section
90
90
  </div>
91
91
  """
92
- When I run `cuki pull --skip-autoformat --skip-header`
92
+ When I run `cuki pull --skip-autoformat`
93
93
  Then the file "features/products/add_product.feature" should contain exactly:
94
94
  """
95
95
  Feature: Add Product
@@ -104,7 +104,7 @@ Feature: Splitting
104
104
  """
105
105
 
106
106
  @announce
107
- Scenario:Special Chars
107
+ Scenario: Special Chars
108
108
  Given a file named "config/cuki.yaml" with:
109
109
  """
110
110
  ---
@@ -129,7 +129,7 @@ Feature: Splitting
129
129
  h1. Next Section
130
130
  </div>
131
131
  """
132
- When I run `cuki pull --skip-autoformat --skip-header`
132
+ When I run `cuki pull --skip-autoformat`
133
133
  Then the file "features/products/add_remove_product.feature" should contain exactly:
134
134
  """
135
135
  Feature: Add/Remove Product
@@ -141,4 +141,5 @@ Feature: Splitting
141
141
  Scenario: Scenario A
142
142
 
143
143
 
144
- """
144
+ """
145
+
@@ -7,13 +7,17 @@ Feature: Tables
7
7
  ---
8
8
  host: http://example.com
9
9
  mappings:
10
- 123: features/products/add_product.feature
10
+ 123: features/products
11
11
  """
12
12
  And a Confluence page on "example.com" with id 123:
13
13
  """
14
- <input id="content-title" value="Add Product">
14
+ <input id="content-title" value="Products">
15
15
  <div id="markupTextarea">
16
- h5. Scenario: Foo
16
+ h1. Acceptance Criteria
17
+
18
+ h2. Add Product
19
+
20
+ h6. Scenario: Foo
17
21
 
18
22
  Given this:
19
23
  || foo || bar ||
@@ -21,13 +25,12 @@ Feature: Tables
21
25
  | b | 2 |
22
26
  </div>
23
27
  """
24
- When I run `cuki pull --skip-autoformat --skip-header`
28
+ When I run `cuki pull --skip-autoformat`
25
29
  Then the file "features/products/add_product.feature" should contain exactly:
26
30
  """
27
31
  Feature: Add Product
28
32
 
29
- http://example.com/pages/viewpage.action?pageId=123
30
-
33
+ http://example.com/pages/viewpage.action?pageId=123#Products-AddProduct
31
34
 
32
35
  Scenario: Foo
33
36
 
@@ -9,23 +9,28 @@ Feature: Tags
9
9
  draft: "{info:title=Draft version}"
10
10
  signed_off: "{info:title=Signed-off}"
11
11
  mappings:
12
- 123: features/products/add_product.feature
12
+ 123: features/products
13
13
  """
14
14
  And a Confluence page on "example.com" with id 123:
15
15
  """
16
- <input id="content-title" value="Add Product">
17
- <div id="markupTextarea">{info:title=Draft version}
18
- h5. Scenario: Foo
16
+ <input id="content-title" value="Products">
17
+ <div id="markupTextarea">
18
+ h1. Acceptance Criteria
19
+
20
+ {info:title=Draft version}
21
+
22
+ h2. Add Product
23
+
24
+ h6. Scenario: Foo
19
25
  </div>
20
26
  """
21
- When I run `cuki pull --skip-autoformat --skip-header`
27
+ When I run `cuki pull --skip-autoformat`
22
28
  Then the file "features/products/add_product.feature" should contain exactly:
23
29
  """
24
30
  @draft
25
31
  Feature: Add Product
26
32
 
27
- http://example.com/pages/viewpage.action?pageId=123
28
-
33
+ http://example.com/pages/viewpage.action?pageId=123#Products-AddProduct
29
34
 
30
35
  Scenario: Foo
31
36
 
@@ -6,24 +6,27 @@ Feature: Textile
6
6
  ---
7
7
  host: http://example.com
8
8
  mappings:
9
- 123: features/products/add_product.feature
9
+ 123: features/products
10
10
  """
11
11
  And a Confluence page on "example.com" with id 123:
12
12
  """
13
- <input id="content-title" value="Add Product">
13
+ <input id="content-title" value="Products">
14
14
  <div id="markupTextarea">
15
- h5. Scenario: Foo
15
+ h1. Acceptance Criteria
16
+
17
+ h2. Add Product
18
+
19
+ h6. Scenario: Foo
16
20
 
17
21
  h6. Scenario Outline: Bar
18
22
  </div>
19
23
  """
20
- When I run `cuki pull --skip-autoformat --skip-header`
24
+ When I run `cuki pull --skip-autoformat`
21
25
  Then the file "features/products/add_product.feature" should contain exactly:
22
26
  """
23
27
  Feature: Add Product
24
28
 
25
- http://example.com/pages/viewpage.action?pageId=123
26
-
29
+ http://example.com/pages/viewpage.action?pageId=123#Products-AddProduct
27
30
 
28
31
  Scenario: Foo
29
32
 
@@ -11,7 +11,31 @@ class ConfluencePage
11
11
  end
12
12
 
13
13
  def content
14
- CGI.unescapeHTML @doc.css('#markupTextarea').text
14
+ content = CGI.unescapeHTML @doc.css('#markupTextarea').text
15
+
16
+ content.gsub!('&nbsp;', '')
17
+
18
+ # remove the double pipes used for table headers in Confluence
19
+ content.gsub!('||', '|')
20
+
21
+ # remove other noise
22
+ content.gsub!("\r\n", "\n")
23
+ content.gsub!("\\\\\n", '')
24
+ content.gsub!('\\', '')
25
+
26
+ # remove any unwanted headers
27
+ content.gsub!(/h\d\. (Scenario: .*)/, '\1')
28
+ content.gsub!(/h\d\. (Scenario Outline: .*)/, '\1')
29
+ content.gsub!(/h\d\. (Background: .*)/, '\1')
30
+
31
+ #Remove fancy quotes
32
+ content.gsub!('’', "'")
33
+ content.gsub!('‘', "'")
34
+ content.gsub!('“', '"')
35
+ content.gsub!('”', '"')
36
+
37
+ content.gsub!(/^#(.*)/, '-' + '\1')
38
+ content
15
39
  end
16
40
 
17
41
  end
data/lib/cuki.rb CHANGED
@@ -6,7 +6,6 @@ require 'json'
6
6
  require 'parallel'
7
7
  require File.dirname(__FILE__) + '/string_utils'
8
8
  require File.dirname(__FILE__) + '/link_builder'
9
- require File.dirname(__FILE__) + '/cleaner'
10
9
  require File.dirname(__FILE__) + '/confluence_page'
11
10
  require File.dirname(__FILE__) + '/feature_file'
12
11
  require File.dirname(__FILE__) + '/test_bits'
@@ -14,226 +13,138 @@ require File.dirname(__FILE__) + '/test_bits'
14
13
  class Cuki
15
14
 
16
15
  CONFIG_PATH = 'config/cuki.yaml'
16
+ DEFAULT_CONTAINER = /h1\. Acceptance Criteria/
17
+ PRIMARY_HEADER = "h1\."
18
+ FEATURE_HEADER = "h2\."
19
+ SCENARIO_HEADER = "h6\."
20
+
21
+ FLAGS = {:skip_autoformat => '--skip-autoformat'}
17
22
 
18
23
  def self.invoke(args)
19
24
  new(args)
20
25
  end
21
26
 
22
27
  def initialize(args)
23
- validate_args args
28
+ @args = args
29
+ validate_args
24
30
  read_config
25
31
  configure_http_client
26
-
32
+ @link_builder = LinkBuilder.new(@config['host'])
27
33
  action = args.first
28
- if args.include?('--skip-autoformat')
29
- args.delete_if { |arg| '--skip-autoformat' == arg }
34
+ if args.include?(FLAGS[:skip_autoformat])
35
+ args.delete_if { |arg| FLAGS[:skip_autoformat] == arg }
30
36
  @skip_autoformat = true
31
37
  end
32
- if args.include?('--skip-header')
33
- args.delete_if { |arg| '--skip-header' == arg }
34
- @skip_header = true
35
- end
36
- if 'pull' == action
37
- configure_pull_stubs
38
- verify_project
39
- file = args[1]
40
- if file
41
- id = @config['mappings'].invert[file]
42
- raise "could not get id for #{file}" unless id
43
- pull_feature id, file
44
- else
45
- Parallel.map(@config['mappings'], :in_processes => 4) do |id, filepath|
46
- pull_feature id, filepath
47
- end
48
- end
49
- autoformat
38
+ configure_pull_stubs
39
+ verify_project
40
+ file = args[1]
41
+ if file
42
+ id = mappings.invert[file]
43
+ terminate "could not get id for #{file}" unless id
44
+ pull_feature id, file
50
45
  else
51
- puts "Unknown action '#{action}"
52
- exit(1)
46
+ Parallel.map(mappings, :in_processes => 4) do |id, filepath|
47
+ pull_feature id, filepath
48
+ end
53
49
  end
50
+ autoformat!
54
51
  end
55
52
 
56
53
  private
57
-
54
+
58
55
  def verify_project
59
- # check features folder exists
60
- raise "features folder not found" unless File.exists?('features')
61
- autoformat
56
+ terminate "features folder not found" unless File.exists?('features')
57
+ `cucumber --dry-run -P`
62
58
  end
63
-
59
+
64
60
  def read_config
65
- unless File.exist?(CONFIG_PATH)
66
- puts "No config file found at #{CONFIG_PATH}"
67
- exit(1)
68
- end
61
+ terminate "No config file found at #{CONFIG_PATH}" unless File.exist?(CONFIG_PATH)
69
62
  @config = YAML::load( File.open( CONFIG_PATH ) )
70
- unless @config["host"]
71
- puts "Host not found in #{CONFIG_PATH}"
72
- exit(1)
73
- end
74
- unless @config["mappings"]
75
- puts "Mappings not found in #{CONFIG_PATH}"
76
- exit(1)
77
- end
63
+ terminate "Host not found in #{CONFIG_PATH}" unless @config["host"]
64
+ terminate "Mappings not found in #{CONFIG_PATH}" unless @config["mappings"]
78
65
  end
79
-
66
+
80
67
  def configure_http_client
81
68
  @client = HTTPClient.new
82
69
  @client.ssl_config.set_trust_ca(ENV['CER']) if ENV['CER']
83
70
  @client.ssl_config.set_client_cert_file(ENV['PEM'], ENV['PEM']) if ENV['PEM']
84
71
  end
85
-
72
+
86
73
  def pull_feature(id, filepath)
87
- @content = ''
88
-
89
- link_builder = LinkBuilder.new(@config['host'])
90
-
91
- wiki_edit_link = link_builder.edit(id)
92
- wiki_view_link = link_builder.view(id)
93
-
74
+ wiki_edit_link = @link_builder.edit(id)
94
75
  puts "Downloading #{wiki_edit_link}"
95
76
  response = @client.get wiki_edit_link
96
-
97
- confluence_page = ConfluencePage.new(response.body)
98
-
99
- unless confluence_page.content
100
- puts "Not a valid confluence page:"
101
- puts response.body
102
- exit(1)
103
- end
104
-
105
- unless filepath.include?('.feature')
106
-
107
- @config['container'] ||= /h1\. Acceptance Criteria/
108
-
109
- handle_multi response.body, id
110
- else
111
-
112
- feature_file = FeatureFile.new
113
- feature_file.title = confluence_page.title
114
- feature_file.link = wiki_view_link
115
- feature_file.content = confluence_page.content
116
-
117
- content = Cleaner.clean(feature_file.to_s)
118
-
119
- content = process_tags content
120
-
121
- content = generated_by + content unless @skip_header
122
-
123
- save_file content, filepath
124
- end
77
+ handle_multi response.body, id
125
78
  end
126
-
127
- def generated_by
128
- "# Generated by Cuki (#{Time.now})\n"
79
+
80
+ def container
81
+ @config['container'] ||= DEFAULT_CONTAINER
129
82
  end
130
-
131
- def autoformat
83
+
84
+ def autoformat!
132
85
  `cucumber -a . --dry-run -P` unless @skip_autoformat
133
86
  end
134
-
87
+
135
88
  def handle_multi response_body, id
136
89
  confluence_page = ConfluencePage.new(response_body)
137
-
138
- feature_title_compressed = confluence_page.title.anchorize
139
-
140
- @content += confluence_page.content
141
-
142
- @content = Cleaner.clean(@content)
143
-
144
- unless @content.match(@config['container'])
145
- puts "Could not find acceptance criteria container"
146
- exit(1)
147
- end
148
- acceptance_criteria_block = @content.split(@config['container']).last
149
- if acceptance_criteria_block.match(/h1\./)
150
- acceptance_criteria_block = acceptance_criteria_block.split(/h1\./).first
151
- end
152
- unless acceptance_criteria_block
153
- puts "Could not match #{@config['container']} in #{id}"
154
- exit(1)
90
+
91
+ content = confluence_page.content
92
+
93
+ terminate "Could not find acceptance criteria container" unless content.match(container)
94
+
95
+ acceptance_criteria = content.split(container).last
96
+ if acceptance_criteria.include?(PRIMARY_HEADER)
97
+ acceptance_criteria = acceptance_criteria.split(/#{PRIMARY_HEADER}/).first
155
98
  end
156
- acceptance_criteria = acceptance_criteria_block
157
- scenario_titles = acceptance_criteria.scan(/h2\. (.*)/).flatten
158
- scenario_blocks = acceptance_criteria.split(/h2\. .*/)
99
+
100
+ terminate "Could not match #{container} in #{id}" unless acceptance_criteria
101
+
102
+ scenario_titles = acceptance_criteria.scan(/#{FEATURE_HEADER} (.*)/).flatten
103
+ scenario_blocks = acceptance_criteria.split(/#{FEATURE_HEADER} .*/)
159
104
  scenario_blocks.shift
160
105
 
161
106
  combined = {}
162
107
  found = 0
163
108
  scenario_titles.each_with_index do |title, index|
164
- combined[title] = scenario_blocks[index].gsub(/h6. (.*)/, '\1')
109
+ combined[title] = scenario_blocks[index].gsub(/#{SCENARIO_HEADER} (.*)/, '\1')
165
110
  found += 1
166
111
  end
167
- if 0 == found
168
- puts "No scenarios found in doc #{id}"
169
- exit(1)
170
- end
171
- combined.each do |title, content|
172
-
173
- tags = []
174
- if @config['tags']
175
- @config['tags'].each_pair do |tag, snippet|
176
- tags << "@#{tag}" if @content.include?(snippet)
177
- end
178
- end
179
- unless tags.empty?
180
- content = tags.join(' ') + "\n" + content
181
- # tags.each do |tag|
182
- # content.gsub!(@config['tags'][tag.gsub('@', '')], '')
183
- # end
184
- end
185
-
186
- scenario_title_compressed = title.anchorize
187
- feature_filename = title.parameterize
188
112
 
189
- dirpath = @config['mappings'][id]
113
+ terminate "No scenarios found in doc #{id}" if 0 == found
114
+ combined.each do |title, content|
190
115
 
116
+ feature_filename = title.parameterize
117
+ dirpath = mappings[id]
191
118
  FileUtils.mkdir_p(dirpath)
192
-
119
+
193
120
  fname = "#{dirpath}/#{feature_filename.gsub("\r", '').parameterize}.feature"
121
+ puts "Writing #{fname}"
194
122
  File.open(fname, 'w') do |f|
195
- puts "Writing #{fname}"
196
- f.write generated_by unless @skip_header
123
+ if @config['tags']
124
+ @config['tags'].each do |tag, token|
125
+ f.write "@#{tag}\n" if acceptance_criteria.include?(token)
126
+ end
127
+ end
197
128
  f.write "Feature: #{title}\n\n"
198
- link = @config['host'] + "/pages/viewpage.action?pageId=#{id}##{feature_title_compressed}-#{scenario_title_compressed}"
199
- f.write link
129
+ f.write @link_builder.view(id, confluence_page.title, title)
200
130
  f.write content
201
131
  end
202
132
  end
203
133
  end
204
-
205
- def process_tags(content)
206
- tags = []
207
- if @config['tags']
208
- @config['tags'].each_pair do |tag, snippet|
209
- tags << "@#{tag}" if content.include?(snippet)
210
- end
211
- end
212
- unless tags.empty?
213
- content = tags.join(' ') + "\n" + content
214
- tags.each do |tag|
215
- content.gsub!(@config['tags'][tag.gsub('@', '')], '')
216
- end
217
- end
218
- content
219
- end
220
-
221
- def save_file(content, filepath)
222
- dir_path = File.dirname(filepath)
223
134
 
224
- FileUtils.mkdir_p(dir_path) unless File.exists?(dir_path)
135
+ def validate_args
136
+ terminate "No action given" if @args.empty?
137
+ command = @args.first
138
+ terminate "Unknown action '#{@args.first}'" unless 'pull' == command
139
+ end
225
140
 
226
- File.open(filepath, 'w') do |f|
227
- puts "Writing #{filepath}"
228
- f.puts content
229
- end
141
+ def mappings
142
+ @config['mappings']
230
143
  end
231
144
 
232
- def validate_args args
233
- if args.empty?
234
- puts "No action given"
235
- exit(1)
236
- end
145
+ def terminate(message)
146
+ puts message
147
+ exit(1)
237
148
  end
238
-
149
+
239
150
  end
data/lib/link_builder.rb CHANGED
@@ -8,8 +8,10 @@ class LinkBuilder
8
8
  @host + '/pages/editpage.action?pageId=' + id.to_s
9
9
  end
10
10
 
11
- def view(id)
12
- @host + '/pages/viewpage.action?pageId=' + id.to_s
11
+ def view(id, feature=nil, scenario=nil)
12
+ link = @host + '/pages/viewpage.action?pageId=' + id.to_s
13
+ link += '#' + feature.anchorize if feature
14
+ link += '-' + scenario.anchorize if scenario
13
15
  end
14
16
 
15
17
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuki
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
4
+ hash: 9
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 10
10
- version: 0.0.10
9
+ - 11
10
+ version: 0.0.11
11
11
  platform: ruby
12
12
  authors:
13
13
  - Andy Waite
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-10-22 00:00:00 Z
18
+ date: 2011-10-23 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  requirement: &id001 !ruby/object:Gem::Requirement
@@ -169,7 +169,6 @@ files:
169
169
  - features/step_defs/pull_steps.rb
170
170
  - features/step_defs/push_steps.rb
171
171
  - features/support/env.rb
172
- - lib/cleaner.rb
173
172
  - lib/confluence_page.rb
174
173
  - lib/cuki.rb
175
174
  - lib/feature_file.rb
data/lib/cleaner.rb DELETED
@@ -1,32 +0,0 @@
1
- class Cleaner
2
-
3
- def self.clean(content)
4
-
5
- content.gsub!('&nbsp;', '')
6
-
7
- # remove the double pipes used for table headers in Confluence
8
- content.gsub!('||', '|')
9
-
10
- # remove other noise
11
- content.gsub!("\r\n", "\n")
12
- content.gsub!("\\\\\n", '')
13
- content.gsub!('\\', '')
14
-
15
- # remove any unwanted headers
16
- content.gsub!(/h\d\. (Scenario: .*)/, '\1')
17
- content.gsub!(/h\d\. (Scenario Outline: .*)/, '\1')
18
- content.gsub!(/h\d\. (Background: .*)/, '\1')
19
-
20
- #Remove fancy quotes
21
- content.gsub!('’', "'")
22
- content.gsub!('‘', "'")
23
- content.gsub!('“', '"')
24
- content.gsub!('”', '"')
25
-
26
- content.gsub!(/^#(.*)/, '-' + '\1')
27
-
28
- content
29
-
30
- end
31
-
32
- end