]> source.dussan.org Git - redmine.git/commitdiff
Adds rake task to download SVG icons from Tabler Github repository using config/icon_...
authorMarius Balteanu <marius.balteanu@zitec.com>
Tue, 8 Oct 2024 21:53:53 +0000 (21:53 +0000)
committerMarius Balteanu <marius.balteanu@zitec.com>
Tue, 8 Oct 2024 21:53:53 +0000 (21:53 +0000)
* @icons:download@: downloads the default icons
* @icons:sprite@: generates the SVG sprite file for the default icons
* @icons:generate@: runs @icons:download@ and @icons:sprite@ tasks
* @icons:plugin:download@: downloads the icons for a specific plugin if the plugin provides a @icon_source.yaml@ in plugin config directory.
* @icons:plugin:sprite@: generates the SVG sprite for the plugin.
* @icons:plugin:generate@: runs @icons:plugin:download@ and @icons:plugin:sprite@ tasks

git-svn-id: https://svn.redmine.org/redmine/trunk@23105 e93f8b46-1217-0410-a6f0-8f06a7374b81

Gemfile
app/assets/images/icons.svg
config/icon_source.yml [new file with mode: 0644]
lib/tasks/icons.rake [new file with mode: 0644]

diff --git a/Gemfile b/Gemfile
index 46eeb92760067517cdd74910f91612284cd88509..b57b3bd9d3908dfd9d85b637da6ba41524943fb0 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -95,6 +95,7 @@ end
 group :development do
   gem 'listen', '~> 3.3'
   gem 'yard', require: false
+  gem 'svg_sprite', require: false
 end
 
 group :test do
index 43d476b463a05e5d0630bf4dbe47c403392c30a7..92c345560ef4af3005cff10925d2b9ab72c743f8 100644 (file)
@@ -1,3 +1,4 @@
+<?xml version="1.0"?>
 <svg xmlns="http://www.w3.org/2000/svg" class="icon--sprite">
   <defs>
     <symbol viewBox="0 0 24 24" stroke-linecap="round" stroke-linejoin="round" id="icon--3-bullets">
