Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-05-03 15:07:28 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-05-03 15:07:28 +0300
commit5fabe42e23beba3fbe393e566a5a4ebde2062c61 (patch)
tree9a2dfa55656973763fcc05ac393bd2bd06125935 /scripts/lib
parent4df4a22481c3ed10e22cdb795dd6d811c4e89fde (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'scripts/lib')
-rw-r--r--scripts/lib/glfm/constants.rb30
-rw-r--r--scripts/lib/glfm/shared.rb28
-rw-r--r--scripts/lib/glfm/update_specification.rb105
3 files changed, 163 insertions, 0 deletions
diff --git a/scripts/lib/glfm/constants.rb b/scripts/lib/glfm/constants.rb
new file mode 100644
index 00000000000..70f38e45cf5
--- /dev/null
+++ b/scripts/lib/glfm/constants.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Glfm
+ module Constants
+ # Root dir containing all specification files
+ specification_path = Pathname.new(File.expand_path("../../../glfm_specification", __dir__))
+
+ # GitHub Flavored Markdown specification file
+ GHFM_SPEC_TXT_URI = 'https://raw.githubusercontent.com/github/cmark-gfm/master/test/spec.txt'
+ GHFM_SPEC_VERSION = '0.29'
+ GHFM_SPEC_TXT_FILENAME = "ghfm_spec_v_#{GHFM_SPEC_VERSION}.txt"
+ GHFM_SPEC_TXT_PATH = specification_path.join('input/github_flavored_markdown', GHFM_SPEC_TXT_FILENAME)
+
+ # GitLab Flavored Markdown specification files
+ specification_input_glfm_path = specification_path.join('input/gitlab_flavored_markdown')
+ GLFM_INTRO_TXT_PATH = specification_input_glfm_path.join('glfm_intro.txt')
+ GLFM_EXAMPLES_TXT_PATH = specification_input_glfm_path.join('glfm_canonical_examples.txt')
+ GLFM_SPEC_TXT_PATH = specification_path.join('output/spec.txt')
+
+ # Other constants used for processing files
+ GLFM_SPEC_TXT_HEADER = <<~GLFM_SPEC_TXT_HEADER
+ ---
+ title: GitLab Flavored Markdown (GLFM) Spec
+ version: alpha
+ ...
+ GLFM_SPEC_TXT_HEADER
+ INTRODUCTION_HEADER_LINE_TEXT = /\A# Introduction\Z/.freeze
+ END_TESTS_COMMENT_LINE_TEXT = /\A<!-- END TESTS -->\Z/.freeze
+ end
+end
diff --git a/scripts/lib/glfm/shared.rb b/scripts/lib/glfm/shared.rb
new file mode 100644
index 00000000000..92ca067f9f8
--- /dev/null
+++ b/scripts/lib/glfm/shared.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+require 'fileutils'
+
+module Glfm
+ module Shared
+ def write_file(file_path, file_content_string)
+ FileUtils.mkdir_p(File.dirname(file_path))
+ # NOTE: We don't use the block form of File.open because we want to be able to easily
+ # mock it for testing.
+ io = File.open(file_path, 'w')
+ io.binmode
+ io.write(file_content_string)
+ # NOTE: We are using #fsync + #close_write instead of just #close`, in order to unit test
+ # with a real StringIO and not just a mock object.
+ io.fsync
+ io.close_write
+ end
+
+ # All script output goes through this method. This makes it easy to mock in order to prevent
+ # output from being printed to the console during tests. We don't want to directly mock
+ # Kernel#puts, because that could interfere or cause spurious test failures when #puts is used
+ # for debugging. And for some reason RuboCop says `rubocop:disable Rails/Output` would be
+ # redundant here, so not including it.
+ def output(string)
+ puts string
+ end
+ end
+end
diff --git a/scripts/lib/glfm/update_specification.rb b/scripts/lib/glfm/update_specification.rb
new file mode 100644
index 00000000000..df648f4115b
--- /dev/null
+++ b/scripts/lib/glfm/update_specification.rb
@@ -0,0 +1,105 @@
+# frozen_string_literal: true
+require 'fileutils'
+require 'open-uri'
+require 'pathname'
+require_relative 'constants'
+require_relative 'shared'
+
+module Glfm
+ class UpdateSpecification
+ include Constants
+ include Shared
+
+ def process
+ output('Updating specification...')
+ ghfm_spec_txt_lines = download_and_write_ghfm_spec_txt
+ glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_txt_lines)
+ write_glfm_spec_txt(glfm_spec_txt_string)
+ end
+
+ private
+
+ def download_and_write_ghfm_spec_txt
+ output("Downloading #{GHFM_SPEC_TXT_URI}...")
+ ghfm_spec_txt_uri_io = URI.open(GHFM_SPEC_TXT_URI)
+
+ # Read IO stream into an array of lines for easy processing later
+ ghfm_spec_txt_lines = ghfm_spec_txt_uri_io.readlines
+ raise "Unable to read lines from #{GHFM_SPEC_TXT_URI}" if ghfm_spec_txt_lines.empty?
+
+ # Make sure the GHFM spec version has not changed
+ validate_expected_spec_version!(ghfm_spec_txt_lines[2])
+
+ # Reset IO stream and re-read into a single string for easy writing
+ # noinspection RubyNilAnalysis
+ ghfm_spec_txt_uri_io.seek(0)
+ ghfm_spec_txt_string = ghfm_spec_txt_uri_io.read
+ raise "Unable to read string from #{GHFM_SPEC_TXT_URI}" unless ghfm_spec_txt_string
+
+ output("Writing #{GHFM_SPEC_TXT_PATH}...")
+ GHFM_SPEC_TXT_PATH.dirname.mkpath
+ write_file(GHFM_SPEC_TXT_PATH, ghfm_spec_txt_string)
+
+ ghfm_spec_txt_lines
+ end
+
+ def validate_expected_spec_version!(version_line)
+ return if version_line =~ /\Aversion: #{GHFM_SPEC_VERSION}\Z/o
+
+ raise "GitHub Flavored Markdown spec.txt version mismatch! " \
+ "Expected 'version: #{GHFM_SPEC_VERSION}', got '#{version_line}'"
+ end
+
+ def build_glfm_spec_txt(ghfm_spec_txt_lines)
+ glfm_spec_txt_lines = ghfm_spec_txt_lines.dup
+ replace_header(glfm_spec_txt_lines)
+ replace_intro_section(glfm_spec_txt_lines)
+ insert_examples_txt(glfm_spec_txt_lines)
+ glfm_spec_txt_lines.join('')
+ end
+
+ def replace_header(spec_txt_lines)
+ spec_txt_lines[0, spec_txt_lines.index("...\n") + 1] = GLFM_SPEC_TXT_HEADER
+ end
+
+ def replace_intro_section(spec_txt_lines)
+ glfm_intro_txt_lines = File.open(GLFM_INTRO_TXT_PATH).readlines
+ raise "Unable to read lines from #{GLFM_INTRO_TXT_PATH}" if glfm_intro_txt_lines.empty?
+
+ ghfm_intro_header_begin_index = spec_txt_lines.index do |line|
+ line =~ INTRODUCTION_HEADER_LINE_TEXT
+ end
+ raise "Unable to locate introduction header line in #{GHFM_SPEC_TXT_PATH}" if ghfm_intro_header_begin_index.nil?
+
+ # Find the index of the next header after the introduction header, starting from the index
+ # of the introduction header this is the length of the intro section
+ ghfm_intro_section_length = spec_txt_lines[ghfm_intro_header_begin_index + 1..].index do |line|
+ line.start_with?('# ')
+ end
+
+ # Replace the intro section with the GitLab flavored Markdown intro section
+ spec_txt_lines[ghfm_intro_header_begin_index, ghfm_intro_section_length] = glfm_intro_txt_lines
+ end
+
+ def insert_examples_txt(spec_txt_lines)
+ glfm_examples_txt_lines = File.open(GLFM_EXAMPLES_TXT_PATH).readlines
+ raise "Unable to read lines from #{GLFM_EXAMPLES_TXT_PATH}" if glfm_examples_txt_lines.empty?
+
+ ghfm_end_tests_comment_index = spec_txt_lines.index do |line|
+ line =~ END_TESTS_COMMENT_LINE_TEXT
+ end
+ raise "Unable to locate 'END TESTS' comment line in #{GHFM_SPEC_TXT_PATH}" if ghfm_end_tests_comment_index.nil?
+
+ # Insert the GLFM examples before the 'END TESTS' comment line
+ spec_txt_lines[ghfm_end_tests_comment_index - 1] = ["\n", glfm_examples_txt_lines, "\n"].flatten
+
+ spec_txt_lines
+ end
+
+ def write_glfm_spec_txt(glfm_spec_txt_string)
+ output("Writing #{GLFM_SPEC_TXT_PATH}...")
+ FileUtils.mkdir_p(Pathname.new(GLFM_SPEC_TXT_PATH).dirname)
+ write_file(GLFM_SPEC_TXT_PATH, glfm_spec_txt_string)
+ end
+ end
+end