cuki 0.0.10 → 0.0.11

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/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