Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add project name and version to API docs #8792

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ LIB_CRYSTAL_TARGET = src/ext/libcrystal.a
DEPS = $(LLVM_EXT_OBJ) $(LIB_CRYSTAL_TARGET)
CFLAGS += -fPIC $(if $(debug),-g -O0)
CXXFLAGS += $(if $(debug),-g -O0)
CRYSTAL_VERSION ?= $(shell cat src/VERSION)

ifeq ($(shell command -v ld.lld >/dev/null && uname -s),Linux)
EXPORT_CC ?= CC="cc -fuse-ld=lld"
Expand Down Expand Up @@ -90,7 +91,7 @@ compiler_spec: $(O)/compiler_spec ## Run compiler specs

.PHONY: docs
docs: ## Generate standard library documentation
$(BUILD_PATH) ./bin/crystal docs src/docs_main.cr $(DOCS_OPTIONS)
$(BUILD_PATH) ./bin/crystal docs src/docs_main.cr $(DOCS_OPTIONS) --project-name=Crystal --project-version=$(CRYSTAL_VERSION)

.PHONY: crystal
crystal: $(O)/crystal ## Build the compiler
Expand Down
62 changes: 62 additions & 0 deletions spec/compiler/crystal/tools/doc_spec.cr
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require "../../../spec_helper"
require "../../../support/tempfile"

private def assert_matches_pattern(url, **options)
match = Crystal::Doc::Generator::GIT_REMOTE_PATTERNS.each_key.compact_map(&.match(url)).first?
Expand Down Expand Up @@ -60,3 +61,64 @@ describe Crystal::Doc::Generator do
end
end
end

describe Crystal::Doc::ProjectInfo do
it "find_default_version" do
with_tempfile("docs-git-version") do |tempdir|
Dir.mkdir tempdir
Dir.cd(tempdir) do
# Non-git directory
Crystal::Doc::ProjectInfo.find_default_version.should be_nil

`git init`
Crystal::Doc::ProjectInfo.find_default_version.should be_nil

File.write("file.txt", "foo")
`git add file.txt`
`git commit -m 'Initial commit' --no-gpg-sign`
Crystal::Doc::ProjectInfo.find_default_version.should be_nil

`git tag v0.1.0`
`git tag --list`
`git log`
Crystal::Doc::ProjectInfo.find_default_version.should eq "v0.1.0"

File.write("file.txt", "bar")
Crystal::Doc::ProjectInfo.find_default_version.should be_nil

`git add file.txt`
Crystal::Doc::ProjectInfo.find_default_version.should be_nil

`git reset --hard v0.1.0`
Crystal::Doc::ProjectInfo.find_default_version.should eq "v0.1.0"

`git tag v0.2.0`
Crystal::Doc::ProjectInfo.find_default_version.should be_nil
end
end
end

it "find_default_name" do
with_tempfile("docs-shard-name") do |tempdir|
Dir.mkdir tempdir
Dir.cd(tempdir) do
Crystal::Doc::ProjectInfo.find_default_name.should be_nil

File.write("shard.yml", "foo: bar\n")
Crystal::Doc::ProjectInfo.find_default_name.should be_nil

File.write("shard.yml", "name: \n")
Crystal::Doc::ProjectInfo.find_default_name.should be_nil

File.write("shard.yml", " name: bar\n")
Crystal::Doc::ProjectInfo.find_default_name.should be_nil

File.write("shard.yml", "name: bar\n")
Crystal::Doc::ProjectInfo.find_default_name.should eq "bar"

File.write("shard.yml", "name: bar # comment\n")
Crystal::Doc::ProjectInfo.find_default_name.should eq "bar"
end
end
end
end
32 changes: 31 additions & 1 deletion src/compiler/crystal/command/docs.cr
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class Crystal::Command
sitemap_base_url = nil
sitemap_priority = "1.0"
sitemap_changefreq = "never"
project_name = nil
project_version = nil

compiler = Compiler.new

Expand All @@ -24,6 +26,14 @@ class Crystal::Command
Options:
BANNER

opts.on("--project-name=NAME", "Set project name") do |value|
project_name = value
end

opts.on("--project-version=VERSION", "Set project version") do |value|
project_version = value
end

