diff options
author | Marius Balteanu <marius.balteanu@zitec.com> | 2024-10-08 21:53:53 +0000 |
---|---|---|
committer | Marius Balteanu <marius.balteanu@zitec.com> | 2024-10-08 21:53:53 +0000 |
commit | 5d67308977050bbc77941ca1bfc86ba20d08f29d (patch) | |
tree | 9e722764ca35e2dc75aaa422cddce590b340bcee | |
parent | a8c9e9124578858963167cd02d99025812b2a8ff (diff) | |
download | redmine-5d67308977050bbc77941ca1bfc86ba20d08f29d.tar.gz redmine-5d67308977050bbc77941ca1bfc86ba20d08f29d.zip |
Adds rake task to download SVG icons from Tabler Github repository using config/icon_source.yml as source and to generate a sprite file with all the SVG icons (#23980):
* @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
-rw-r--r-- | Gemfile | 1 | ||||
-rw-r--r-- | app/assets/images/icons.svg | 1 | ||||
-rw-r--r-- | config/icon_source.yml | 194 | ||||
-rw-r--r-- | lib/tasks/icons.rake | 142 |
4 files changed, 338 insertions, 0 deletions
@@ -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 diff --git a/app/assets/images/icons.svg b/app/assets/images/icons.svg index 43d476b46..92c345560 100644 --- a/app/assets/images/icons.svg +++ b/app/assets/images/icons.svg @@ -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 index 000000000..32d28b6b0 --- /dev/null +++ b/config/icon_source.yml @@ -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 index 000000000..bda10f2a2 --- /dev/null +++ b/lib/tasks/icons.rake @@ -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 |