"Fossies" - the Fresh Open Source Software Archive

Member "discourse-2.8.3/lib/tasks/release_note.rake" (14 Apr 2022, 4174 Bytes) of package /linux/www/discourse-2.8.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Ruby source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "release_note.rake": 2.7.13_vs_2.8.0.

    1 # frozen_string_literal: true
    2 
    3 DATE_REGEX ||= /\A\d{4}-\d{2}-\d{2}/
    4 
    5 CHANGE_TYPES ||= [
    6   { pattern: /^FEATURE:/, heading: "New Features" },
    7   { pattern: /^FIX:/, heading: "Bug Fixes" },
    8   { pattern: /^UX:/, heading: "UX Changes" },
    9   { pattern: /^SECURITY:/, heading: "Security Changes" },
   10   { pattern: /^PERF:/, heading: "Performance" },
   11   { pattern: /^A11Y:/, heading: "Accessibility" },
   12 ]
   13 
   14 desc "generate a release note from the important commits"
   15 task "release_note:generate", :from, :to, :repo do |t, args|
   16   repo = args[:repo] || "."
   17   changes = find_changes(repo, args[:from], args[:to])
   18 
   19   CHANGE_TYPES.each do |ct|
   20     print_changes(ct[:heading], changes[ct], "###")
   21   end
   22 
   23   if changes.values.all?(&:empty?)
   24     puts "(no changes)", ""
   25   end
   26 end
   27 
   28 # To use with all-the-plugins:
   29 #  1. Make sure you have a local, up-to-date clone of https://github.com/discourse/all-the-plugins
   30 #  2. In all-the-plugins, `git submodule update --init --recursive --remote`
   31 #  3. Change back to your discourse directory
   32 #  4. rake "release_note:plugins:generate[ 2021-06-01 , 2021-07-01 , /path/to/all-the-plugins/plugins/* , discourse ]"
   33 desc "generate release notes for all official plugins in a directory"
   34 task "release_note:plugins:generate", :from, :to, :plugin_glob, :org do |t, args|
   35   from = args[:from]
   36   to = args[:to]
   37   plugin_glob = args[:plugin_glob] || "./plugins/*"
   38   git_org = args[:org]
   39 
   40   all_repos = Dir.glob(plugin_glob).filter { |f| File.directory?(f) && File.exist?("#{f}/.git")  }
   41 
   42   if git_org
   43     all_repos = all_repos.filter { |dir| `git -C #{dir} remote get-url origin`.match?(/github.com[\/:]#{git_org}\//) }
   44   end
   45 
   46   no_changes_repos = []
   47 
   48   all_repos.each do |dir|
   49     name = File.basename(dir)
   50     changes = find_changes(dir, from, to)
   51 
   52     if changes.values.all?(&:empty?)
   53       no_changes_repos << name
   54       next
   55     end
   56 
   57     puts "### #{name}\n\n"
   58     CHANGE_TYPES.each do |ct|
   59       print_changes(ct[:heading], changes[ct], "####")
   60     end
   61   end
   62 
   63   puts "(No changes found in #{no_changes_repos.join(", ")})"
   64 end
   65 
   66 def find_changes(repo, from, to)
   67   dates = from&.match?(DATE_REGEX) || to&.match?(DATE_REGEX)
   68 
   69   if !dates
   70     from ||= `git -C #{repo} describe --tags --abbrev=0`.strip
   71     to ||= "HEAD"
   72   end
   73 
   74   cmd = "git -C #{repo} log --pretty='tformat:%s' "
   75   if dates
   76     cmd += "--after '#{from}' " if from
   77     cmd += "--before '#{to}' " if to
   78   else
   79     cmd += "#{from}..#{to}"
   80   end
   81 
   82   out = `#{cmd}`
   83   raise "Status #{$?.exitstatus} running git log\n#{out}" if !$?.success?
   84 
   85   changes = {}
   86   CHANGE_TYPES.each do |ct|
   87     changes[ct] = Set.new
   88   end
   89 
   90   out.each_line do |comment|
   91     next if comment =~ /^\s*Revert/
   92     split_comments(comment).each do |line|
   93       ct = CHANGE_TYPES.find { |t| line =~ t[:pattern] }
   94       changes[ct] << better(line) if ct
   95     end
   96   end
   97 
   98   changes
   99 end
  100 
  101 def print_changes(heading, changes, importance)
  102   return if changes.length == 0
  103 
  104   puts "#{importance} #{heading}", ""
  105   puts changes.to_a, ""
  106 end
  107 
  108 def better(line)
  109   line = remove_prefix(line)
  110   line = escape_brackets(line)
  111   line = remove_pull_request(line)
  112   line[0] = '\#' if line[0] == '#'
  113   if line[0]
  114     line[0] = line[0].capitalize
  115     "- " + line
  116   else
  117     nil
  118   end
  119 end
  120 
  121 def remove_prefix(line)
  122   line.gsub(/^(FIX|FEATURE|UX|SECURITY|PERF|A11Y):/, "").strip
  123 end
  124 
  125 def escape_brackets(line)
  126   line.gsub("<", "`<")
  127     .gsub(">", ">`")
  128     .gsub("[", "`[")
  129     .gsub("]", "]`")
  130 end
  131 
  132 def remove_pull_request(line)
  133   line.gsub(/ \(\#\d+\)$/, "")
  134 end
  135 
  136 def split_comments(text)
  137   text = normalize_terms(text)
  138   terms = ["FIX:", "FEATURE:", "UX:", "SECURITY:" , "PERF:" , "A11Y:"]
  139   terms.each do |term|
  140     text = text.gsub(/(#{term})+/i, term)
  141     text = newlines_at_term(text, term)
  142   end
  143   text.split("\n")
  144 end
  145 
  146 def normalize_terms(text)
  147   text = text.gsub(/(BUGFIX|FIX|BUG):/i, "FIX:")
  148   text = text.gsub(/FEATURE:/i, "FEATURE:")
  149   text = text.gsub(/(UX|UI):/i, "UX:")
  150   text = text.gsub(/(SECURITY):/i, "SECURITY:")
  151   text = text.gsub(/(PERF):/i, "PERF:")
  152   text = text.gsub(/(A11Y):/i, "A11Y:")
  153 end
  154 
  155 def newlines_at_term(text, term)
  156   if text.include?(term)
  157     text = text.split(term).map { |l| l.strip }.join("\n#{term} ")
  158   end
  159   text
  160 end