Add support for PlantUML diagrams in Asciidoc.
This MR enables rendering of PlantUML diagrams in Asciidoc documents. To add a PlantUML diagram all we need is to include a plantuml block like: ``` [plantuml, id="myDiagram", width="100px", height="100px"] -- bob -> alice : ping alice -> bob : pong -- ``` The plantuml block is substituted by an HTML img element with *src* pointing to an external PlantUML server. This MR also add a PlantUML integration section to the Administrator -> Settings page to configure the PlantUML rendering service and to enable/disable it. Closes: #17603
This commit is contained in:
parent
826adaaff8
commit
f986b4c4e5
19 changed files with 206 additions and 16 deletions
25
Gemfile
25
Gemfile
|
@ -99,18 +99,19 @@ gem 'unf', '~> 0.1.4'
|
|||
gem 'seed-fu', '~> 2.3.5'
|
||||
|
||||
# Markdown and HTML processing
|
||||
gem 'html-pipeline', '~> 1.11.0'
|
||||
gem 'deckar01-task_list', '1.0.6', require: 'task_list/railtie'
|
||||
gem 'gitlab-markup', '~> 1.5.1'
|
||||
gem 'redcarpet', '~> 3.3.3'
|
||||
gem 'RedCloth', '~> 4.3.2'
|
||||
gem 'rdoc', '~> 4.2'
|
||||
gem 'org-ruby', '~> 0.9.12'
|
||||
gem 'creole', '~> 0.5.0'
|
||||
gem 'wikicloth', '0.8.1'
|
||||
gem 'asciidoctor', '~> 1.5.2'
|
||||
gem 'rouge', '~> 2.0'
|
||||
gem 'truncato', '~> 0.7.8'
|
||||
gem 'html-pipeline', '~> 1.11.0'
|
||||
gem 'deckar01-task_list', '1.0.6', require: 'task_list/railtie'
|
||||
gem 'gitlab-markup', '~> 1.5.0'
|
||||
gem 'redcarpet', '~> 3.3.3'
|
||||
gem 'RedCloth', '~> 4.3.2'
|
||||
gem 'rdoc', '~> 4.2'
|
||||
gem 'org-ruby', '~> 0.9.12'
|
||||
gem 'creole', '~> 0.5.0'
|
||||
gem 'wikicloth', '0.8.1'
|
||||
gem 'asciidoctor', '~> 1.5.2'
|
||||
gem 'asciidoctor-plantuml', '0.0.6'
|
||||
gem 'rouge', '~> 2.0'
|
||||
gem 'truncato', '~> 0.7.8'
|
||||
|
||||
# See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s
|
||||
# and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM
|
||||
|
|
|
@ -54,6 +54,8 @@ GEM
|
|||
faraday_middleware-multi_json (~> 0.0)
|
||||
oauth2 (~> 1.0)
|
||||
asciidoctor (1.5.3)
|
||||
asciidoctor-plantuml (0.0.6)
|
||||
asciidoctor (~> 1.5)
|
||||
ast (2.3.0)
|
||||
attr_encrypted (3.0.3)
|
||||
encryptor (~> 3.0.0)
|
||||
|
@ -841,6 +843,7 @@ DEPENDENCIES
|
|||
allocations (~> 1.0)
|
||||
asana (~> 0.4.0)
|
||||
asciidoctor (~> 1.5.2)
|
||||
asciidoctor-plantuml (= 0.0.6)
|
||||
attr_encrypted (~> 3.0.0)
|
||||
awesome_print (~> 1.2.0)
|
||||
babosa (~> 1.0.2)
|
||||
|
|
|
@ -101,6 +101,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
|
|||
:html_emails_enabled,
|
||||
:koding_enabled,
|
||||
:koding_url,
|
||||
:plantuml_enabled,
|
||||
:plantuml_url,
|
||||
:max_artifacts_size,
|
||||
:max_attachment_size,
|
||||
:metrics_enabled,
|
||||
|
|
|
@ -68,6 +68,10 @@ class ApplicationSetting < ActiveRecord::Base
|
|||
presence: true,
|
||||
if: :koding_enabled
|
||||
|
||||
validates :plantuml_url,
|
||||
presence: true,
|
||||
if: :plantuml_enabled
|
||||
|
||||
validates :max_attachment_size,
|
||||
presence: true,
|
||||
numericality: { only_integer: true, greater_than: 0 }
|
||||
|
@ -184,6 +188,8 @@ class ApplicationSetting < ActiveRecord::Base
|
|||
akismet_enabled: false,
|
||||
koding_enabled: false,
|
||||
koding_url: nil,
|
||||
plantuml_enabled: false,
|
||||
plantuml_url: nil,
|
||||
repository_checks_enabled: true,
|
||||
disabled_oauth_sign_in_sources: [],
|
||||
send_user_confirmation_email: false,
|
||||
|
|
|
@ -420,6 +420,23 @@
|
|||
= succeed "." do
|
||||
= link_to "Koding administration documentation", help_page_path("administration/integration/koding")
|
||||
|
||||
%fieldset
|
||||
%legend PlantUML
|
||||
.form-group
|
||||
.col-sm-offset-2.col-sm-10
|
||||
.checkbox
|
||||
= f.label :plantuml_enabled do
|
||||
= f.check_box :plantuml_enabled
|
||||
Enable PlantUML
|
||||
.form-group
|
||||
= f.label :plantuml_url, 'PlantUML URL', class: 'control-label col-sm-2'
|
||||
.col-sm-10
|
||||
= f.text_field :plantuml_url, class: 'form-control', placeholder: 'http://gitlab.your-plantuml-instance.com:8080'
|
||||
.help-block
|
||||
Allow rendering of
|
||||
= link_to "PlantUML", "http://plantuml.com"
|
||||
diagrams in Asciidoc documents using an external PlantUML service.
|
||||
|
||||
%fieldset
|
||||
%legend Usage statistics
|
||||
.form-group
|
||||
|
|
4
changelogs/unreleased/asciidoctor-plantuml.yml
Normal file
4
changelogs/unreleased/asciidoctor-plantuml.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Add support for PlantUML diagrams in AsciiDoc documents.
|
||||
merge_request: 7810
|
||||
author: Horacio Sanson
|
|
@ -0,0 +1,12 @@
|
|||
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class AddPlantUmlUrlToApplicationSettings < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def change
|
||||
add_column :application_settings, :plantuml_url, :string
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class AddPlantUmlEnabledToApplicationSettings < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def change
|
||||
add_column :application_settings, :plantuml_enabled, :boolean
|
||||
end
|
||||
end
|
|
@ -107,6 +107,8 @@ ActiveRecord::Schema.define(version: 20170106172224) do
|
|||
t.integer "housekeeping_full_repack_period", default: 50, null: false
|
||||
t.integer "housekeeping_gc_period", default: 200, null: false
|
||||
t.boolean "html_emails_enabled", default: true
|
||||
t.string "plantuml_url"
|
||||
t.boolean "plantuml_enabled"
|
||||
end
|
||||
|
||||
create_table "audit_events", force: :cascade do |t|
|
||||
|
|
BIN
doc/administration/img/integration/plantuml-example.png
Normal file
BIN
doc/administration/img/integration/plantuml-example.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
87
doc/administration/integration/plantuml.md
Normal file
87
doc/administration/integration/plantuml.md
Normal file
|
@ -0,0 +1,87 @@
|
|||
# PlantUML & GitLab
|
||||
|
||||
> [Introduced][ce-7810] in GitLab 8.16.
|
||||
|
||||
When [PlantUML](http://plantuml.com) integration is enabled and configured in
|
||||
GitLab we are able to create simple diagrams in AsciiDoc documents created in
|
||||
snippets, wikis, and repos.
|
||||
|
||||
## PlantUML Server
|
||||
|
||||
Before you can enable PlantUML in GitLab; you need to set up your own PlantUML
|
||||
server that will generate the diagrams. Installing and configuring your
|
||||
own PlantUML server is easy in Debian/Ubuntu distributions using Tomcat.
|
||||
|
||||
First you need to create a `plantuml.war` file from the source code:
|
||||
|
||||
```
|
||||
sudo apt-get install graphviz openjdk-7-jdk git-core maven
|
||||
git clone https://github.com/plantuml/plantuml-server.git
|
||||
cd plantuml-server
|
||||
mvn package
|
||||
```
|
||||
|
||||
The above sequence of commands will generate a WAR file that can be deployed
|
||||
using Tomcat:
|
||||
|
||||
```
|
||||
sudo apt-get install tomcat7
|
||||
sudo cp target/plantuml.war /var/lib/tomcat7/webapps/plantuml.war
|
||||
sudo chown tomcat7:tomcat7 /var/lib/tomcat7/webapps/plantuml.war
|
||||
sudo service restart tomcat7
|
||||
```
|
||||
|
||||
Once the Tomcat service restarts the PlantUML service will be ready and
|
||||
listening for requests on port 8080:
|
||||
|
||||
```
|
||||
http://localhost:8080/plantuml
|
||||
```
|
||||
|
||||
you can change these defaults by editing the `/etc/tomcat7/server.xml` file.
|
||||
|
||||
|
||||
## GitLab
|
||||
|
||||
You need to enable PlantUML integration from Settings under Admin Area. To do
|
||||
that, login with an Admin account and do following:
|
||||
|
||||
- in GitLab go to **Admin Area** and then **Settings**
|
||||
- scroll to bottom of the page until PlantUML section
|
||||
- check **Enable PlantUML** checkbox
|
||||
- set the PlantUML instance as **PlantUML URL**
|
||||
|
||||
## Creating Diagrams
|
||||
|
||||
With PlantUML integration enabled and configured, we can start adding diagrams to
|
||||
our AsciiDoc snippets, wikis and repos using blocks:
|
||||
|
||||
```
|
||||
[plantuml, format="png", id="myDiagram", width="200px"]
|
||||
--
|
||||
Bob->Alice : hello
|
||||
Alice -> Bob : Go Away
|
||||
--
|
||||
```
|
||||
|
||||
The above block will be converted to an HTML img tag with source pointing to the
|
||||
PlantUML instance. If the PlantUML server is correctly configured, this should
|
||||
render a nice diagram instead of the block:
|
||||
|
||||
![PlantUML Integration](../img/integration/plantuml-example.png)
|
||||
|
||||
Inside the block you can add any of the supported diagrams by PlantUML such as
|
||||
[Sequence](http://plantuml.com/sequence-diagram), [Use Case](http://plantuml.com/use-case-diagram),
|
||||
[Class](http://plantuml.com/class-diagram), [Activity](http://plantuml.com/activity-diagram-legacy),
|
||||
[Component](http://plantuml.com/component-diagram), [State](http://plantuml.com/state-diagram),
|
||||
and [Object](http://plantuml.com/object-diagram) diagrams. You do not need to use the PlantUML
|
||||
diagram delimiters `@startuml`/`@enduml` as these are replaced by the AsciiDoc `plantuml` block.
|
||||
|
||||
Some parameters can be added to the block definition:
|
||||
|
||||
- *format*: Can be either `png` or `svg`. Note that `svg` is not supported by
|
||||
all browsers so use with care. The default is `png`.
|
||||
- *id*: A CSS id added to the diagram HTML tag.
|
||||
- *width*: Width attribute added to the img tag.
|
||||
- *height*: Height attribute added to the img tag.
|
||||
|
|
@ -44,7 +44,9 @@ Example response:
|
|||
"repository_storage": "default",
|
||||
"repository_storages": ["default"],
|
||||
"koding_enabled": false,
|
||||
"koding_url": null
|
||||
"koding_url": null,
|
||||
"plantuml_enabled": false,
|
||||
"plantuml_url": null
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -80,6 +82,8 @@ PUT /application/settings
|
|||
| `koding_enabled` | boolean | no | Enable Koding integration. Default is `false`. |
|
||||
| `koding_url` | string | yes (if `koding_enabled` is `true`) | The Koding instance URL for integration. |
|
||||
| `disabled_oauth_sign_in_sources` | Array of strings | no | Disabled OAuth sign-in sources |
|
||||
| `plantuml_enabled` | boolean | no | Enable PlantUML integration. Default is `false`. |
|
||||
| `plantuml_url` | string | yes (if `plantuml_enabled` is `true`) | The PlantUML instance URL for integration. |
|
||||
|
||||
```bash
|
||||
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/application/settings?signup_enabled=false&default_project_visibility=1
|
||||
|
@ -112,6 +116,8 @@ Example response:
|
|||
"container_registry_token_expire_delay": 5,
|
||||
"repository_storage": "default",
|
||||
"koding_enabled": false,
|
||||
"koding_url": null
|
||||
"koding_url": null,
|
||||
"plantuml_enabled": false,
|
||||
"plantuml_url": null
|
||||
}
|
||||
```
|
||||
|
|
|
@ -16,6 +16,7 @@ See the documentation below for details on how to configure these services.
|
|||
- [reCAPTCHA](recaptcha.md) Configure GitLab to use Google reCAPTCHA for new users
|
||||
- [Akismet](akismet.md) Configure Akismet to stop spam
|
||||
- [Koding](../administration/integration/koding.md) Configure Koding to use IDE integration
|
||||
- [PlantUML](../administration/integration/plantuml.md) Configure PlantUML to use diagrams in AsciiDoc documents.
|
||||
|
||||
GitLab Enterprise Edition contains [advanced Jenkins support][jenkins].
|
||||
|
||||
|
|
|
@ -565,6 +565,8 @@ module API
|
|||
expose :repository_storages
|
||||
expose :koding_enabled
|
||||
expose :koding_url
|
||||
expose :plantuml_enabled
|
||||
expose :plantuml_url
|
||||
end
|
||||
|
||||
class Release < Grape::Entity
|
||||
|
|
|
@ -93,6 +93,10 @@ module API
|
|||
given koding_enabled: ->(val) { val } do
|
||||
requires :koding_url, type: String, desc: 'The Koding team URL'
|
||||
end
|
||||
optional :plantuml_enabled, type: Boolean, desc: 'Enable PlantUML'
|
||||
given plantuml_enabled: ->(val) { val } do
|
||||
requires :plantuml_url, type: String, desc: 'The PlantUML server URL'
|
||||
end
|
||||
optional :version_check_enabled, type: Boolean, desc: 'Let GitLab inform you when an update is available.'
|
||||
optional :email_author_in_body, type: Boolean, desc: 'Some email servers do not support overriding the email sender name. Enable this option to include the name of the author of the issue, merge request or comment in the email body instead.'
|
||||
optional :html_emails_enabled, type: Boolean, desc: 'By default GitLab sends emails in HTML and plain text formats so mail clients can choose what format to use. Disable this option if you only want to send emails in plain text format.'
|
||||
|
@ -114,7 +118,7 @@ module API
|
|||
:shared_runners_enabled, :max_artifacts_size, :container_registry_token_expire_delay,
|
||||
:metrics_enabled, :sidekiq_throttling_enabled, :recaptcha_enabled,
|
||||
:akismet_enabled, :admin_notification_email, :sentry_enabled,
|
||||
:repository_storage, :repository_checks_enabled, :koding_enabled,
|
||||
:repository_storage, :repository_checks_enabled, :koding_enabled, :plantuml_enabled,
|
||||
:version_check_enabled, :email_author_in_body, :html_emails_enabled,
|
||||
:housekeeping_enabled
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'asciidoctor'
|
||||
require 'asciidoctor/converter/html5'
|
||||
require "asciidoctor-plantuml"
|
||||
|
||||
module Gitlab
|
||||
# Parser/renderer for the AsciiDoc format that uses Asciidoctor and filters
|
||||
|
@ -29,6 +30,8 @@ module Gitlab
|
|||
)
|
||||
asciidoc_opts[:attributes].unshift(*DEFAULT_ADOC_ATTRS)
|
||||
|
||||
plantuml_setup
|
||||
|
||||
html = ::Asciidoctor.convert(input, asciidoc_opts)
|
||||
|
||||
html = Banzai.post_process(html, context)
|
||||
|
@ -36,6 +39,15 @@ module Gitlab
|
|||
html.html_safe
|
||||
end
|
||||
|
||||
def self.plantuml_setup
|
||||
Asciidoctor::PlantUml.configure do |conf|
|
||||
conf.url = ApplicationSetting.current.plantuml_url
|
||||
conf.svg_enable = ApplicationSetting.current.plantuml_enabled
|
||||
conf.png_enable = ApplicationSetting.current.plantuml_enabled
|
||||
conf.txt_enable = false
|
||||
end
|
||||
end
|
||||
|
||||
class Html5Converter < Asciidoctor::Converter::Html5Converter
|
||||
extend Asciidoctor::Converter::Config
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ module Gitlab
|
|||
signin_enabled: Settings.gitlab['signin_enabled'],
|
||||
gravatar_enabled: Settings.gravatar['enabled'],
|
||||
koding_enabled: false,
|
||||
plantuml_enabled: false,
|
||||
sign_in_text: nil,
|
||||
after_sign_up_text: nil,
|
||||
help_page_text: nil,
|
||||
|
|
|
@ -8,6 +8,10 @@ module Gitlab
|
|||
let(:html) { 'H<sub>2</sub>O' }
|
||||
|
||||
context "without project" do
|
||||
before do
|
||||
allow_any_instance_of(ApplicationSetting).to receive(:current).and_return(::ApplicationSetting.create_from_defaults)
|
||||
end
|
||||
|
||||
it "converts the input using Asciidoctor and default options" do
|
||||
expected_asciidoc_opts = {
|
||||
safe: :secure,
|
||||
|
|
|
@ -16,6 +16,8 @@ describe API::Settings, 'Settings', api: true do
|
|||
expect(json_response['repository_storage']).to eq('default')
|
||||
expect(json_response['koding_enabled']).to be_falsey
|
||||
expect(json_response['koding_url']).to be_nil
|
||||
expect(json_response['plantuml_enabled']).to be_falsey
|
||||
expect(json_response['plantuml_url']).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -28,7 +30,8 @@ describe API::Settings, 'Settings', api: true do
|
|||
|
||||
it "updates application settings" do
|
||||
put api("/application/settings", admin),
|
||||
default_projects_limit: 3, signin_enabled: false, repository_storage: 'custom', koding_enabled: true, koding_url: 'http://koding.example.com'
|
||||
default_projects_limit: 3, signin_enabled: false, repository_storage: 'custom', koding_enabled: true, koding_url: 'http://koding.example.com',
|
||||
plantuml_enabled: true, plantuml_url: 'http://plantuml.example.com'
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json_response['default_projects_limit']).to eq(3)
|
||||
expect(json_response['signin_enabled']).to be_falsey
|
||||
|
@ -36,6 +39,8 @@ describe API::Settings, 'Settings', api: true do
|
|||
expect(json_response['repository_storages']).to eq(['custom'])
|
||||
expect(json_response['koding_enabled']).to be_truthy
|
||||
expect(json_response['koding_url']).to eq('http://koding.example.com')
|
||||
expect(json_response['plantuml_enabled']).to be_truthy
|
||||
expect(json_response['plantuml_url']).to eq('http://plantuml.example.com')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -47,5 +52,14 @@ describe API::Settings, 'Settings', api: true do
|
|||
expect(json_response['error']).to eq('koding_url is missing')
|
||||
end
|
||||
end
|
||||
|
||||
context "missing plantuml_url value when plantuml_enabled is true" do
|
||||
it "returns a blank parameter error message" do
|
||||
put api("/application/settings", admin), plantuml_enabled: true
|
||||
|
||||
expect(response).to have_http_status(400)
|
||||
expect(json_response['error']).to eq('plantuml_url is missing')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue