Skip to content

Commit

Permalink
更新至 v5.2.1
Browse files Browse the repository at this point in the history
favicon 和 logo 固定为 SVG 格式,Firefox 支持 SVG 图片作为 favicon,
而 chrome 将在 80 版本支持 SVG,safari 也支持使用 mask-icon 作为图片。

修正 static.Pack 可能的错误,不再允许打包目标文件夹中的二进制文件,
将 favicon 允许的格式改为 SVG,也将唯一的进制文件 icon.png 去掉了。
  • Loading branch information
caixw committed Dec 17, 2019
1 parent 6bab7ad commit e87fa4c
Show file tree
Hide file tree
Showing 18 changed files with 139 additions and 95 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ dist
# project
.apidoc.yaml
.apidoc.yml
/.vscode
apidoc.json
apidoc.yaml
apidoc.xml

.vscode
.idea

.testdata
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# CHANGELOG

## [Unreleased]
## [v5.2.1]

### Changed

- favicon 现在只支持 SVG 格式的图片;

### Fixed

- 修正 Pack 可能将二进制等文件进行打包的错误;

## [v5.2.0]

Expand Down
2 changes: 1 addition & 1 deletion apidoc.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func Pack(h *message.Handler, url string, contentType, pkgName, varName, path st
contentType = http.DetectContentType(data)
}

