diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b44a0c9e9..57b0bc393 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,9 +15,6 @@ jobs: with: bundler-cache: true - - name: Check if documentation is up to date - run: bundle exec rake ruby_lsp:check_docs - - name: Typecheck run: bundle exec srb tc diff --git a/Gemfile b/Gemfile index 3c76abd00..8a62574a3 100644 --- a/Gemfile +++ b/Gemfile @@ -13,7 +13,6 @@ group :development do gem "mocha", "~> 2.3" gem "psych", "~> 5.1", require: false gem "rake", "~> 13.2" - gem "rdoc", require: false, github: "Shopify/rdoc", branch: "create_snapper_generator" gem "rubocop-md", "~> 1.2.0", require: false gem "rubocop-minitest", "~> 0.35.0", require: false gem "rubocop-rake", "~> 0.6.0", require: false diff --git a/Gemfile.lock b/Gemfile.lock index f995fbdac..ee6663a8d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,3 @@ -GIT - remote: https://github.com/Shopify/rdoc.git - revision: 92a6b4fcf8b72dd6776c9aa6714abe6f90d4a99e - branch: create_snapper_generator - specs: - rdoc (6.6.3.1) - psych (>= 4.0.0) - PATH remote: . specs: @@ -58,6 +50,8 @@ GEM sorbet-runtime (>= 0.5.9204) rbs (3.5.3) logger + rdoc (6.6.3.1) + psych (>= 4.0.0) regexp_parser (2.9.2) reline (0.5.10) io-console (~> 0.5) @@ -138,7 +132,6 @@ DEPENDENCIES mocha (~> 2.3) psych (~> 5.1) rake (~> 13.2) - rdoc! rubocop (~> 1.65) rubocop-md (~> 1.2.0) rubocop-minitest (~> 0.35.0) diff --git a/Rakefile b/Rakefile index 63b88d07b..76b5329ad 100644 --- a/Rakefile +++ b/Rakefile @@ -2,8 +2,6 @@ require "bundler/gem_tasks" require "rake/testtask" -require "rdoc/task" -require "ruby_lsp/check_docs" Rake::TestTask.new(:test) do |t| t.libs << "test" @@ -19,21 +17,8 @@ namespace :test do end end -RDoc::Task.new do |rdoc| - rdoc.main = "README.md" - rdoc.title = "Ruby LSP documentation" - rdoc.rdoc_files.include("*.md", "lib/**/*.rb") - rdoc.rdoc_dir = "docs" - rdoc.markup = "markdown" - rdoc.generator = "snapper" - rdoc.options.push("--copy-files", "misc") - rdoc.options.push("--copy-files", "LICENSE.txt") -end - require "rubocop/rake_task" RuboCop::RakeTask.new -RubyLsp::CheckDocs.new(FileList["#{__dir__}/lib/ruby_lsp/**/*.rb"], FileList["#{__dir__}/misc/**/*.gif"]) - task default: ["test:indexer", :test] diff --git a/dev.yml b/dev.yml index 62e958353..4e17e3aee 100644 --- a/dev.yml +++ b/dev.yml @@ -12,11 +12,6 @@ up: - vscode commands: - docs: - run: bundle exec rake rdoc - subcommands: - check: - run: bundle exec rake ruby_lsp:check_docs server: exe/ruby-lsp style: bin/rubocop typecheck: diff --git a/lib/ruby_lsp/check_docs.rb b/lib/ruby_lsp/check_docs.rb deleted file mode 100644 index 6392bee41..000000000 --- a/lib/ruby_lsp/check_docs.rb +++ /dev/null @@ -1,130 +0,0 @@ -# typed: strict -# frozen_string_literal: true - -require "ruby_lsp/internal" -require "objspace" - -module RubyLsp - # This rake task checks that all requests or addons are fully documented. Add the rake task to your Rakefile and - # specify the absolute path for all files that must be required in order to discover all requests and their related - # GIFs - # - # # Rakefile - # request_files = FileList.new("#{__dir__}/lib/ruby_lsp/requests/*.rb") do |fl| - # fl.exclude(/base_request\.rb/) - # end - # gif_files = FileList.new("#{__dir__}/**/*.gif") - # RubyLsp::CheckDocs.new(request_files, gif_files) - # # Run with bundle exec rake ruby_lsp:check_docs - class CheckDocs < Rake::TaskLib - extend T::Sig - - sig { params(require_files: Rake::FileList, gif_files: Rake::FileList).void } - def initialize(require_files, gif_files) - super() - - @name = T.let("ruby_lsp:check_docs", String) - @file_list = require_files - @gif_list = gif_files - define_task - end - - private - - sig { void } - def define_task - desc("Checks if all Ruby LSP requests are documented") - task(@name) { run_task } - end - - sig { params(request_path: String).returns(T::Boolean) } - def gif_exists?(request_path) - request_gif = request_path.gsub(".rb", ".gif").split("/").last - - @gif_list.any? { |gif_path| gif_path.end_with?(request_gif) } - end - - sig { void } - def run_task - # Require all files configured to make sure all requests are loaded - @file_list.each { |f| require(f.delete_suffix(".rb")) } - - # Find all classes that inherit from BaseRequest, which are the ones we want to make sure are - # documented - features = ObjectSpace.each_object(Class).select do |k| - klass = T.unsafe(k) - klass < Requests::Request - end - - missing_docs = T.let(Hash.new { |h, k| h[k] = [] }, T::Hash[String, T::Array[String]]) - - features.each do |klass| - class_name = T.unsafe(klass).name - file_path, line_number = Module.const_source_location(class_name) - next unless file_path && line_number - - # Adjust the line number to start searching right above the class definition - line_number -= 2 - - lines = File.readlines(file_path) - docs = [] - - # Extract the documentation on top of the request constant - while (line = lines[line_number]&.strip) && line.start_with?("#") - docs.unshift(line) - line_number -= 1 - end - - documentation = docs.join("\n") - - if docs.empty? - T.must(missing_docs[class_name]) << "No documentation found" - elsif !%r{\(https://microsoft.github.io/language-server-protocol/specification#.*\)}.match?(documentation) - T.must(missing_docs[class_name]) << <<~DOCS - Missing specification link. Requests and addons should include a link to the LSP specification for the - related feature. For example: - - [Inlay hint](https://microsoft.github.io/language-server-protocol/specification#textDocument_inlayHint) - DOCS - elsif !documentation.include?("# Example") - T.must(missing_docs[class_name]) << <<~DOCS - Missing example. Requests and addons should include a code example that explains what the feature does. - - # # Example - # ```ruby - # class Foo # <- information is shown here - # end - # ``` - DOCS - elsif !/\[.* demo\]\(.*\.gif\)/.match?(documentation) - T.must(missing_docs[class_name]) << <<~DOCS - Missing demonstration GIF. Each request and addon must be documented with a GIF that shows the feature - working. For example: - - # [Inlay hint demo](../../inlay_hint.gif) - DOCS - elsif !gif_exists?(file_path) - T.must(missing_docs[class_name]) << <<~DOCS - The GIF for the request documentation does not exist. Make sure to add it, - with the same naming as the request. For example: - - # lib/ruby_lsp/requests/code_lens.rb - # foo/bar/code_lens.gif - DOCS - end - end - - if missing_docs.any? - $stderr.puts(<<~WARN) - The following requests are missing documentation: - - #{missing_docs.map { |k, v| "#{k}\n\n#{v.join("\n")}" }.join("\n\n")} - WARN - - abort - end - - puts "All requests are documented!" - end - end -end diff --git a/rakelib/index.rake b/rakelib/index.rake index 726ae6e85..27e00d07a 100644 --- a/rakelib/index.rake +++ b/rakelib/index.rake @@ -1,5 +1,8 @@ # frozen_string_literal: true +require "sorbet-runtime" +require "ruby_lsp/internal" + # Based on https://github.com/ruby/prism/blob/main/rakelib/lex.rake module GemIndexing