diff --git a/doc/development/gitlab_flavored_markdown/specification_guide/index.md b/doc/development/gitlab_flavored_markdown/specification_guide/index.md index 4a6a1d8f64fea89a0cf6eb43966462556d0e8131..b1ab39b03214811a48b65d3db9343a092fa8685b 100644 --- a/doc/development/gitlab_flavored_markdown/specification_guide/index.md +++ b/doc/development/gitlab_flavored_markdown/specification_guide/index.md @@ -86,7 +86,7 @@ Some places in the code refer to both the GitLab and GitHub specifications simultaneous in the same areas of logic. In these situations, _GitHub_ Flavored Markdown may be referred to with variable or constant names like `ghfm_` to avoid confusion. For example, we use the `ghfm` acronym for the -[`ghfm_spec_v_0.29.txt` GitHub Flavored Markdown specification file](#github-flavored-markdown-specification) +[`ghfm_spec_v_0.29.md` GitHub Flavored Markdown specification file](#github-flavored-markdown-specification), which is committed to the `gitlab` repository and used as input to the [`update_specification.rb` script](#update-specificationrb-script). @@ -618,8 +618,8 @@ subgraph script: A --> B{Backend Markdown API} end subgraph input:<br/>input specification files - C[ghfm_spec_v_0.29.txt] --> A - D[glfm_intro.txt] --> A + C[ghfm_spec_v_0.29.md] --> A + D[glfm_intro.md] --> A E[glfm_official_specification_examples.md] --> A F[glfm_internal_extension_examples.md] --> A end @@ -749,7 +749,7 @@ subcategories based on their usage and purpose: These are the original input to drive all other automated GLFM specification scripts, processes, or tests. - `github_flavored_markdown`: Contains only the downloaded and committed - [`ghfm_spec_v_0.29.txt`](#github-flavored-markdown-specification) specification. + [`ghfm_spec_v_0.29.md`](#github-flavored-markdown-specification) specification. - `gitlab_flavored_markdown`: Contains all `glfm_*` files. - `*.md` [input specification files](#input-specification-files), which represent the GLFM specification itself. @@ -769,19 +769,20 @@ See the main [specification files](#specification-files) section for more contex ##### GitHub Flavored Markdown specification -[`glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt) -is the official latest [GFM `spec.txt`](https://github.com/github/cmark-gfm/blob/master/test/spec.txt). +[`glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md) +is a copy of the official latest [GFM `spec.txt`](https://github.com/github/cmark-gfm/blob/master/test/spec.txt). -- It is automatically downloaded and updated by `update-specification.rb` script. +- It is automatically downloaded and updated by the `update-specification.rb` script. - When it is downloaded, the version number is added to the filename. +- The extension is changed from `*.txt` to `*.md` so that it can be handled better by Markdown editors. NOTE: For extra clarity, this file uses the `ghfm` acronym in its name instead of `gfm`, as explained in the [Acronyms section](#acronyms-glfm-ghfm-gfm-commonmark). -##### `glfm_intro.txt` +##### `glfm_intro.md` -[`glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt) +[`glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md) is the GitLab-specific version of the prose in the introduction section of the GLFM specification. - It is manually updated. diff --git a/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt b/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md similarity index 99% rename from glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt rename to glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md index 582131d700a42830dcbc46dc4baebbe2f347f4e8..1702761563ec48c004d27abcacec5734ed1756f8 100644 --- a/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.txt +++ b/glfm_specification/input/github_flavored_markdown/ghfm_spec_v_0.29.md @@ -2077,7 +2077,7 @@ followed by one of the strings (case-insensitive) `address`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hr`, `html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`, `nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`, -`section`, `source`, `summary`, `table`, `tbody`, `td`, +`section`, `summary`, `table`, `tbody`, `td`, `tfoot`, `th`, `thead`, `title`, `tr`, `track`, `ul`, followed by [whitespace], the end of the line, the string `>`, or the string `/>`.\ @@ -10224,4 +10224,3 @@ closers: After we're done, we remove all delimiters above `stack_bottom` from the delimiter stack. - diff --git a/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt b/glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md similarity index 100% rename from glfm_specification/input/gitlab_flavored_markdown/glfm_intro.txt rename to glfm_specification/input/gitlab_flavored_markdown/glfm_intro.md diff --git a/glfm_specification/output/spec.txt b/glfm_specification/output/spec.txt index af4eba06758ddee6d0d291183a445cd95defd289..9fa6c4c291e62c6b9951e9d0e9a25e16db5d9bb3 100644 --- a/glfm_specification/output/spec.txt +++ b/glfm_specification/output/spec.txt @@ -1791,7 +1791,7 @@ followed by one of the strings (case-insensitive) `address`, `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `head`, `header`, `hr`, `html`, `iframe`, `legend`, `li`, `link`, `main`, `menu`, `menuitem`, `nav`, `noframes`, `ol`, `optgroup`, `option`, `p`, `param`, -`section`, `source`, `summary`, `table`, `tbody`, `td`, +`section`, `summary`, `table`, `tbody`, `td`, `tfoot`, `th`, `thead`, `title`, `tr`, `track`, `ul`, followed by [whitespace], the end of the line, the string `>`, or the string `/>`.\ @@ -10328,4 +10328,3 @@ closers: After we're done, we remove all delimiters above `stack_bottom` from the delimiter stack. - diff --git a/scripts/lib/glfm/constants.rb b/scripts/lib/glfm/constants.rb index e5790bbdd8831621e0dcdef75b4cefd9b694d461..27b959cd135cca6d85bc140f70089d7a9840d543 100644 --- a/scripts/lib/glfm/constants.rb +++ b/scripts/lib/glfm/constants.rb @@ -10,12 +10,12 @@ module Constants # 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) + GHFM_SPEC_MD_FILENAME = "ghfm_spec_v_#{GHFM_SPEC_VERSION}.md" + GHFM_SPEC_MD_PATH = specification_path.join('input/github_flavored_markdown', GHFM_SPEC_MD_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_INTRO_MD_PATH = specification_input_glfm_path.join('glfm_intro.md') GLFM_EXAMPLES_TXT_PATH = specification_input_glfm_path.join('glfm_canonical_examples.txt') GLFM_EXAMPLE_STATUS_YML_PATH = specification_input_glfm_path.join('glfm_example_status.yml') GLFM_EXAMPLE_METADATA_YML_PATH = diff --git a/scripts/lib/glfm/update_specification.rb b/scripts/lib/glfm/update_specification.rb index 73c23d40de5b16ccda723f20b7da056d35bd8d0e..7a89797123b284477a4c0ce632f12ae988e41ffe 100644 --- a/scripts/lib/glfm/update_specification.rb +++ b/scripts/lib/glfm/update_specification.rb @@ -12,16 +12,16 @@ class UpdateSpecification def process output('Updating specification...') - ghfm_spec_txt_lines = load_ghfm_spec_txt - glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_txt_lines) + ghfm_spec_lines = load_ghfm_spec + glfm_spec_txt_string = build_glfm_spec_txt(ghfm_spec_lines) write_glfm_spec_txt(glfm_spec_txt_string) end private - def load_ghfm_spec_txt + def load_ghfm_spec # We only re-download the GitHub Flavored Markdown specification if the - # UPDATE_GHFM_SPEC_TXT environment variable is set to true, which should only + # UPDATE_GHFM_SPEC_MD environment variable is set to true, which should only # ever be done manually and locally, never in CI. This provides some security # protection against a possible injection attack vector, if the GitHub-hosted # version of the spec is ever temporarily compromised with an injection attack. @@ -29,40 +29,40 @@ def load_ghfm_spec_txt # This also avoids doing external network access to download the file # in CI jobs, which can avoid potentially flaky builds if the GitHub-hosted # version of the file is temporarily unavailable. - if ENV['UPDATE_GHFM_SPEC_TXT'] == 'true' - download_and_write_ghfm_spec_txt + if ENV['UPDATE_GHFM_SPEC_MD'] == 'true' + update_ghfm_spec_md else - read_existing_ghfm_spec_txt + read_existing_ghfm_spec_md end end - def read_existing_ghfm_spec_txt - output("Reading existing #{GHFM_SPEC_TXT_PATH}...") - File.open(GHFM_SPEC_TXT_PATH).readlines + def read_existing_ghfm_spec_md + output("Reading existing #{GHFM_SPEC_MD_PATH}...") + File.open(GHFM_SPEC_MD_PATH).readlines end - def download_and_write_ghfm_spec_txt + def update_ghfm_spec_md 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? + ghfm_spec_lines = ghfm_spec_txt_uri_io.readlines + raise "Unable to read lines from #{GHFM_SPEC_TXT_URI}" if ghfm_spec_lines.empty? # Make sure the GHFM spec version has not changed - validate_expected_spec_version!(ghfm_spec_txt_lines[2]) + validate_expected_spec_version!(ghfm_spec_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 + ghfm_spec_string = ghfm_spec_txt_uri_io.read + raise "Unable to read string from #{GHFM_SPEC_TXT_URI}" unless ghfm_spec_string - output("Writing #{GHFM_SPEC_TXT_PATH}...") - GHFM_SPEC_TXT_PATH.dirname.mkpath - write_file(GHFM_SPEC_TXT_PATH, ghfm_spec_txt_string) + output("Writing #{GHFM_SPEC_MD_PATH}...") + GHFM_SPEC_MD_PATH.dirname.mkpath + write_file(GHFM_SPEC_MD_PATH, ghfm_spec_string) - ghfm_spec_txt_lines + ghfm_spec_lines end def validate_expected_spec_version!(version_line) @@ -85,13 +85,13 @@ def replace_header(spec_txt_lines) 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? + glfm_intro_md_lines = File.open(GLFM_INTRO_MD_PATH).readlines + raise "Unable to read lines from #{GLFM_INTRO_MD_PATH}" if glfm_intro_md_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? + raise "Unable to locate introduction header line in #{GHFM_SPEC_MD_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 @@ -100,7 +100,7 @@ def replace_intro_section(spec_txt_lines) 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 + spec_txt_lines[ghfm_intro_header_begin_index, ghfm_intro_section_length] = glfm_intro_md_lines end def insert_examples_txt(spec_txt_lines) @@ -110,7 +110,7 @@ def insert_examples_txt(spec_txt_lines) 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? + raise "Unable to locate 'END TESTS' comment line in #{GHFM_SPEC_MD_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 diff --git a/spec/scripts/lib/glfm/update_specification_spec.rb b/spec/scripts/lib/glfm/update_specification_spec.rb index 9fb671e0016a1076923681b89339cda9ff7ef22a..1cdc90876de94a49d3685dc1813276d7ef06f068 100644 --- a/spec/scripts/lib/glfm/update_specification_spec.rb +++ b/spec/scripts/lib/glfm/update_specification_spec.rb @@ -7,11 +7,11 @@ let(:ghfm_spec_txt_uri) { described_class::GHFM_SPEC_TXT_URI } let(:ghfm_spec_txt_uri_io) { StringIO.new(ghfm_spec_txt_contents) } - let(:ghfm_spec_txt_path) { described_class::GHFM_SPEC_TXT_PATH } + let(:ghfm_spec_md_path) { described_class::GHFM_SPEC_MD_PATH } let(:ghfm_spec_txt_local_io) { StringIO.new(ghfm_spec_txt_contents) } - let(:glfm_intro_txt_path) { described_class::GLFM_INTRO_TXT_PATH } - let(:glfm_intro_txt_io) { StringIO.new(glfm_intro_txt_contents) } + let(:glfm_intro_md_path) { described_class::GLFM_INTRO_MD_PATH } + let(:glfm_intro_md_io) { StringIO.new(glfm_intro_md_contents) } let(:glfm_examples_txt_path) { described_class::GLFM_EXAMPLES_TXT_PATH } let(:glfm_examples_txt_io) { StringIO.new(glfm_examples_txt_contents) } let(:glfm_spec_txt_path) { described_class::GLFM_SPEC_TXT_PATH } @@ -52,7 +52,7 @@ MARKDOWN end - let(:glfm_intro_txt_contents) do + let(:glfm_intro_md_contents) do # language=Markdown <<~MARKDOWN # Introduction @@ -73,15 +73,15 @@ before do # Mock default ENV var values - allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_TXT').and_return(nil) + allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_MD').and_return(nil) allow(ENV).to receive(:[]).and_call_original # We mock out the URI and local file IO objects with real StringIO, instead of just mock # objects. This gives better and more realistic coverage, while still avoiding # actual network and filesystem I/O during the spec run. allow(URI).to receive(:open).with(ghfm_spec_txt_uri) { ghfm_spec_txt_uri_io } - allow(File).to receive(:open).with(ghfm_spec_txt_path) { ghfm_spec_txt_local_io } - allow(File).to receive(:open).with(glfm_intro_txt_path) { glfm_intro_txt_io } + allow(File).to receive(:open).with(ghfm_spec_md_path) { ghfm_spec_txt_local_io } + allow(File).to receive(:open).with(glfm_intro_md_path) { glfm_intro_md_io } allow(File).to receive(:open).with(glfm_examples_txt_path) { glfm_examples_txt_io } allow(File).to receive(:open).with(glfm_spec_txt_path, 'w') { glfm_spec_txt_io } @@ -90,7 +90,7 @@ end describe 'retrieving latest GHFM spec.txt' do - context 'when UPDATE_GHFM_SPEC_TXT is not true (default)' do + context 'when UPDATE_GHFM_SPEC_MD is not true (default)' do it 'does not download' do expect(URI).not_to receive(:open).with(ghfm_spec_txt_uri) @@ -100,12 +100,12 @@ end end - context 'when UPDATE_GHFM_SPEC_TXT is true' do + context 'when UPDATE_GHFM_SPEC_MD is true' do let(:ghfm_spec_txt_local_io) { StringIO.new } before do - allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_TXT').and_return('true') - allow(File).to receive(:open).with(ghfm_spec_txt_path, 'w') { ghfm_spec_txt_local_io } + allow(ENV).to receive(:[]).with('UPDATE_GHFM_SPEC_MD').and_return('true') + allow(File).to receive(:open).with(ghfm_spec_md_path, 'w') { ghfm_spec_txt_local_io } end context 'with success' do @@ -170,7 +170,7 @@ it 'replaces the intro section with the GitLab version' do expect(glfm_contents).not_to match(/What is GitHub Flavored Markdown/m) - expect(glfm_contents).to match(/#{Regexp.escape(glfm_intro_txt_contents)}/m) + expect(glfm_contents).to match(/#{Regexp.escape(glfm_intro_md_contents)}/m) end it 'inserts the GitLab examples sections before the appendix section' do