From f986b4c4e529f4c2518f0ce37dc9dfcaa2f073a0 Mon Sep 17 00:00:00 2001
From: Horacio Sanson <horacio@allm.net>
Date: Tue, 29 Nov 2016 02:41:29 +0900
Subject: [PATCH] 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
---
 Gemfile                                       |  25 ++---
 Gemfile.lock                                  |   3 +
 .../admin/application_settings_controller.rb  |   2 +
 app/models/application_setting.rb             |   6 ++
 .../application_settings/_form.html.haml      |  17 ++++
 .../unreleased/asciidoctor-plantuml.yml       |   4 +
 ...d_plant_uml_url_to_application_settings.rb |  12 +++
 ...ant_uml_enabled_to_application_settings.rb |  12 +++
 db/schema.rb                                  |   2 +
 .../img/integration/plantuml-example.png      | Bin 0 -> 33034 bytes
 doc/administration/integration/plantuml.md    |  87 ++++++++++++++++++
 doc/api/settings.md                           |  10 +-
 doc/integration/README.md                     |   1 +
 lib/api/entities.rb                           |   2 +
 lib/api/settings.rb                           |   6 +-
 lib/gitlab/asciidoc.rb                        |  12 +++
 lib/gitlab/current_settings.rb                |   1 +
 spec/lib/gitlab/asciidoc_spec.rb              |   4 +
 spec/requests/api/settings_spec.rb            |  16 +++-
 19 files changed, 206 insertions(+), 16 deletions(-)
 create mode 100644 changelogs/unreleased/asciidoctor-plantuml.yml
 create mode 100644 db/migrate/20161201001911_add_plant_uml_url_to_application_settings.rb
 create mode 100644 db/migrate/20161206003819_add_plant_uml_enabled_to_application_settings.rb
 create mode 100644 doc/administration/img/integration/plantuml-example.png
 create mode 100644 doc/administration/integration/plantuml.md

diff --git a/Gemfile b/Gemfile
index a8141abafc25..b43604bd2536 100644
--- a/Gemfile
+++ b/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
diff --git a/Gemfile.lock b/Gemfile.lock
index bdd591e008a9..e2d7f94e571a 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -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)
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index e34ba4244975..1b4987dd7382 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -101,6 +101,8 @@ def application_setting_params_ce
       :html_emails_enabled,
       :koding_enabled,
       :koding_url,
+      :plantuml_enabled,
+      :plantuml_url,
       :max_artifacts_size,
       :max_attachment_size,
       :metrics_enabled,
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index bf463a3b6bbd..8fab77cda0aa 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -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 @@ def self.create_from_defaults
       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,
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 4612a7a058ac..558bbe07b160 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -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
diff --git a/changelogs/unreleased/asciidoctor-plantuml.yml b/changelogs/unreleased/asciidoctor-plantuml.yml
new file mode 100644
index 000000000000..ba6ef7c08002
--- /dev/null
+++ b/changelogs/unreleased/asciidoctor-plantuml.yml
@@ -0,0 +1,4 @@
+---
+title: Add support for PlantUML diagrams in AsciiDoc documents.
+merge_request: 7810
+author: Horacio Sanson
diff --git a/db/migrate/20161201001911_add_plant_uml_url_to_application_settings.rb b/db/migrate/20161201001911_add_plant_uml_url_to_application_settings.rb
new file mode 100644
index 000000000000..b8d8742ae402
--- /dev/null
+++ b/db/migrate/20161201001911_add_plant_uml_url_to_application_settings.rb
@@ -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
diff --git a/db/migrate/20161206003819_add_plant_uml_enabled_to_application_settings.rb b/db/migrate/20161206003819_add_plant_uml_enabled_to_application_settings.rb
new file mode 100644
index 000000000000..3677f978cc2c
--- /dev/null
+++ b/db/migrate/20161206003819_add_plant_uml_enabled_to_application_settings.rb
@@ -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
diff --git a/db/schema.rb b/db/schema.rb
index f3bf7ced3930..c58a886b0fa4 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -107,6 +107,8 @@
     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|
diff --git a/doc/administration/img/integration/plantuml-example.png b/doc/administration/img/integration/plantuml-example.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb64eca1a8ae7111d3cfe18165ec91015f6566d7
GIT binary patch
literal 33034
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
Gul^6xz`7j(

literal 0
HcmV?d00001

diff --git a/doc/administration/integration/plantuml.md b/doc/administration/integration/plantuml.md
new file mode 100644
index 000000000000..e5cf592e0a66
--- /dev/null
+++ b/doc/administration/integration/plantuml.md
@@ -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.
+
diff --git a/doc/api/settings.md b/doc/api/settings.md
index 0bd38a6e664a..f86c7cc2f941 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -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
 }
 ```
diff --git a/doc/integration/README.md b/doc/integration/README.md
index ed843c0bfa98..e97430feb573 100644
--- a/doc/integration/README.md
+++ b/doc/integration/README.md
@@ -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].
 
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index d2fadf6a3d07..885ce7d44bc6 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -565,6 +565,8 @@ class ApplicationSetting < Grape::Entity
       expose :repository_storages
       expose :koding_enabled
       expose :koding_url
+      expose :plantuml_enabled
+      expose :plantuml_url
     end
 
     class Release < Grape::Entity
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index 9eb9a105bde6..c5eff16a5de2 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -93,6 +93,10 @@ def current_settings
       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 @@ def current_settings
                       :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
diff --git a/lib/gitlab/asciidoc.rb b/lib/gitlab/asciidoc.rb
index fa2342843612..0618107e2c3f 100644
--- a/lib/gitlab/asciidoc.rb
+++ b/lib/gitlab/asciidoc.rb
@@ -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 @@ def self.render(input, context, asciidoc_opts = {})
       )
       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 @@ def self.render(input, context, asciidoc_opts = {})
       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
 
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 9d142f1b82e8..2ff27e46d646 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -35,6 +35,7 @@ def fake_application_settings
         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,
diff --git a/spec/lib/gitlab/asciidoc_spec.rb b/spec/lib/gitlab/asciidoc_spec.rb
index f3843ca64ff6..ba199917f5c8 100644
--- a/spec/lib/gitlab/asciidoc_spec.rb
+++ b/spec/lib/gitlab/asciidoc_spec.rb
@@ -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,
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index ad9d8a25af45..91e3c333a02e 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -16,6 +16,8 @@
       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 @@
 
       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 @@
         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 @@
         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
-- 
GitLab