opts.on("--output=DIR", "-o DIR", "Set the output directory (default: #{output_directory})") do |value|
output_directory = value
end
Expand Down Expand Up @@ -88,6 +98,8 @@ class Crystal::Command
setup_compiler_warning_options(opts, compiler)
end

project_info = create_project_info(project_name, project_version)

if options.empty?
sources = [Compiler::Source.new("require", %(require "./src/**"))]
included_dirs = [] of String
Expand All @@ -103,9 +115,27 @@ class Crystal::Command
compiler.wants_doc = true
result = compiler.top_level_semantic sources

Doc::Generator.new(result.program, included_dirs, output_directory, output_format, sitemap_base_url, sitemap_priority, sitemap_changefreq).run
Doc::Generator.new(result.program, included_dirs, output_directory, output_format, sitemap_base_url, sitemap_priority, sitemap_changefreq, project_info).run

report_warnings result
exit 1 if warnings_fail_on_exit?(result)
end

private def create_project_info(name, version)
name ||= Doc::ProjectInfo.find_default_name
unless name
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
STDERR.puts "Couldn't determine name from shard.yml, please provide --project-name option"
end

version ||= Doc::ProjectInfo.find_default_version
unless version
STDERR.puts "Couldn't determine version from git, please provide --project-version option"
straight-shoota marked this conversation as resolved.
Show resolved Hide resolved
end

unless name && version
abort
end

Doc::ProjectInfo.new(name, version)
end
end
10 changes: 6 additions & 4 deletions src/compiler/crystal/tools/doc/generator.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class Crystal::Doc::Generator
property is_crystal_repo : Bool
@repository : String? = nil
getter repository_name = ""
getter project_info

# Adding a flag and associated css class will add support in parser
FLAG_COLORS = {
Expand All @@ -29,13 +30,14 @@ class Crystal::Doc::Generator
}

def self.new(program : Program, included_dirs : Array(String))
new(program, included_dirs, ".", "html", nil, "1.0", "never")
new(program, included_dirs, ".", "html", nil, "1.0", "never", ProjectInfo.new("test", "0.0.0-test"))
end

def initialize(@program : Program, @included_dirs : Array(String),
@output_dir : String, @output_format : String,
@sitemap_base_url : String?,
@sitemap_priority : String, @sitemap_changefreq : String)
@sitemap_priority : String, @sitemap_changefreq : String,
@project_info : ProjectInfo)
@base_dir = Dir.current.chomp
@types = {} of Crystal::Type => Doc::Type
@repo_name = ""
Expand Down Expand Up @@ -95,7 +97,7 @@ class Crystal::Doc::Generator
raw_body = read_readme
body = doc(program_type, raw_body)

File.write File.join(@output_dir, "index.html"), MainTemplate.new(body, types, repository_name)
File.write File.join(@output_dir, "index.html"), MainTemplate.new(body, types, project_info)

main_index = Main.new(raw_body, Type.new(self, @program), repository_name)
File.write File.join(@output_dir, "index.json"), main_index
Expand Down Expand Up @@ -124,7 +126,7 @@ class Crystal::Doc::Generator
filename = File.join(dir, "#{type.name}.html")
end

File.write filename, TypeTemplate.new(type, all_types)
File.write filename, TypeTemplate.new(type, all_types, project_info)

next if type.program?

Expand Down
12 changes: 12 additions & 0 deletions src/compiler/crystal/tools/doc/html/_sidebar.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@
<input type="search" class="search-input" placeholder="Search..." spellcheck="false" aria-label="Search">
</div>

<div class="project-summary">
<h1 class="project-name">
<a href="<%= current_type.try(&.path_to("")) %>index.html">
<%= project_info.name %>
</a>
</h1>

<span class="project-version">
<%= project_info.version %>
</span>
</div>

<div class="repository-links">
<a href="<%= current_type.try(&.path_to("")) %>index.html">README</a>
</div>
Expand Down
20 changes: 19 additions & 1 deletion src/compiler/crystal/tools/doc/html/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ body {
}

.sidebar .search-box {
padding: 8px 9px;
padding: 13px 9px;
}

