diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eac731..c515221 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ A concise overview of the public-facing changes to the gem from version to versi ## Unreleased +- Add Rake task `graphql-docs:generate` for integration with Rails and other Ruby projects that use Rake. Supports both task arguments and environment variables for configuration. Can be used with `Rake::Task["assets:precompile"].enhance(["graphql-docs:generate"])` to generate docs as part of the build process. + ## v5.2.0 - 2025-02-09 - Add search filter to sidebar. Thanks @denisahearn! diff --git a/README.md b/README.md index a4e9bb7..d3aa319 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,80 @@ See all of the supported CLI options with: graphql-docs -h ``` +### Rake Task + +GraphQLDocs includes a Rake task for integration with Rails applications and other Ruby projects that use Rake. This allows you to generate documentation as part of your build process or hook it into other Rake tasks. + +#### Basic Usage + +Using task arguments (recommended): + +```console +rake graphql-docs:generate[schema.graphql] +rake graphql-docs:generate[schema.graphql,./docs] +rake graphql-docs:generate[schema.graphql,./docs,/api-docs,true] +``` + +Or using environment variables: + +```console +GRAPHQL_SCHEMA_FILE=schema.graphql rake graphql-docs:generate +``` + +#### Available Arguments + +Arguments are passed in order: `[schema_file, output_dir, base_url, delete_output]` + +1. `schema_file` - Path to GraphQL schema file (required) +2. `output_dir` - Output directory (default: `./output/`) +3. `base_url` - Base URL for assets and links (default: `''`) +4. `delete_output` - Delete output directory before generating (`true`/`false`, default: `false`) + +#### Available Environment Variables + +- `GRAPHQL_SCHEMA_FILE` - Path to GraphQL schema file (required) +- `GRAPHQL_OUTPUT_DIR` - Output directory (default: `./output/`) +- `GRAPHQL_BASE_URL` - Base URL for assets and links (default: `''`) +- `GRAPHQL_DELETE_OUTPUT` - Delete output directory before generating (`true`/`false`) + +Note: Task arguments take precedence over environment variables. + +#### Example: Generate Docs Before Asset Compilation + +In Rails, you can automatically generate documentation before compiling assets: + +```ruby +# Rakefile or lib/tasks/docs.rake +Rake::Task["assets:precompile"].enhance(["graphql-docs:generate"]) +``` + +Then configure using environment variables: + +```ruby +# config/application.rb or .env +ENV["GRAPHQL_SCHEMA_FILE"] = Rails.root.join("app/graphql/schema.graphql").to_s +``` + +Or invoke with arguments in your custom task: + +```ruby +# lib/tasks/custom_docs.rake +namespace :docs do + desc "Generate API documentation" + task :generate do + Rake::Task["graphql-docs:generate"].invoke( + "app/graphql/schema.graphql", # schema_file + "public/api-docs", # output_dir + "/api-docs", # base_url + "true" # delete_output + ) + end +end + +# Hook into asset compilation +Rake::Task["assets:precompile"].enhance(["docs:generate"]) +``` + ### Rack Application (Dynamic) For more flexibility and control, you can serve documentation dynamically using the Rack application. This is useful for: diff --git a/Rakefile b/Rakefile index 645b36e..fe01384 100644 --- a/Rakefile +++ b/Rakefile @@ -5,6 +5,9 @@ require "rake/testtask" require "standard/rake" +# Load graphql-docs rake tasks +Dir.glob("lib/tasks/**/*.rake").each { |r| load r } + Rake::TestTask.new(:test) do |t| t.libs << "test" t.libs << "lib" diff --git a/lib/tasks/graphql-docs.rake b/lib/tasks/graphql-docs.rake new file mode 100644 index 0000000..f1ed696 --- /dev/null +++ b/lib/tasks/graphql-docs.rake @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +begin + require "graphql-docs" + + namespace :"graphql-docs" do + desc "Generate GraphQL documentation from schema" + task :generate, [:schema_file, :output_dir, :base_url, :delete_output] do |_t, args| + options = {} + + # Prefer task arguments over environment variables + options[:filename] = args[:schema_file] || ENV["GRAPHQL_SCHEMA_FILE"] + options[:output_dir] = args[:output_dir] || ENV["GRAPHQL_OUTPUT_DIR"] + options[:base_url] = args[:base_url] || ENV["GRAPHQL_BASE_URL"] + + # Handle delete_output as a boolean + delete_output_arg = args[:delete_output] || ENV["GRAPHQL_DELETE_OUTPUT"] + options[:delete_output] = delete_output_arg == "true" if delete_output_arg + + # Check if a schema file is specified + if options[:filename].nil? + puts "Please specify a GraphQL schema file:" + puts "" + puts "Using task arguments:" + puts " rake graphql-docs:generate[path/to/schema.graphql]" + puts " rake graphql-docs:generate[schema.graphql,./docs]" + puts " rake graphql-docs:generate[schema.graphql,./docs,/api-docs,true]" + puts "" + puts "Or using environment variables:" + puts " GRAPHQL_SCHEMA_FILE=path/to/schema.graphql rake graphql-docs:generate" + puts "" + puts "Available arguments (in order):" + puts " 1. schema_file - Path to GraphQL schema file (required)" + puts " 2. output_dir - Output directory (default: ./output/)" + puts " 3. base_url - Base URL for assets and links (default: '')" + puts " 4. delete_output - Delete output directory before generating (true/false, default: false)" + puts "" + puts "Available environment variables:" + puts " GRAPHQL_SCHEMA_FILE - Path to GraphQL schema file (required)" + puts " GRAPHQL_OUTPUT_DIR - Output directory (default: ./output/)" + puts " GRAPHQL_BASE_URL - Base URL for assets and links (default: '')" + puts " GRAPHQL_DELETE_OUTPUT - Delete output directory before generating (true/false)" + exit 1 + end + + puts "Generating GraphQL documentation..." + puts " Schema: #{options[:filename]}" + puts " Output: #{options[:output_dir] || "./output/"}" + + GraphQLDocs.build(options) + + puts "Documentation generated successfully!" + end + end +rescue LoadError + # graphql-docs not available, skip task definition +end diff --git a/test/rake_task_test.rb b/test/rake_task_test.rb new file mode 100644 index 0000000..000ba04 --- /dev/null +++ b/test/rake_task_test.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require "test_helper" +require "rake" + +class RakeTaskTest < Minitest::Test + def setup + # Clear any existing tasks to ensure clean state + Rake::Task.clear if Rake::Task.respond_to?(:clear) + + @rake = Rake::Application.new + Rake.application = @rake + + # Load the graphql-docs library and the rake task + require "graphql-docs" + load File.expand_path("../lib/tasks/graphql-docs.rake", __dir__) + end + + def teardown + # Clean up the task + Rake::Task["graphql-docs:generate"].clear if Rake::Task.task_defined?("graphql-docs:generate") + Rake.application = nil + end + + def test_rake_task_is_defined + assert Rake::Task.task_defined?("graphql-docs:generate"), "graphql-docs:generate task should be defined" + end + + def test_rake_task_name_is_correct + task = Rake::Task["graphql-docs:generate"] + assert_equal "graphql-docs:generate", task.name + end + + def test_rake_task_exits_without_schema_file + task = Rake::Task["graphql-docs:generate"] + + # Capture output and exit + out, _err = capture_io do + assert_raises(SystemExit) do + task.invoke + end + end + + assert_match(/Please specify a GraphQL schema file/, out) + assert_match(/Using task arguments/, out) + assert_match(/Or using environment variables/, out) + end + + def test_rake_task_can_be_enhanced + # This test verifies that the task can be used in task dependencies + # which is the main use case mentioned in the requirements + task = Rake::Task["graphql-docs:generate"] + assert_respond_to task, :enhance + end + + def test_rake_task_accepts_arguments + # Verify that the task accepts the expected arguments + task = Rake::Task["graphql-docs:generate"] + assert task.arg_names.include?(:schema_file), "Task should accept schema_file argument" + assert task.arg_names.include?(:output_dir), "Task should accept output_dir argument" + assert task.arg_names.include?(:base_url), "Task should accept base_url argument" + assert task.arg_names.include?(:delete_output), "Task should accept delete_output argument" + end +end