return static.Pack("./docs", pkgName, varName, path, t, nil, &static.FileInfo{
return static.Pack("./docs", pkgName, varName, path, t, &static.FileInfo{
Name: url,
Content: data,
ContentType: contentType,
Expand Down
2 changes: 1 addition & 1 deletion config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type Config struct {

// LoadConfig 加载指定目录下的配置文件
//
// 所有的错误信息会输出到 h
// 所有的错误信息会输出到 h,在出错时,会返回 nil
func LoadConfig(h *message.Handler, wd string) *Config {
for _, filename := range vars.AllowConfigFilenames {
p := filepath.Join(wd, filename)
Expand Down
94 changes: 76 additions & 18 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ package apidoc
import (
"bytes"
"path/filepath"
"strconv"
"testing"
"time"

Expand All @@ -14,15 +13,40 @@ import (
"github.com/caixw/apidoc/v5/input"
"github.com/caixw/apidoc/v5/internal/vars"
"github.com/caixw/apidoc/v5/message"
"github.com/caixw/apidoc/v5/static"
)

func buildMessageHandle() (*bytes.Buffer, message.HandlerFunc) {
buf := new(bytes.Buffer)

return buf, func(msg *message.Message) {
buf.WriteString(strconv.Itoa(int(msg.Type)))
buf.WriteString(msg.Message)
func buildMessageHandle() (erro, succ *bytes.Buffer, h *message.Handler) {
erro = new(bytes.Buffer)
succ = new(bytes.Buffer)

f := func(msg *message.Message) {
switch msg.Type {
case message.Erro:
erro.WriteString(msg.Message)
default:
succ.WriteString(msg.Message)
}
}

return erro, succ, message.NewHandler(f)
}

func TestLoadConfig(t *testing.T) {
a := assert.New(t)

erro, succ, h := buildMessageHandle()
cfg := LoadConfig(h, "./")
a.NotNil(cfg).
Empty(erro.String())

erro, succ, h = buildMessageHandle()
cfg = LoadConfig(h, "./docs") // 不存在 apidoc 的配置文件

h.Stop()
a.Nil(cfg).
NotEmpty(erro.String()).
Empty(succ.String())
}

func TestLoadFile(t *testing.T) {
Expand All @@ -42,9 +66,9 @@ func TestDetect_Load(t *testing.T) {
a.NotError(err).NotEmpty(wd)
a.NotError(Detect(wd, true))

out, f := buildMessageHandle()
cfg := LoadConfig(message.NewHandler(f), wd)
a.Empty(out.String()).NotNil(cfg)
erro, _, h := buildMessageHandle()
cfg := LoadConfig(h, wd)
a.Empty(erro.String()).NotNil(cfg)

a.Equal(cfg.Version, vars.Version()).
Equal(cfg.Inputs[0].Lang, "go")
Expand Down Expand Up @@ -78,21 +102,55 @@ func TestConfig_sanitize(t *testing.T) {
Equal(err.Field, "output")
}

func TestConfig_Test(t *testing.T) {
a := assert.New(t)

erro, succ, h := buildMessageHandle()
cfg := LoadConfig(h, "./docs/example")
a.NotNil(cfg)
cfg.Test()

h.Stop()
a.Empty(erro.String()).
NotEmpty(succ.String()) // 有成功提示
}

func TestConfig_Pack(t *testing.T) {
a := assert.New(t)

erro, succ, h := buildMessageHandle()
cfg := LoadConfig(h, "./docs/example")
a.NotNil(cfg)
cfg.Pack("testdata", "Data", "./.testdata", "apidoc.xml", "application/xml", static.TypeAll)

h.Stop()
a.Empty(erro.String()).
Empty(succ.String())
}

func TestConfig_Do(t *testing.T) {
a := assert.New(t)

out, f := buildMessageHandle()
h := message.NewHandler(f)
LoadConfig(h, "./docs/example").Do(time.Now())
a.Empty(out.String())
erro, succ, h := buildMessageHandle()
cfg := LoadConfig(h, "./docs/example")
a.NotNil(cfg)
cfg.Do(time.Now())

h.Stop()
a.NotEmpty(succ.String()). // 有成功提示
Empty(erro.String())
}

func TestConfig_Buffer(t *testing.T) {
a := assert.New(t)

out, f := buildMessageHandle()
h := message.NewHandler(f)
buf := LoadConfig(h, "./docs/example").Buffer()
a.Empty(out.String()).
erro, succ, h := buildMessageHandle()
cfg := LoadConfig(h, "./docs/example")
a.NotNil(cfg)

buf := cfg.Buffer()
h.Stop()
a.Empty(erro.String()).
Empty(succ.String()).
True(buf.Len() > 0)
}
2 changes: 1 addition & 1 deletion docs/example/.apidoc.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 5.0.0
version: 5.2.0
inputs:
- lang: c++
dir: .
Expand Down
2 changes: 1 addition & 1 deletion docs/example/index.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>

<?xml-stylesheet type="text/xsl" href="../v5/apidoc.xsl"?>
<apidoc apidoc="5.2.0" created="2019-12-17T21:57:24+08:00" version="1.1.1">
<apidoc apidoc="5.2.1" created="2019-12-18T00:16:56+08:00" version="1.1.1">
<title>示例文档</title>
<description type="html"><![CDATA[
Expand Down
Binary file removed docs/icon.png
Binary file not shown.
2 changes: 1 addition & 1 deletion docs/index.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
<description><p>用于描述整个文档的相关内容,只能出现一次。</p></description>
<item name="@version">文档的版本</item>
<item name="@lang">内容的本地化 ID,比如 <samp><var>zh-hans</var></samp> 等。</item>
<item name="@logo">图标</item>
<item name="@logo">图标,默认采用官网的 <var>https://apidoc.tools/icon.svg</var>,同时作用于 favicon 和 logo,只支持 SVG 格式。</item>
<item name="@created">文档的生成时间</item>
<item name="title">文档的标题</item>
<item name="description">文档的整体介绍,可以是使用 HTML 内容。</item>
Expand Down
3 changes: 2 additions & 1 deletion docs/index.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1"/>
<meta name="keywords" content="{$keywords}RESTful API,document,apidoc" />
<link rel="icon" type="image/png" href="./icon.png" />
<link rel="icon" type="image/svg+xml" href="./icon.svg" />
<link rel="mask-icon" type="image/svg+xml" href="./icon.svg" color="black" />
<link rel="canonical" href="{document('config.xml')/config/url}" />
<link rel="stylesheet" type="text/css" href="./index.css" />
<link rel="license" href="{/docs/liense/@url}" />
Expand Down
2 changes: 1 addition & 1 deletion docs/index.zh-hant.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
<description><p>用於描述整個文檔的相關內容,只能出現壹次。</p></description>
<item name="@version">文檔的版本</item>
<item name="@lang">內容的本地化 ID,比如 <samp><var>zh-hans</var></samp> 等。</item>
<item name="@logo">圖標</item>
<item name="@logo">圖標,默認采用官網的 <var>https://apidoc.tools/icon.svg</var>,同時作用於 favicon 和 logo,只支持 SVG 格式。</item>
<item name="@created">文檔的生成時間</item>
<item name="title">文檔的標題</item>
<item name="description">文檔的整體介紹,可以是使用 HTML 內容。</item>
Expand Down
5 changes: 3 additions & 2 deletions docs/v5/apidoc.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1" />
<meta name="generator" content="apidoc" />
<link rel="icon" type="image/png" href="{$icon}" />
<link rel="icon" type="image/svg+xml" href="{$icon}" />
<link rel="mask-icon" type="image/svg+xml" href="{$icon}" color="black" />
<xsl:if test="apidoc/license"><link rel="license" href="{apidoc/license/@url}" /></xsl:if>
<link rel="stylesheet" type="text/css" href="{$base-url}apidoc.css" />
<script src="{$base-url}apidoc.js"></script>
Expand Down Expand Up @@ -509,7 +510,7 @@
<xsl:value-of select="/apidoc/@logo" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($base-url, '../icon.png')" />
<xsl:value-of select="concat($base-url, '../icon.svg')" />
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
Expand Down
2 changes: 1 addition & 1 deletion internal/vars/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import "strings"
//
// 遵守 https://semver.org/lang/zh-CN/ 规则。
// 程序不兼容或是文档格式不兼容时,需要提升主版本号。
const version = "5.2.0"
const version = "5.2.1"

var (
fullVersion = version
Expand Down
61 changes: 20 additions & 41 deletions static/pack.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,24 @@
package static

import (
"bufio"
"bytes"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
"unicode"

"github.com/issue9/utils"

"github.com/caixw/apidoc/v5/internal/locale"
"github.com/caixw/apidoc/v5/message"
)

const goModPath = "../go.mod"
const modulePath = "github.com/caixw/apidoc/v5/static"

const header = "// 当前文件由工具自动生成,请勿手动修改!\n\n"

var allowPackExts = []string{
".xml", ".xsl", ".svg",
".css", ".js", ".html", ".htm",
}

// FileInfo 被打包文件的信息
type FileInfo struct {
// 相对于打包根目录的地址,同时也会被作为路由地址
Expand All @@ -39,6 +38,8 @@ type FileInfo struct {
// path 内容保存的文件名;
// t 打包的文件类型,如果为 TypeNone,则只打包 addTo 的内容;
// addTo 追加的打包内容;
//
// NOTE: 隐藏文件不会被打包
func Pack(root, pkgName, varName, path string, t Type, addTo ...*FileInfo) error {
fis, err := getFileInfos(root, t)
if err != nil {
Expand All @@ -58,11 +59,7 @@ func Pack(root, pkgName, varName, path string, t Type, addTo ...*FileInfo) error

ws("package ", pkgName, "\n\n")

goMod, err := getPkgPath(goModPath)
if err != nil {
return err
}
ws("import \"", goMod+"/static", "\"\n\n")
ws("import \"", modulePath, "\"\n\n")

ws("var ", varName, "= []*static.FileInfo{")
for _, info := range fis {
Expand All @@ -82,24 +79,25 @@ func getFileInfos(root string, t Type) ([]*FileInfo, error) {
return nil, nil
}

paths := []string{}
var paths []string

walk := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}

if info.IsDir() {
// 过滤各类未知的隐藏文件
if info.IsDir() || !isAllowPackFile(filepath.Ext(info.Name())) {
return nil
}

relpath, err := filepath.Rel(root, path)
relPath, err := filepath.Rel(root, path)
if err != nil {
return err
}

if t != TypeStylesheet || isStylesheetFile(relpath) {
paths = append(paths, relpath)
if t != TypeStylesheet || isStylesheetFile(relPath) {
paths = append(paths, relPath)
}

return nil
Expand Down Expand Up @@ -144,30 +142,11 @@ func dump(buf *bytes.Buffer, file *FileInfo) (err error) {
return err
}

const modulePrefix = "module"

// 分析 go.mod 文件,获取其中的 module 值
func getPkgPath(path string) (string, error) {
file, err := os.Open(path)
if err != nil {
return "", err
}

s := bufio.NewScanner(bufio.NewReader(file))
s.Split(bufio.ScanLines)
for s.Scan() {
line := strings.TrimSpace(s.Text())
if !strings.HasPrefix(line, modulePrefix) {
continue
func isAllowPackFile(ext string) bool {
for _, e := range allowPackExts {
if e == ext {
return true
}

line = line[len(modulePrefix):]
if line == "" || !unicode.IsSpace(rune(line[0])) {
continue
}

return strings.TrimSpace(line), nil
}

return "", message.NewLocaleError(goModPath, "", 0, locale.ErrInvalidFormat)
return false
}
Loading

0 comments on commit e87fa4c

Please sign in to comment.