.sidebar input {
Expand Down Expand Up @@ -106,6 +106,24 @@ body {
text-indent: 2px;
}

.project-summary {
display: inline-block;
padding: 9px 15px 30px 30px;
text-align: right;
}

.project-name {
font-size: 1.4rem;
margin: 0;
color: #f4f4f4;
font-weight: 600;
}

.project-version {
margin-top: 5px;
display: block;
}

.sidebar ul {
margin: 0;
padding: 0;
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/crystal/tools/doc/html/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<html lang="en">
<head>
<%= HeadTemplate.new("") %>
<meta id="repository-name" content="<%= repository_name %>">
<title>README - <%= repository_name %></title>
<meta id="repository-name" content="<%= project_info.name %>">
<title><%= project_info.name %> <%= project_info.version %></title>
<script type="text/javascript">
CrystalDoc.base_path = "";
</script>
</head>
<body>

<%= SidebarTemplate.new(repository_name, types, nil) %>
<%= SidebarTemplate.new(project_info, types, nil) %>

<div class="main-content">
<%= body %>
Expand Down
6 changes: 3 additions & 3 deletions src/compiler/crystal/tools/doc/html/type.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<html lang="en">
<head>
<%= HeadTemplate.new(type.path_to "") %>
<meta id="repository-name" content="<%= type.repository_name %>">
<title><%= type.full_name %> - <%= type.repository_name %></title>
<meta id="repository-name" content="<%= project_info.name %>">
<title><%= type.full_name %> - <%= project_info.name %> <%= project_info.version %></title>
<script type="text/javascript">
CrystalDoc.base_path = "<%= type.path_to "" %>";
</script>
</head>
<body>

<%= SidebarTemplate.new(type.repository_name, types, type) %>
<%= SidebarTemplate.new(project_info, types, type) %>

<div class="main-content">
<h1 class="type-name">
Expand Down
35 changes: 35 additions & 0 deletions src/compiler/crystal/tools/doc/project_info.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Crystal::Doc
record ProjectInfo, name : String, version : String do
def self.find_default_version
# Use git to determine if index and working directory are clean
io = IO::Memory.new
status = Process.run("git", ["status", "--porcelain"], output: io)
# If clean, output of `git status --porcelain` is empty. Still need to check
# the status code, to make sure empty doesn't mean error.
io.rewind
return unless status.success? && io.bytesize == 0

# Check if current HEAD is tagged
status = Process.run("git", ["tag", "--points-at", "HEAD"], output: io)
return unless status.success?
io.rewind
tags = io.to_s.lines
# Only accept when there's exactly one tag pointing at HEAD.
if tags.size == 1
tags.first
end
end

def self.find_default_name
return unless File.readable?("shard.yml")

# Poor man's YAML reader
File.each_line("shard.yml") do |line|
if line.starts_with?("name:")
end_pos = line.byte_index("#") || line.bytesize
return line.byte_slice(5, end_pos - 5).strip.presence
end
end
end
end
end
6 changes: 3 additions & 3 deletions src/compiler/crystal/tools/doc/templates.cr
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module Crystal::Doc
ANCHOR
end

record TypeTemplate, type : Type, types : Array(Type) do
record TypeTemplate, type : Type, types : Array(Type), project_info : ProjectInfo do
ECR.def_to_s "#{__DIR__}/html/type.html"
end

Expand All @@ -45,15 +45,15 @@ module Crystal::Doc
ECR.def_to_s "#{__DIR__}/html/_other_types.html"
end

record MainTemplate, body : String, types : Array(Type), repository_name : String do
record MainTemplate, body : String, types : Array(Type), project_info : ProjectInfo do
ECR.def_to_s "#{__DIR__}/html/main.html"
end

record HeadTemplate, base_path : String do
ECR.def_to_s "#{__DIR__}/html/_head.html"
end

record SidebarTemplate, repository_name : String, types : Array(Type), current_type : Type? do
record SidebarTemplate, project_info : ProjectInfo, types : Array(Type), current_type : Type? do
ECR.def_to_s "#{__DIR__}/html/_sidebar.html"
end

Expand Down
6 changes: 1 addition & 5 deletions src/compiler/crystal/tools/doc/type.cr
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,6 @@ class Crystal::Doc::Type
@generator.relative_locations(@type)
end

def repository_name
@generator.repository_name
end

def program?
@type.is_a?(Program)
end
Expand Down Expand Up @@ -795,7 +791,7 @@ class Crystal::Doc::Type
end
end
builder.field "locations", locations
builder.field "repository_name", repository_name
builder.field "repository_name", @generator.repository_name
builder.field "program", program?
builder.field "enum", enum?
builder.field "alias", alias?
Expand Down