asciidoctor-confluence 0.0.2
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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rakeTasks +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.adoc +88 -0
- data/Rakefile +9 -0
- data/asciidoctor-confluence.gemspec +31 -0
- data/bin/asciidoctor-confluence +7 -0
- data/lib/asciidoctor/confluence.rb +69 -0
- data/lib/asciidoctor/confluence/invoker.rb +38 -0
- data/lib/asciidoctor/confluence/options.rb +93 -0
- data/lib/asciidoctor/confluence/version.rb +5 -0
- data/lib/asciidoctor/confluence_api.rb +99 -0
- data/lib/asciidoctor/page.rb +38 -0
- data/test/Asciidoctor/confluence/confluence_api_tests.rb +18 -0
- data/test/Asciidoctor/confluence/options_tests.rb +65 -0
- data/test/Asciidoctor/confluence/publisher_tests.rb +58 -0
- data/test/Asciidoctor/confluence/test.adoc +8 -0
- metadata +242 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d2cb76281aed69188ca0255ee7a6be3712432665
|
4
|
+
data.tar.gz: e96b1d629dfe599e86e64d35c42c08c0427bb68d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a14f538b0337c4ddc43412a6b1a7a56989b922ed338d4a119849d58cea04f12668c38b5a7cbf957e17f269e313f17fd3ed263f1ee60b167fcae902b70f26ff99
|
7
|
+
data.tar.gz: 4eaf3c09f948684045b27bb9b3d6858860e143693a4f91a376776b920dc55fd4a84796d1aa8cb63140db898cd543b7c7231aaefdbc67f7c4e07af64dfe55dd8a
|
data/.gitignore
ADDED
data/.rakeTasks
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<Settings><!--This file was automatically generated by Ruby plugin.
|
3
|
+
You are allowed to:
|
4
|
+
1. Remove rake task
|
5
|
+
2. Add existing rake tasks
|
6
|
+
To add existing rake tasks automatically delete this file and reload the project.
|
7
|
+
--><RakeGroup description="" fullCmd="" taksId="rake"><RakeTask description="Build asciidoctor-confluence-0.0.1.gem into the pkg directory" fullCmd="build" taksId="build" /><RakeTask description="Run tests" fullCmd="default" taksId="default" /><RakeTask description="Build and install asciidoctor-confluence-0.0.1.gem into system gems" fullCmd="install" taksId="install" /><RakeTask description="Create tag v0.0.1 and build and push asciidoctor-confluence-0.0.1.gem to Rubygems" fullCmd="release" taksId="release" /><RakeTask description="Run tests" fullCmd="test" taksId="test" /></RakeGroup></Settings>
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Guillaume Scheibel
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.adoc
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
:version: 0.0.1
|
2
|
+
:asciidoctor-base-version: 1.5.2
|
3
|
+
:confluence-version: 5.x
|
4
|
+
|
5
|
+
= Asciidoctor-Confluence {version}
|
6
|
+
|
7
|
+
Asciidoctor-confluence is a ruby gem that takes Asciidoc files, parse them using https://github.com/asciidoctor/asciidoctor[Asciidoctor] and push the result into https://www.atlassian.com/software/confluence[Confluence].
|
8
|
+
This gem currently supports Asciidoctor {asciidoctor-base-version} +
|
9
|
+
This gem is compatible with Confluence {confluence-version}
|
10
|
+
|
11
|
+
== How to use it ?
|
12
|
+
|
13
|
+
First you need to download and install the gem
|
14
|
+
|
15
|
+
[source, ruby]
|
16
|
+
----
|
17
|
+
gem install asciidoctor-confluence
|
18
|
+
----
|
19
|
+
|
20
|
+
Then to create a page
|
21
|
+
|
22
|
+
[source]
|
23
|
+
----
|
24
|
+
asciidoctor-confluence --host HOSTNAME --spaceKey SPACEKEY --title TITLE --username USERNAME --password PASSWORD file.adoc
|
25
|
+
----
|
26
|
+
|
27
|
+
To update a page
|
28
|
+
[source]
|
29
|
+
----
|
30
|
+
asciidoctor-confluence --host HOSTNAME --spaceKey SPACEKEY --title TITLE --username USERNAME --password PASSWORD --update file.adoc
|
31
|
+
#or
|
32
|
+
asciidoctor-confluence --host HOSTNAME --spaceKey SPACEKEY --title TITLE --username USERNAME --password PASSWORD --update --pageid PAGEID file.adoc
|
33
|
+
----
|
34
|
+
|
35
|
+
Here is the list of arguments that can used with this gem
|
36
|
+
|
37
|
+
.Gem parameters
|
38
|
+
|===
|
39
|
+
|Argument | Is mandatory | Role | Example
|
40
|
+
|
41
|
+
|host
|
42
|
+
|yes
|
43
|
+
|The hostname of the Confluence instance
|
44
|
+
|http://confluence.mydomain/
|
45
|
+
|
46
|
+
|spaceKey
|
47
|
+
|yes
|
48
|
+
|The space wihtin the page will be created
|
49
|
+
|'AS' in http://confluence.mydomain/display/AS/
|
50
|
+
|
51
|
+
|title
|
52
|
+
|yes
|
53
|
+
|The title of the Confluence page
|
54
|
+
|
|
55
|
+
|
56
|
+
|username
|
57
|
+
|no
|
58
|
+
|The username to use if the page has write restrictions
|
59
|
+
|
|
60
|
+
|
61
|
+
|password
|
62
|
+
|no
|
63
|
+
|The password associated to the account used to login into Confluence
|
64
|
+
|
|
65
|
+
|
66
|
+
|update
|
67
|
+
|false
|
68
|
+
|Indicate that the page must be updated instead of created. No values are required for this option
|
69
|
+
|
|
70
|
+
|
71
|
+
|pageid
|
72
|
+
|no
|
73
|
+
|The ID of the page you want to update, if it's not provided it will be determined using the space key and the title
|
74
|
+
|
|
75
|
+
|===
|
76
|
+
|
77
|
+
|
78
|
+
== Want to try it ?
|
79
|
+
|
80
|
+
If you want to try asciidoctor-confluence you need to
|
81
|
+
|
82
|
+
. Install the gem locally (at the moment it has not been publish to rubygem)
|
83
|
+
.. Clone the github repository locally `git clone https://github.com/gscheibel/asciidoctor-confluence.git`
|
84
|
+
.. Built it `gem build asciidoctor-confluence.gemspec`
|
85
|
+
.. Install it `gem install ./asciidoctor-confluence.{version}.gem`
|
86
|
+
.. To check it has been done correctly `asciidoctor-confluence -v` should display `asciidoctor-confluence: {version}`
|
87
|
+
. Have a Confluence instance
|
88
|
+
.. If you don't have a Confluence server, you can use a Docker container (e.i.: https://registry.hub.docker.com/u/cptactionhank/atlassian-confluence/), the option requires therefore an Atlassian account so it can generate a trial licence key.
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'asciidoctor/confluence/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "asciidoctor-confluence"
|
8
|
+
spec.version = Asciidoctor::Confluence::VERSION
|
9
|
+
spec.authors = ["Guillaume Scheibel"]
|
10
|
+
spec.email = ["guillaume.scheibel@gmail.com"]
|
11
|
+
spec.summary = "Publishing Asciidoctor content as Confluence page"
|
12
|
+
spec.description = "Asciidoctor-Confluence allows to parse asciidoc files, transform them into HTML and then push them into a Confluence"
|
13
|
+
spec.homepage = "http://asciidoctor.org"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = ['asciidoctor-confluence'] #spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.4', '>= 10.4.2'
|
23
|
+
spec.add_development_dependency 'test-unit', '~> 3.0', '>= 3.0.9'
|
24
|
+
spec.add_development_dependency 'rspec', '~> 3.1.0', '>= 3.1'
|
25
|
+
spec.add_development_dependency 'rspec-mocks', '~> 3.1.3', '>= 3.1'
|
26
|
+
spec.add_development_dependency 'webmock', '~> 1.20.4', '>= 1.20'
|
27
|
+
|
28
|
+
spec.add_runtime_dependency 'asciidoctor', '~> 1.5.2', '>= 1.5'
|
29
|
+
spec.add_runtime_dependency 'faraday', '~> 0.9.1', '>= 0.9'
|
30
|
+
spec.add_runtime_dependency 'json', '~> 1.8.2', '>= 1.8.2'
|
31
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative 'confluence/version'
|
2
|
+
require_relative './page'
|
3
|
+
require_relative './confluence_api'
|
4
|
+
|
5
|
+
require 'asciidoctor'
|
6
|
+
require 'faraday'
|
7
|
+
require 'json'
|
8
|
+
|
9
|
+
|
10
|
+
module Asciidoctor
|
11
|
+
module Confluence
|
12
|
+
|
13
|
+
class Publisher
|
14
|
+
SUCCESSFUL_CREATE_RESULT = 'The page has been successfully created. It is available here: '
|
15
|
+
SUCCESSFUL_UPDATE_RESULT = 'The page has been successfully updated. It is available here: '
|
16
|
+
|
17
|
+
def initialize(options)
|
18
|
+
@confluence_options = options[:confluence]
|
19
|
+
@asciidoctor_options = options
|
20
|
+
@asciidoctor_options[:to_file] = false
|
21
|
+
@asciidoctor_options[:header_footer] = false
|
22
|
+
|
23
|
+
if (options[:input_files].is_a? ::Array) && (options[:input_files].length == 1)
|
24
|
+
@input_file = options[:input_files][0]
|
25
|
+
else
|
26
|
+
@input_file = options[:input_files]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def publish
|
31
|
+
document = Asciidoctor.convert_file @input_file, @asciidoctor_options
|
32
|
+
page = Page.new @confluence_options[:space_key], @confluence_options[:title], document, @confluence_options[:page_id]
|
33
|
+
api = ConfluenceAPI.new @confluence_options, page
|
34
|
+
|
35
|
+
begin
|
36
|
+
response = api.create_or_update_page @confluence_options[:update], @confluence_options[:page_id]
|
37
|
+
|
38
|
+
response_body = JSON.parse response.body
|
39
|
+
if response.success?
|
40
|
+
url = response_body['_links']['base']+response_body['_links']['webui']
|
41
|
+
|
42
|
+
if @confluence_options[:update]
|
43
|
+
$stdout.puts SUCCESSFUL_UPDATE_RESULT + url
|
44
|
+
else
|
45
|
+
$stdout.puts SUCCESSFUL_CREATE_RESULT + url
|
46
|
+
end
|
47
|
+
return 0
|
48
|
+
else
|
49
|
+
action = get_action_string
|
50
|
+
show_error action, response_body['message']
|
51
|
+
return 1
|
52
|
+
end
|
53
|
+
rescue Exception => e
|
54
|
+
show_error get_action_string, e.message
|
55
|
+
end
|
56
|
+
return 0
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_action_string
|
60
|
+
@confluence_options[:update] ? action = 'updated' : action = 'created'
|
61
|
+
action
|
62
|
+
end
|
63
|
+
|
64
|
+
def show_error(action, message)
|
65
|
+
$stderr.puts "An error occurred, the page has not been #{action} because:\n#{message}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'asciidoctor'
|
2
|
+
require 'stringio'
|
3
|
+
require 'asciidoctor/cli'
|
4
|
+
require_relative './options'
|
5
|
+
require_relative '../confluence/invoker'
|
6
|
+
|
7
|
+
module Asciidoctor
|
8
|
+
module Confluence
|
9
|
+
|
10
|
+
class Invoker
|
11
|
+
def self.invoke(args)
|
12
|
+
begin
|
13
|
+
orig_stdout, orig_stderr = $stdout, $stderr
|
14
|
+
captured_stdout, captured_stderr = StringIO.new, StringIO.new
|
15
|
+
$stdout, $stderr = captured_stdout, captured_stderr
|
16
|
+
|
17
|
+
options = Asciidoctor::Confluence::Options.parse! args
|
18
|
+
unless invoke_helper_or_version(args)
|
19
|
+
publisher = Asciidoctor::Confluence::Publisher.new options
|
20
|
+
publisher.publish
|
21
|
+
end
|
22
|
+
ensure
|
23
|
+
$stderr = orig_stdout
|
24
|
+
$stdout = orig_stderr
|
25
|
+
|
26
|
+
$stderr.puts captured_stderr.string
|
27
|
+
$stdout.puts captured_stdout.string
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.invoke_helper_or_version(args)
|
32
|
+
helpers = %w(-h --help -V --version)
|
33
|
+
args.size == 1 && helpers.include?(args[0])
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'asciidoctor/cli/options'
|
2
|
+
require_relative '../confluence'
|
3
|
+
|
4
|
+
module Asciidoctor
|
5
|
+
module Confluence
|
6
|
+
|
7
|
+
class Options < Asciidoctor::Cli::Options
|
8
|
+
|
9
|
+
HOST_MISSING = 'FAILED: The hostname of the Confluence instance is missing'
|
10
|
+
SPACE_KEY_MISSING = 'FAILED: The spaceKey of the Confluence instance is missing'
|
11
|
+
TITLE_MISSING = 'FAILED: The title of the Confluence page is missing'
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
super options
|
15
|
+
self[:confluence] = options[:confluence] || {:update => false}
|
16
|
+
self[:confluence][:auth] = {} if self[:confluence][:auth].nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse!(args)
|
20
|
+
init_options args
|
21
|
+
unless args.empty?
|
22
|
+
base_options = super args
|
23
|
+
if (base_options.is_a? ::Integer) && base_options == -1
|
24
|
+
$stderr.puts 'There are some issue with the asciidoctor command'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def init_options(args)
|
32
|
+
opts_parser = ::OptionParser.new do |opts|
|
33
|
+
opts.banner = <<-EOS
|
34
|
+
Usage: asciidoctor-confluence --host HOSTNAME --spaceKey SPACEKEY --title TITLE [ASCIIDOCTOR OPTIONS]... FILE...
|
35
|
+
EOS
|
36
|
+
|
37
|
+
opts.on('--host HOST', 'the hostname of the Confluence instance ') do |host|
|
38
|
+
self[:confluence][:host] = host
|
39
|
+
end
|
40
|
+
|
41
|
+
opts.on('--spaceKey SPACEKEY', 'the Confluence space within the page will be created') do |spaceKey|
|
42
|
+
self[:confluence][:space_key] = spaceKey
|
43
|
+
end
|
44
|
+
|
45
|
+
opts.on('--title TITLE', 'the title of the Confluence page') do |title|
|
46
|
+
self[:confluence][:title] = title
|
47
|
+
end
|
48
|
+
|
49
|
+
opts.on('--pageid PAGEID', 'the id of the page to update') do |page_id|
|
50
|
+
self[:confluence][:page_id] = page_id
|
51
|
+
end
|
52
|
+
|
53
|
+
opts.on('--update', 'indicate that the page must be updated instead of created') do
|
54
|
+
self[:confluence][:update] = true
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.on('--username USERNAME', 'the username used if credential are need to create the page') do |spaceKey|
|
58
|
+
self[:confluence][:auth][:username] = spaceKey
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.on('--password PASSWORD', 'the password used if credential are need to create the page') do |spaceKey|
|
62
|
+
self[:confluence][:auth][:password] = spaceKey
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on_tail('-h', '--help', 'Show the full helper (including Asciidoctor helper)') do
|
66
|
+
$stdout.puts opts, "\n\n"
|
67
|
+
return Asciidoctor::Cli::Options.parse! ['-h']
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on_tail('-V', '--version', 'display the version and runtime environment (or -v if no other flags or arguments)') do
|
71
|
+
$stdout.puts "Asciidoctor-confluence v#{Asciidoctor::Confluence::VERSION}\n"
|
72
|
+
return Asciidoctor::Cli::Options.parse! ['-V']
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
opts_parser.parse! args
|
78
|
+
check_mandatory_options
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def check_mandatory_options
|
83
|
+
raise HOST_MISSING if self[:confluence][:host].nil?
|
84
|
+
raise SPACE_KEY_MISSING if self[:confluence][:space_key].nil?
|
85
|
+
raise TITLE_MISSING if self[:confluence][:title].nil?
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.parse! (*args)
|
89
|
+
Options.new.parse! args.flatten
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Asciidoctor
|
2
|
+
module Confluence
|
3
|
+
class ConfluenceAPI
|
4
|
+
|
5
|
+
DEFAULT_CONTENT_TYPE = 'application/json'
|
6
|
+
API_CONTENT = 'rest/api/content'
|
7
|
+
|
8
|
+
attr_reader :url
|
9
|
+
@page
|
10
|
+
@auth
|
11
|
+
|
12
|
+
def initialize(confluence_options, page)
|
13
|
+
@url = build_api_content_url(confluence_options)
|
14
|
+
@auth = confluence_options[:auth] unless confluence_options[:auth].nil?
|
15
|
+
@page = page
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_api_content_url(confluence_options)
|
19
|
+
host = confluence_options[:host]
|
20
|
+
host = host + '/' unless confluence_options[:host].end_with?('/')
|
21
|
+
host+ API_CONTENT
|
22
|
+
end
|
23
|
+
|
24
|
+
def create_connection
|
25
|
+
conn = Faraday.new do |faraday|
|
26
|
+
faraday.request :url_encoded
|
27
|
+
faraday.adapter Faraday.default_adapter
|
28
|
+
end
|
29
|
+
|
30
|
+
conn.basic_auth(@auth[:username], @auth[:password]) unless @auth.nil?
|
31
|
+
conn
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_or_update_page(update=false, page_id=nil)
|
35
|
+
if update
|
36
|
+
if page_id.nil?
|
37
|
+
confluence_page = find_page_by_title_and_space(@page.space_key, @page.title)
|
38
|
+
response_body = JSON.parse confluence_page.body
|
39
|
+
results = response_body['results']
|
40
|
+
|
41
|
+
length = results.length
|
42
|
+
|
43
|
+
if length == 1
|
44
|
+
page_id = results[0]['id']
|
45
|
+
current_revision = results[0]['version']['number']
|
46
|
+
else
|
47
|
+
plural = length > 0 ? 's' : ''
|
48
|
+
raise Exception, "Error: #{length} page#{plural} entitled '#{@page.title}' found in the space '#{@page.space_key}'"
|
49
|
+
end
|
50
|
+
else
|
51
|
+
confluence_page = find_page page_id
|
52
|
+
response_body = JSON.parse confluence_page.body
|
53
|
+
current_revision = response_body['version']['number']
|
54
|
+
end
|
55
|
+
|
56
|
+
update_page page_id, current_revision
|
57
|
+
else
|
58
|
+
create_page
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def create_page
|
63
|
+
conn = create_connection
|
64
|
+
conn.post do |req|
|
65
|
+
req.url @url
|
66
|
+
req.headers['Content-Type'] = DEFAULT_CONTENT_TYPE
|
67
|
+
req.body = @page.to_json
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def update_page(page_id, current_revision)
|
72
|
+
@page.revision = current_revision.to_i+1
|
73
|
+
|
74
|
+
conn = create_connection
|
75
|
+
conn.put do |req|
|
76
|
+
req.url "#{@url}/#{page_id}"
|
77
|
+
req.headers['Content-Type'] = DEFAULT_CONTENT_TYPE
|
78
|
+
req.body = @page.to_json
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def find_page_by_title_and_space(space_key, title)
|
83
|
+
conn = create_connection
|
84
|
+
conn.get do |req|
|
85
|
+
req.url "#{@url}/?spaceKey=#{space_key}&title=#{title}&expand=version"
|
86
|
+
req.headers['Content-Type'] = DEFAULT_CONTENT_TYPE
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def find_page(page_id)
|
91
|
+
conn = create_connection
|
92
|
+
conn.get do |req|
|
93
|
+
req.url "#{@url}/#{page_id}"
|
94
|
+
req.headers['Content-Type'] = DEFAULT_CONTENT_TYPE
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Page
|
2
|
+
|
3
|
+
TYPE = 'page'
|
4
|
+
REPRESENTATION = 'storage'
|
5
|
+
@document
|
6
|
+
|
7
|
+
attr_reader :page_id, :title, :space_key
|
8
|
+
attr_writer :revision
|
9
|
+
|
10
|
+
def initialize(space_key, title, document, page_id)
|
11
|
+
@space_key = space_key
|
12
|
+
@title = title
|
13
|
+
@document = document
|
14
|
+
@page_id = page_id
|
15
|
+
@revision = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json
|
19
|
+
page = {
|
20
|
+
:type => TYPE,
|
21
|
+
:title => @title,
|
22
|
+
:space => {
|
23
|
+
:key => @space_key
|
24
|
+
},
|
25
|
+
:body => {
|
26
|
+
:storage => {
|
27
|
+
:value => @document,
|
28
|
+
:representation => REPRESENTATION
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
33
|
+
page[:version] = {:number => @revision} unless @revision.nil?
|
34
|
+
page[:id] = @page_id unless @page_id.nil?
|
35
|
+
|
36
|
+
JSON.generate page
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'asciidoctor/confluence_api'
|
3
|
+
|
4
|
+
class ConfluenceAPITests < Test::Unit::TestCase
|
5
|
+
def test_build_content_api_without_ending_slash
|
6
|
+
url = 'http://confluence.mydomain'
|
7
|
+
api = Asciidoctor::Confluence::ConfluenceAPI.new({:host => url}, nil)
|
8
|
+
assert_equal url+'/'+Asciidoctor::Confluence::ConfluenceAPI::API_CONTENT, api.url
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_build_content_api_with_ending_slash
|
12
|
+
url = 'http://confluence.mydomain/'
|
13
|
+
api = Asciidoctor::Confluence::ConfluenceAPI.new({:host => url}, nil)
|
14
|
+
assert_equal url+Asciidoctor::Confluence::ConfluenceAPI::API_CONTENT, api.url
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'asciidoctor/confluence/options'
|
3
|
+
|
4
|
+
class OptionsTests < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@orig_stderr = $stderr
|
7
|
+
$stderr = StringIO.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def teardown
|
11
|
+
$stderr = @orig_stderr
|
12
|
+
@orig_stderr = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_init_options
|
16
|
+
options = Asciidoctor::Confluence::Options.new
|
17
|
+
host = 'http://hostname'
|
18
|
+
space_key = 'key'
|
19
|
+
title = 'title'
|
20
|
+
username = 'username'
|
21
|
+
password = 'pass'
|
22
|
+
file_name = 'file.adoc'
|
23
|
+
base_options = options.init_options ['--host', host, '--spaceKey', space_key, '--title', title, '--username', username, '--password', password, file_name]
|
24
|
+
|
25
|
+
assert_equal 1, base_options.size
|
26
|
+
assert_equal file_name, base_options[0]
|
27
|
+
assert_equal host, options[:confluence][:host]
|
28
|
+
assert_equal space_key, options[:confluence][:space_key]
|
29
|
+
assert_equal title, options[:confluence][:title]
|
30
|
+
assert_equal username, options[:confluence][:auth][:username]
|
31
|
+
assert_equal password, options[:confluence][:auth][:password]
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_with_full_options
|
35
|
+
args = {:confluence => {:host => 'http://hostname/', :space_key => 'TEST_KEY', :title =>'Test title'}}
|
36
|
+
options = Asciidoctor::Confluence::Options.new args
|
37
|
+
res = options.check_mandatory_options
|
38
|
+
assert_equal 1, res
|
39
|
+
assert_true $stderr.string.nil_or_empty?
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_host_not_present
|
44
|
+
options = Asciidoctor::Confluence::Options.new
|
45
|
+
res = options.check_mandatory_options
|
46
|
+
assert_equal 0, res
|
47
|
+
assert_true($stderr.string.include? Asciidoctor::Confluence::Options::HOST_MISSING)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_space_key_not_present
|
51
|
+
args = {:confluence => {:host => 'http://hostname/'}}
|
52
|
+
options = Asciidoctor::Confluence::Options.new args
|
53
|
+
res = options.check_mandatory_options
|
54
|
+
assert_equal 0, res
|
55
|
+
assert_true($stderr.string.include? Asciidoctor::Confluence::Options::SPACE_KEY_MISSING)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_title_not_present
|
59
|
+
args = {:confluence => {:host => 'http://hostname/', :space_key => 'TEST_KEY'}}
|
60
|
+
options = Asciidoctor::Confluence::Options.new args
|
61
|
+
res = options.check_mandatory_options
|
62
|
+
assert_equal 0, res
|
63
|
+
assert_true($stderr.string.include? Asciidoctor::Confluence::Options::TITLE_MISSING)
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test-unit'
|
2
|
+
require 'webmock/test_unit'
|
3
|
+
require 'asciidoctor/confluence_api'
|
4
|
+
require 'asciidoctor/confluence'
|
5
|
+
|
6
|
+
#require 'asciidoctor-confluence/lib/asciidoctor/confluence'
|
7
|
+
|
8
|
+
class PublisherTests < Test::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@orig_stderr = $stderr
|
11
|
+
$stderr = StringIO.new
|
12
|
+
|
13
|
+
@orig_stdout = $stdout
|
14
|
+
$stdout = StringIO.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
$stderr = @orig_stderr
|
19
|
+
@orig_stderr
|
20
|
+
$stdout = @orig_stdout
|
21
|
+
@orig_stdout = nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_successful_publishing
|
25
|
+
test_url = 'http://username:password@confluence.domain/'+Asciidoctor::Confluence::ConfluenceAPI::API_CONTENT
|
26
|
+
host = 'http://confluence.domain/'
|
27
|
+
webui = 'webui'
|
28
|
+
response_body = JSON.generate ( {
|
29
|
+
'_links' => {
|
30
|
+
'base' => host,
|
31
|
+
'webui' => webui
|
32
|
+
}
|
33
|
+
})
|
34
|
+
stub_request(:post, test_url).to_return(:status => 200, :body => response_body)
|
35
|
+
auth = {:username => 'username', :password => 'password'}
|
36
|
+
options = {:confluence => {:auth => auth, :host => host, :title => 'Asciidoctor Page'}, :input_files => ['test.adoc']}
|
37
|
+
publisher = Asciidoctor::Confluence::Publisher.new options
|
38
|
+
publish_result = publisher.publish
|
39
|
+
assert_equal 0, publish_result
|
40
|
+
assert_true $stdout.string.include? Asciidoctor::Confluence::Publisher::SUCCESSFUL_RESULT+host+webui
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_failing_publishing
|
44
|
+
test_url = 'http://username:password@confluence.domain/'+Asciidoctor::Confluence::ConfluenceAPI::API_CONTENT
|
45
|
+
host = 'http://confluence.domain/'
|
46
|
+
error_message = 'The page already exists'
|
47
|
+
response_body = JSON.generate ( {
|
48
|
+
'message' => error_message
|
49
|
+
})
|
50
|
+
stub_request(:post, test_url).to_return(:status => 400, :body => response_body)
|
51
|
+
auth = {:username => 'username', :password => 'password'}
|
52
|
+
options = {:confluence => {:auth => auth, :host => host, :title => 'Asciidoctor Page'}, :input_files => ['test.adoc']}
|
53
|
+
publisher = Asciidoctor::Confluence::Publisher.new options
|
54
|
+
publish_result = publisher.publish
|
55
|
+
assert_equal 1, publish_result
|
56
|
+
assert_true $stderr.string.include? error_message
|
57
|
+
end
|
58
|
+
end
|
metadata
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: asciidoctor-confluence
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guillaume Scheibel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-11 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.4'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 10.4.2
|
37
|
+
type: :development
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '10.4'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 10.4.2
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: test-unit
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '3.0'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 3.0.9
|
57
|
+
type: :development
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '3.0'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 3.0.9
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rspec
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 3.1.0
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '3.1'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 3.1.0
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '3.1'
|
87
|
+
- !ruby/object:Gem::Dependency
|
88
|
+
name: rspec-mocks
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - "~>"
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 3.1.3
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.1'
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 3.1.3
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '3.1'
|
107
|
+
- !ruby/object:Gem::Dependency
|
108
|
+
name: webmock
|
109
|
+
requirement: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - "~>"
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 1.20.4
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '1.20'
|
117
|
+
type: :development
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 1.20.4
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
version: '1.20'
|
127
|
+
- !ruby/object:Gem::Dependency
|
128
|
+
name: asciidoctor
|
129
|
+
requirement: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - "~>"
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: 1.5.2
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '1.5'
|
137
|
+
type: :runtime
|
138
|
+
prerelease: false
|
139
|
+
version_requirements: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - "~>"
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: 1.5.2
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '1.5'
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
name: faraday
|
149
|
+
requirement: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - "~>"
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: 0.9.1
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0.9'
|
157
|
+
type: :runtime
|
158
|
+
prerelease: false
|
159
|
+
version_requirements: !ruby/object:Gem::Requirement
|
160
|
+
requirements:
|
161
|
+
- - "~>"
|
162
|
+
- !ruby/object:Gem::Version
|
163
|
+
version: 0.9.1
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.9'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: json
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 1.8.2
|
174
|
+
- - ">="
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: 1.8.2
|
177
|
+
type: :runtime
|
178
|
+
prerelease: false
|
179
|
+
version_requirements: !ruby/object:Gem::Requirement
|
180
|
+
requirements:
|
181
|
+
- - "~>"
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: 1.8.2
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: 1.8.2
|
187
|
+
description: Asciidoctor-Confluence allows to parse asciidoc files, transform them
|
188
|
+
into HTML and then push them into a Confluence
|
189
|
+
email:
|
190
|
+
- guillaume.scheibel@gmail.com
|
191
|
+
executables:
|
192
|
+
- asciidoctor-confluence
|
193
|
+
extensions: []
|
194
|
+
extra_rdoc_files: []
|
195
|
+
files:
|
196
|
+
- ".gitignore"
|
197
|
+
- ".rakeTasks"
|
198
|
+
- Gemfile
|
199
|
+
- LICENSE.txt
|
200
|
+
- README.adoc
|
201
|
+
- Rakefile
|
202
|
+
- asciidoctor-confluence.gemspec
|
203
|
+
- bin/asciidoctor-confluence
|
204
|
+
- lib/asciidoctor/confluence.rb
|
205
|
+
- lib/asciidoctor/confluence/invoker.rb
|
206
|
+
- lib/asciidoctor/confluence/options.rb
|
207
|
+
- lib/asciidoctor/confluence/version.rb
|
208
|
+
- lib/asciidoctor/confluence_api.rb
|
209
|
+
- lib/asciidoctor/page.rb
|
210
|
+
- test/Asciidoctor/confluence/confluence_api_tests.rb
|
211
|
+
- test/Asciidoctor/confluence/options_tests.rb
|
212
|
+
- test/Asciidoctor/confluence/publisher_tests.rb
|
213
|
+
- test/Asciidoctor/confluence/test.adoc
|
214
|
+
homepage: http://asciidoctor.org
|
215
|
+
licenses:
|
216
|
+
- MIT
|
217
|
+
metadata: {}
|
218
|
+
post_install_message:
|
219
|
+
rdoc_options: []
|
220
|
+
require_paths:
|
221
|
+
- lib
|
222
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
223
|
+
requirements:
|
224
|
+
- - ">="
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '0'
|
227
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
228
|
+
requirements:
|
229
|
+
- - ">="
|
230
|
+
- !ruby/object:Gem::Version
|
231
|
+
version: '0'
|
232
|
+
requirements: []
|
233
|
+
rubyforge_project:
|
234
|
+
rubygems_version: 2.2.2
|
235
|
+
signing_key:
|
236
|
+
specification_version: 4
|
237
|
+
summary: Publishing Asciidoctor content as Confluence page
|
238
|
+
test_files:
|
239
|
+
- test/Asciidoctor/confluence/confluence_api_tests.rb
|
240
|
+
- test/Asciidoctor/confluence/options_tests.rb
|
241
|
+
- test/Asciidoctor/confluence/publisher_tests.rb
|
242
|
+
- test/Asciidoctor/confluence/test.adoc
|