diff --git a/config/icon_source.yml b/config/icon_source.yml
new file mode 100644 (file)
index 0000000..32d28b6
--- /dev/null
@@ -0,0 +1,194 @@
+# Redmine - project management software
+# Copyright (C) 2006-  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+# This file is used by icons rake task to download SVG icons from Tabler
+# Keys description:
+#   - name: destination icon name
+#     svg: source icon name from Github repository
+#     style: outline (default) or filled
+
+- name: edit
+  svg: pencil
+- name: add
+  svg: circle-plus
+- name: copy
+  svg: copy
+- name: del
+  svg: trash
+- name: save
+  svg: device-floppy
+- name: download
+  svg: download
+- name: attachment
+  svg: paperclip
+- name: time-add
+  svg: clock-plus
+- name: time
+  svg: clock
+- name: fav
+  svg: star
+- name: copy-link
+  svg: clipboard-copy
+- name: 3-bullets
+  svg: dots
+- name: history
+  svg: history
+- name: folder
+  svg: folder
+- name: folder-open
+  svg: folder-open
+- name: lock
+  svg: lock
+- name: unlock
+  svg: lock-open
+- name: link-break
+  svg: link-off
+- name: zoom-in
+  svg: zoom-in
+- name: zoom-out
+  svg: zoom-out
+- name: settings
+  svg: settings
+- name: news
+  svg: news
+- name: user
+  svg: user
+- name: group
+  svg: users-group
+- name: bookmarked
+  svg: bookmark
+- name: bookmark-delete
+  svg: bookmark-off
+- name: bookmark-add
+  svg: bookmark-plus
+- name: import
+  svg: database-export
+- name: summary
+  svg: bolt
+- name: angle-down
+  svg: chevron-down
+- name: angle-right
+  svg: chevron-right
+- name: angle-up
+  svg: chevron-up
+- name: email
+  svg: mail
+- name: email-disabled
+  svg: mail-off
+- name: stats
+  svg: chart-bar
+- name: reorder
+  svg: menu-order
+- name: close
+  svg: square-x
+- name: checked
+  svg: check
+- name: reload
+  svg: refresh
+- name: link
+  svg: link
+- name: plugins
+  svg: puzzle
+- name: roles
+  svg: shield-cog
+- name: list
+  svg: list
+- name: workflows
+  svg: jump-rope
+- name: server-authentication
+  svg: server
+- name: table-multiple
+  svg: refresh
+- name: projects
+  svg: packages
+- name: package
+  svg: package
+- name: custom-fields
+  svg: input-check
+- name: help
+  svg: info-circle
+- name: changeset
+  svg: code
+- name: clear-query
+  svg: square-x
+- name: warning
+  svg: alert-triangle
+- name: comments
+  svg: message
+- name: comment
+  svg: message
+- name: arrow-right
+  svg: arrow-big-right
+- name: wiki-page
+  svg: notebook
+- name: bullet-end
+  svg: circle-arrow-left
+- name: bullet-go
+  svg: circle-arrow-right
+- name: bullet-go-end
+  svg: diamonds
+- name: move
+  svg: arrow-forward-up
+- name: cancel
+  svg: arrow-back-up
+- name: document
+  svg: file-text
+- name: issue
+  svg: note
+- name: issue-closed
+  svg: square-check
+- name: issue-edit
+  svg: edit
+- name: issue-note
+  svg: message-plus
+- name: file
+  svg: file
+- name: text-plain
+  svg: file-text
+- name: text-x-c
+  svg: file-code
+- name: text-x-csharp
+  svg: brand-c-sharp
+- name: text-x-java
+  svg: file-code
+- name: text-x-php
+  svg: file-type-php
+- name: text-x-ruby
+  svg: file-code
+- name: text-xml
+  svg: file-type-xml
+- name: text-css
+  svg: file-type-css
+- name: text-html
+  svg: file-type-html
+- name: image-gif
+  svg: file
+- name: image-jpeg
+  svg: file-type-jpg
+- name: image-png
+  svg: file-type-png
+- name: image-tiff
+  svg: file
+- name: application-javascript
+  svg: file-type-js
+- name: application-pdf
+  svg: file-type-pdf
+- name: application-zip
+  svg: file-type-zip
+- name: application-gzip
+  svg: file-zip
+
diff --git a/lib/tasks/icons.rake b/lib/tasks/icons.rake
new file mode 100644 (file)
index 0000000..bda10f2
--- /dev/null
@@ -0,0 +1,142 @@
+# Redmine - project management software
+# Copyright (C) 2006-  Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+unless Rails.env.production?
+  require "svg_sprite"
+
+  ICON_RELEASE_VERSION = "v3.19.0"
+  ICON_DEFAULT_STYLE = "outline"
+  SOURCE = URI.parse("https://raw.githubusercontent.com/tabler/tabler-icons/#{ICON_RELEASE_VERSION}/icons")
+
+  namespace :icons do
+
+    desc 'Downloads default SVG icons'
+    task :download do
+      icons_mapping = YAML.load_file(Rails.root.join('config/icon_source.yml'))
+      destination_path = Rails.root.join("tmp", "icons", "default")
+
+      download_sgv_icons(icons_mapping, destination_path)
+    end
+
+    desc "Generates SVG sprite file default SVG icons"
+    task :sprite do
+      input_path = Rails.root.join("tmp", "icons", "default")
+      sprite_path = Rails.root.join('app', 'assets', 'images', 'icons.svg')
+
+      generate_svg_sprite(input_path, sprite_path)
+    end
+
+    desc 'Downloads default SVG icons and generates a SVG sprite from the icons'
+    task :generate do
+      Rake::Task["icons:download"].execute
+      Rake::Task["icons:sprite"].execute
+    end
+
+    namespace :plugin do
+      desc 'Downloads SVG icons for plugin'
+      task :download do
+        name = ENV['NAME']
+
+        if name.nil?
+          abort "The VERSION argument requires a plugin NAME."
+        end
+
+        icons_mapping_path = Rails.root.join('plugins', name, 'config', 'icon_source.yml')
+        unless File.file?(icons_mapping_path)
+          abort "Icon source file for #{name} plugin not found in #{icons_mapping_path}."
+        end
+
+        icons_mapping = YAML.load_file(icons_mapping_path)
+        destination_path = Rails.root.join("tmp", "icons", name)
+
+        download_sgv_icons(icons_mapping, destination_path)
+      end
+
+      desc "Generates SVG sprite for plugin"
+      task :sprite do
+        name = ENV['NAME']
+
+        if name.nil?
+          abort "The VERSION argument requires a plugin NAME."
+        end
+
+        input_path = Rails.root.join("tmp", "icons", name)
+        sprite_path = Rails.root.join('plugins', name, 'app', 'assets', 'images', 'icons.svg')
+
+        generate_svg_sprite(input_path, sprite_path)
+      end
+
+      desc 'Downloads SVG icons and generates sprite for plugin'
+      task :generate do
+        Rake::Task["icons:plugin:download"].execute
+        Rake::Task["icons:plugin:sprite"].execute
+      end
+    end
+  end
+
+  def download_sgv_icons(icons_mapping, destination)
+    http = Net::HTTP.new(SOURCE.host, SOURCE.port)
+    http.use_ssl = true
+
+    FileUtils.rm_rf(destination)
+    FileUtils.mkdir_p(destination)
+
+    icons_mapping.each do |v|
+      name = v['name']
+      svg = v['svg']
+      style = v['style'] || ICON_DEFAULT_STYLE
+
+      http.start do |h|
+        source = "#{SOURCE}/#{style}/#{svg}.svg"
+
+        puts "Downloading #{name} from #{source}..."
+        req = Net::HTTP::Get.new(source)
+        res = h.request(req)
+
+        case res
+        when Net::HTTPSuccess
+          target = File.join(destination, "#{name}.svg")
+          File.open(target, 'w') do |f|
+            f.write res.body
+          end
+        else
+          abort "Error when trying to download the icon for #{name}"
+        end
+      end
+    end
+  end
+
+  def generate_svg_sprite(input_path, sprite_path)
+    SvgSprite.call(
+      input: input_path,
+      name: 'icon',
+      css_path:  File.join(input_path, 'icons.css'),
+      sprite_path: sprite_path,
+      optimize: true
+    )
+
+    doc = Nokogiri::XML(sprite_path)
+
+    doc.traverse do |node|
+      node.keys.each do |attribute|
+        node.delete attribute if ["fill", "stroke", "stroke-width"].include?(attribute)
+      end
+    end
+
+    File.write(sprite_path, doc.to_xml)
+  end
+end