Добавлен линтер golangci-lint
This commit is contained in:
parent
950aecc036
commit
b32f3ab88a
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.go text eol=lf
|
22
.gitea/workflows/golangci-lint.yaml
Normal file
22
.gitea/workflows/golangci-lint.yaml
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
name: golangci-lint
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go: [stable]
|
||||||
|
os: [ubuntu-latest, windows-latest]
|
||||||
|
name: lint
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
steps:
|
||||||
|
- name: check-out
|
||||||
|
uses: https://gitea.com/actions/checkout@v4
|
||||||
|
- name: set-up go
|
||||||
|
uses: https://gitea.com/actions/setup-go@v5
|
||||||
|
with:
|
||||||
|
go-version: ${{ matrix.go }}
|
||||||
|
- name: lint
|
||||||
|
uses: https://github.com/golangci/golangci-lint-action@v6
|
||||||
|
with:
|
||||||
|
version: v1.60
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -35,6 +35,6 @@ go.work
|
|||||||
# Built Visual Studio Code Extensions
|
# Built Visual Studio Code Extensions
|
||||||
*.vsix
|
*.vsix
|
||||||
|
|
||||||
# Vuild outputs
|
# Build outputs
|
||||||
tmp/
|
tmp/
|
||||||
out/
|
out/
|
||||||
|
314
.golangci.yaml
Normal file
314
.golangci.yaml
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
# This file contains all available configuration options
|
||||||
|
# with their default values (in comments).
|
||||||
|
#
|
||||||
|
# This file is not a configuration example,
|
||||||
|
# it contains the exhaustive configuration with explanations of the options.
|
||||||
|
|
||||||
|
linters:
|
||||||
|
# Disable all linters.
|
||||||
|
# Default: false
|
||||||
|
disable-all: true
|
||||||
|
# Enable specific linter
|
||||||
|
# https://golangci-lint.run/usage/linters/#enabled-by-default
|
||||||
|
enable:
|
||||||
|
- asasalint
|
||||||
|
- asciicheck
|
||||||
|
- bidichk
|
||||||
|
- bodyclose
|
||||||
|
- canonicalheader
|
||||||
|
- containedctx
|
||||||
|
- contextcheck
|
||||||
|
- copyloopvar
|
||||||
|
- cyclop
|
||||||
|
- decorder
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- dupword
|
||||||
|
- durationcheck
|
||||||
|
- err113
|
||||||
|
- errcheck
|
||||||
|
- errchkjson
|
||||||
|
- errname
|
||||||
|
- errorlint
|
||||||
|
- exhaustive
|
||||||
|
- fatcontext
|
||||||
|
- forcetypeassert
|
||||||
|
- funlen
|
||||||
|
- gci
|
||||||
|
- ginkgolinter
|
||||||
|
- gocheckcompilerdirectives
|
||||||
|
# - gochecknoglobals
|
||||||
|
- gochecknoinits
|
||||||
|
- gochecksumtype
|
||||||
|
- gocognit
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
- godot
|
||||||
|
- godox
|
||||||
|
- gofmt
|
||||||
|
- gofumpt
|
||||||
|
- goheader
|
||||||
|
- goimports
|
||||||
|
- gomoddirectives
|
||||||
|
- gomodguard
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- gosimple
|
||||||
|
- gosmopolitan
|
||||||
|
- govet
|
||||||
|
- grouper
|
||||||
|
- importas
|
||||||
|
- inamedparam
|
||||||
|
- ineffassign
|
||||||
|
- interfacebloat
|
||||||
|
- intrange
|
||||||
|
- ireturn
|
||||||
|
- lll
|
||||||
|
- loggercheck
|
||||||
|
- maintidx
|
||||||
|
- makezero
|
||||||
|
- mirror
|
||||||
|
- misspell
|
||||||
|
- mnd
|
||||||
|
- musttag
|
||||||
|
- nakedret
|
||||||
|
- nestif
|
||||||
|
- nilerr
|
||||||
|
- nilnil
|
||||||
|
- nlreturn
|
||||||
|
- noctx
|
||||||
|
- nolintlint
|
||||||
|
- nonamedreturns
|
||||||
|
- nosprintfhostport
|
||||||
|
- paralleltest
|
||||||
|
- perfsprint
|
||||||
|
- prealloc
|
||||||
|
- predeclared
|
||||||
|
- promlinter
|
||||||
|
- protogetter
|
||||||
|
- reassign
|
||||||
|
- revive
|
||||||
|
- rowserrcheck
|
||||||
|
- sloglint
|
||||||
|
- spancheck
|
||||||
|
- sqlclosecheck
|
||||||
|
- staticcheck
|
||||||
|
- stylecheck
|
||||||
|
- tagalign
|
||||||
|
- tagliatelle
|
||||||
|
- tenv
|
||||||
|
- testableexamples
|
||||||
|
- testifylint
|
||||||
|
- testpackage
|
||||||
|
- thelper
|
||||||
|
- tparallel
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- unused
|
||||||
|
- usestdlibvars
|
||||||
|
- varnamelen
|
||||||
|
- wastedassign
|
||||||
|
- whitespace
|
||||||
|
- wrapcheck
|
||||||
|
- wsl
|
||||||
|
- zerologlint
|
||||||
|
|
||||||
|
# Enable all available linters.
|
||||||
|
# Default: false
|
||||||
|
enable-all: false
|
||||||
|
|
||||||
|
# Enable only fast linters from enabled linters set (first run won't be fast)
|
||||||
|
# Default: false
|
||||||
|
fast: true
|
||||||
|
|
||||||
|
# All available settings of specific linters.
|
||||||
|
linters-settings:
|
||||||
|
cyclop:
|
||||||
|
# The maximal code complexity to report.
|
||||||
|
# Default: 10
|
||||||
|
max-complexity: 20
|
||||||
|
# Should ignore tests.
|
||||||
|
# Default: false
|
||||||
|
skip-tests: true
|
||||||
|
|
||||||
|
funlen:
|
||||||
|
# Checks the number of lines in a function.
|
||||||
|
# If lower than 0, disable the check.
|
||||||
|
# Default: 60
|
||||||
|
lines: 80
|
||||||
|
# Checks the number of statements in a function.
|
||||||
|
# If lower than 0, disable the check.
|
||||||
|
# Default: 40
|
||||||
|
statements: 50
|
||||||
|
# Ignore comments when counting lines.
|
||||||
|
# Default false
|
||||||
|
ignore-comments: true
|
||||||
|
|
||||||
|
gocognit:
|
||||||
|
# Minimal code complexity to report.
|
||||||
|
# Default: 30 (but we recommend 10-20)
|
||||||
|
min-complexity: 20
|
||||||
|
|
||||||
|
gocyclo:
|
||||||
|
# Minimal code complexity to report.
|
||||||
|
# Default: 30 (but we recommend 10-20)
|
||||||
|
min-complexity: 20
|
||||||
|
|
||||||
|
godot:
|
||||||
|
# Comments to be checked: `declarations`, `toplevel`, or `all`.
|
||||||
|
# Default: declarations
|
||||||
|
scope: all
|
||||||
|
# List of regexps for excluding particular comment lines from check.
|
||||||
|
# Default: []
|
||||||
|
exclude:
|
||||||
|
# Exclude todo and fixme comments.
|
||||||
|
- "^fixme:"
|
||||||
|
- "^todo:"
|
||||||
|
# Check that each sentence ends with a period.
|
||||||
|
# Default: true
|
||||||
|
period: false
|
||||||
|
# Check that each sentence starts with a capital letter.
|
||||||
|
# Default: false
|
||||||
|
capital: true
|
||||||
|
|
||||||
|
goimports:
|
||||||
|
local-prefixes: git.mousesoft.ru/ms/drawio-export
|
||||||
|
|
||||||
|
gosec:
|
||||||
|
excludes:
|
||||||
|
- G115
|
||||||
|
|
||||||
|
revive:
|
||||||
|
rules:
|
||||||
|
- name: unexported-return
|
||||||
|
disabled: true
|
||||||
|
|
||||||
|
# output configuration options
|
||||||
|
output:
|
||||||
|
# The formats used to render issues.
|
||||||
|
# Formats:
|
||||||
|
# - `colored-line-number`
|
||||||
|
# - `line-number`
|
||||||
|
# - `json`
|
||||||
|
# - `colored-tab`
|
||||||
|
# - `tab`
|
||||||
|
# - `html`
|
||||||
|
# - `checkstyle`
|
||||||
|
# - `code-climate`
|
||||||
|
# - `junit-xml`
|
||||||
|
# - `junit-xml-extended`
|
||||||
|
# - `github-actions`
|
||||||
|
# - `teamcity`
|
||||||
|
# - `sarif`
|
||||||
|
# Output path can be either `stdout`, `stderr` or path to the file to write to.
|
||||||
|
#
|
||||||
|
# For the CLI flag (`--out-format`), multiple formats can be specified by separating them by comma.
|
||||||
|
# The output can be specified for each of them by separating format name and path by colon symbol.
|
||||||
|
# Example: "--out-format=checkstyle:report.xml,json:stdout,colored-line-number"
|
||||||
|
# The CLI flag (`--out-format`) override the configuration file.
|
||||||
|
#
|
||||||
|
# Default:
|
||||||
|
# formats:
|
||||||
|
# - format: colored-line-number
|
||||||
|
# path: stdout
|
||||||
|
formats:
|
||||||
|
# - format: json
|
||||||
|
# path: stderr
|
||||||
|
# - format: checkstyle
|
||||||
|
# path: report.xml
|
||||||
|
- format: colored-line-number
|
||||||
|
|
||||||
|
# Print lines of code with issue.
|
||||||
|
# Default: true
|
||||||
|
print-issued-lines: false
|
||||||
|
|
||||||
|
# Print linter name in the end of issue text.
|
||||||
|
# Default: true
|
||||||
|
print-linter-name: true
|
||||||
|
|
||||||
|
# Make issues output unique by line.
|
||||||
|
# Default: true
|
||||||
|
uniq-by-line: false
|
||||||
|
|
||||||
|
# Add a prefix to the output file references.
|
||||||
|
# Default: ""
|
||||||
|
path-prefix: ""
|
||||||
|
|
||||||
|
# Sort results by the order defined in `sort-order`.
|
||||||
|
# Default: false
|
||||||
|
sort-results: true
|
||||||
|
|
||||||
|
# Order to use when sorting results.
|
||||||
|
# Require `sort-results` to `true`.
|
||||||
|
# Possible values: `file`, `linter`, and `severity`.
|
||||||
|
#
|
||||||
|
# If the severity values are inside the following list, they are ordered in this order:
|
||||||
|
# 1. error
|
||||||
|
# 2. warning
|
||||||
|
# 3. high
|
||||||
|
# 4. medium
|
||||||
|
# 5. low
|
||||||
|
# Either they are sorted alphabetically.
|
||||||
|
#
|
||||||
|
# Default: ["file"]
|
||||||
|
sort-order:
|
||||||
|
- linter
|
||||||
|
- severity
|
||||||
|
- file # filepath, line, and column.
|
||||||
|
|
||||||
|
# Show statistics per linter.
|
||||||
|
# Default: false
|
||||||
|
show-stats: true
|
||||||
|
|
||||||
|
# Options for analysis running.
|
||||||
|
run:
|
||||||
|
# Timeout for analysis, e.g. 30s, 5m.
|
||||||
|
# Default: 1m
|
||||||
|
timeout: 5m
|
||||||
|
|
||||||
|
# Exit code when at least one issue was found.
|
||||||
|
# Default: 1
|
||||||
|
issues-exit-code: 2
|
||||||
|
|
||||||
|
# Include test files or not.
|
||||||
|
# Default: true
|
||||||
|
tests: false
|
||||||
|
|
||||||
|
# List of build tags, all linters use it.
|
||||||
|
# Default: []
|
||||||
|
build-tags:
|
||||||
|
- mytag
|
||||||
|
|
||||||
|
# If set, we pass it to "go list -mod={option}". From "go help modules":
|
||||||
|
# If invoked with -mod=readonly, the go command is disallowed from the implicit
|
||||||
|
# automatic updating of go.mod described above. Instead, it fails when any changes
|
||||||
|
# to go.mod are needed. This setting is most useful to check that go.mod does
|
||||||
|
# not need updates, such as in a continuous integration and testing system.
|
||||||
|
# If invoked with -mod=vendor, the go command assumes that the vendor
|
||||||
|
# directory holds the correct copies of dependencies and ignores
|
||||||
|
# the dependency descriptions in go.mod.
|
||||||
|
#
|
||||||
|
# Allowed values: readonly|vendor|mod
|
||||||
|
# Default: ""
|
||||||
|
modules-download-mode: readonly
|
||||||
|
|
||||||
|
# Allow multiple parallel golangci-lint instances running.
|
||||||
|
# If false, golangci-lint acquires file lock on start.
|
||||||
|
# Default: false
|
||||||
|
allow-parallel-runners: true
|
||||||
|
|
||||||
|
# Allow multiple golangci-lint instances running, but serialize them around a lock.
|
||||||
|
# If false, golangci-lint exits with an error if it fails to acquire file lock on start.
|
||||||
|
# Default: false
|
||||||
|
allow-serial-runners: true
|
||||||
|
|
||||||
|
# Define the Go version limit.
|
||||||
|
# Mainly related to generics support since go1.18.
|
||||||
|
# Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.17
|
||||||
|
go: "1.22"
|
||||||
|
|
||||||
|
# Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously.
|
||||||
|
# If it is explicitly set to 0 (i.e. not the default) then golangci-lint will automatically set the value to match Linux container CPU quota.
|
||||||
|
# Default: the number of logical CPUs in the machine
|
||||||
|
concurrency: 4
|
12
README.md
12
README.md
@ -7,15 +7,8 @@
|
|||||||
|
|
||||||
## Разработка
|
## Разработка
|
||||||
|
|
||||||
Для удобного редактирования, сборки, отладки и тестирования проекта в локальном
|
В проекте приняты (не строго обязательные) соглашения
|
||||||
окружении программиста необходимо выполнить следующие действия:
|
[Uber Go Style Guide](https://github.com/uber-go/guide/blob/master/style.md).
|
||||||
|
|
||||||
1. Клонировать репозиторий проекта в папку `$GOPATH/src/git.mousesoft.ru/ms/`.
|
|
||||||
2. Установить все Go-пакеты, от которых зависит этот проект
|
|
||||||
(см. следующий раздел).
|
|
||||||
3. Если предполагается формирование отчёта о покрытии кода модульными тестами,
|
|
||||||
то нужно установить необходимые для этого пакеты
|
|
||||||
(см. раздел [Тестирование](#тестирование) далее).
|
|
||||||
|
|
||||||
### Структура проекта
|
### Структура проекта
|
||||||
|
|
||||||
@ -25,6 +18,7 @@
|
|||||||
- `build` - Сборка и непрерывная интеграция (Continuous Integration, *CI*).
|
- `build` - Сборка и непрерывная интеграция (Continuous Integration, *CI*).
|
||||||
- `cmd` - Основные приложения проекта. Имя директории для каждого приложения
|
- `cmd` - Основные приложения проекта. Имя директории для каждого приложения
|
||||||
должно совпадать с именем исполняемого файла, который вы хотите собрать.
|
должно совпадать с именем исполняемого файла, который вы хотите собрать.
|
||||||
|
- `internal` - Внутренний код приложения и библиотек.
|
||||||
- `pkg` - Код библиотек, пригодных для использования в сторонних приложениях.
|
- `pkg` - Код библиотек, пригодных для использования в сторонних приложениях.
|
||||||
- `scripts` - Скрипты для сборки, установки, анализа и прочих операций над проектом.
|
- `scripts` - Скрипты для сборки, установки, анализа и прочих операций над проектом.
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"git.mousesoft.ru/ms/drawio-exporter/pkg/drawio"
|
"git.mousesoft.ru/ms/drawio-export/pkg/drawio"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -13,23 +13,44 @@ var (
|
|||||||
version string // Версия приложения
|
version string // Версия приложения
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type flags struct {
|
||||||
|
flagHelp bool // Вывести справку о приложении и выйти
|
||||||
|
flagVersion bool // Вывести информацию о версии приложения и выйти
|
||||||
|
flagIgnoreErrors bool // Игнорировать ошибки
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
var (
|
||||||
|
opts drawio.Options // Аргументы командной строки приложения
|
||||||
|
flags flags // Флаги командной строки
|
||||||
|
)
|
||||||
|
|
||||||
|
initFlags(&opts, &flags)
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
if flagHelp {
|
|
||||||
|
if flags.flagHelp {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
if flagVersion {
|
|
||||||
fmt.Println(appname, version)
|
if flags.flagVersion {
|
||||||
|
_, _ = fmt.Println(appname, version)
|
||||||
|
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
if flag.NArg() < 1 {
|
if flag.NArg() < 1 {
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
exporter := drawio.NewWithOptions(&opts)
|
exporter := drawio.NewWithOptions(&opts)
|
||||||
if err := exporter.Export(flag.Args()...); err != nil && !flagIgnoreErrors {
|
if err := exporter.Export(flag.Args()...); err != nil && !flags.flagIgnoreErrors {
|
||||||
fmt.Fprintln(os.Stderr, "Error:", err)
|
fmt.Fprintln(os.Stderr, "Error:", err)
|
||||||
|
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,23 +3,16 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
|
||||||
"git.mousesoft.ru/ms/drawio-exporter/pkg/drawio"
|
"git.mousesoft.ru/ms/drawio-export/pkg/drawio"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func initFlags(opts *drawio.Options, flags *flags) {
|
||||||
flagHelp bool // Вывести справку о приложении и выйти
|
// Version
|
||||||
flagVersion bool // Вывести информацию о версии приложения и выйти
|
flag.BoolVar(&flags.flagVersion, "V", false, "Prints version information")
|
||||||
flagIgnoreErrors bool // Игнорировать ошибки
|
flag.BoolVar(&flags.flagVersion, "version", false, "Prints version information")
|
||||||
opts = drawio.Options{} // Аргументы командной строки приложения
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// version
|
|
||||||
flag.BoolVar(&flagVersion, "V", false, "Prints version information")
|
|
||||||
flag.BoolVar(&flagVersion, "version", false, "Prints version information")
|
|
||||||
// Ignore Errors
|
// Ignore Errors
|
||||||
flag.BoolVar(&flagIgnoreErrors, "I", false, "Ignore Draw.IO errors")
|
flag.BoolVar(&flags.flagIgnoreErrors, "I", false, "Ignore Draw.IO errors")
|
||||||
flag.BoolVar(&flagIgnoreErrors, "ignore-errors", false, "Ignore Draw.IO errors")
|
flag.BoolVar(&flags.flagIgnoreErrors, "ignore-errors", false, "Ignore Draw.IO errors")
|
||||||
// Application
|
// Application
|
||||||
flag.StringVar(&opts.Application, "A", "", "Draw.io Desktop Application")
|
flag.StringVar(&opts.Application, "A", "", "Draw.io Desktop Application")
|
||||||
flag.StringVar(&opts.Application, "application", "", "Draw.io Desktop Application")
|
flag.StringVar(&opts.Application, "application", "", "Draw.io Desktop Application")
|
||||||
@ -76,7 +69,7 @@ func init() {
|
|||||||
flag.BoolVar(&opts.Uncompressed, "uncompressed", false, "Uncompressed XML output")
|
flag.BoolVar(&opts.Uncompressed, "uncompressed", false, "Uncompressed XML output")
|
||||||
// EnablePlugins
|
// EnablePlugins
|
||||||
flag.BoolVar(&opts.EnablePlugins, "enable-plugins", false, "Enable Plugins")
|
flag.BoolVar(&opts.EnablePlugins, "enable-plugins", false, "Enable Plugins")
|
||||||
// help
|
// Help
|
||||||
flag.BoolVar(&flagHelp, "h", false, "Prints help information")
|
flag.BoolVar(&flags.flagHelp, "h", false, "Prints help information")
|
||||||
flag.BoolVar(&flagHelp, "help", false, "Prints help information")
|
flag.BoolVar(&flags.flagHelp, "help", false, "Prints help information")
|
||||||
}
|
}
|
||||||
|
BIN
drawio-export
BIN
drawio-export
Binary file not shown.
4
go.mod
4
go.mod
@ -1,6 +1,6 @@
|
|||||||
module git.mousesoft.ru/ms/drawio-exporter
|
module git.mousesoft.ru/ms/drawio-export
|
||||||
|
|
||||||
go 1.20
|
go 1.22
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
19
makefile
19
makefile
@ -1,6 +1,8 @@
|
|||||||
# drawio-exporter makefile
|
# drawio-exporter makefile
|
||||||
# ========================
|
# ========================
|
||||||
|
|
||||||
|
SHELL := /usr/bin/env bash
|
||||||
|
|
||||||
PROJECT_ID := drawio-export
|
PROJECT_ID := drawio-export
|
||||||
PROJECT_NAME ?= MouseSoft Draw.IO Export
|
PROJECT_NAME ?= MouseSoft Draw.IO Export
|
||||||
BIN_SUFFIX :=
|
BIN_SUFFIX :=
|
||||||
@ -27,14 +29,13 @@ COVERAGE_FORMAT ?= html
|
|||||||
GOCMD := go
|
GOCMD := go
|
||||||
GOTEST := $(GOCMD) test
|
GOTEST := $(GOCMD) test
|
||||||
GOVET := $(GOCMD) vet
|
GOVET := $(GOCMD) vet
|
||||||
ECHO_CMD := echo
|
ECHO_CMD := echo -e
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
ifeq ($(OS),Windows_NT)
|
||||||
DIST_SUFFIX := windows-$(GOARCH)
|
DIST_SUFFIX := windows-$(GOARCH)
|
||||||
MSI_FILE ?= $(PROJECT_ID)_$(VERSION)_$(GOARCH).msi
|
MSI_FILE ?= $(PROJECT_ID)_$(VERSION)_$(GOARCH).msi
|
||||||
DIST_EXT := .zip
|
DIST_EXT := .zip
|
||||||
DIST_OPTS := -a -cf
|
DIST_OPTS := -a -cf
|
||||||
ECHO_CMD := echo -e
|
|
||||||
MSI_VERSION := $(shell echo $(VERSION_NUMBER) | sed -e 's/-.*//')
|
MSI_VERSION := $(shell echo $(VERSION_NUMBER) | sed -e 's/-.*//')
|
||||||
BIN_SUFFIX := .exe
|
BIN_SUFFIX := .exe
|
||||||
else
|
else
|
||||||
@ -193,14 +194,18 @@ endif
|
|||||||
|
|
||||||
## Lint
|
## Lint
|
||||||
|
|
||||||
lint: lint-go ## Run all available linters.
|
lint: ## Run all available linters.
|
||||||
|
go vet ./...
|
||||||
|
errcheck ./...
|
||||||
|
staticcheck ./...
|
||||||
|
usestdlibvars ./...
|
||||||
@$(ECHO_CMD) "Lint\t\t${GREEN}[OK]${RESET}"
|
@$(ECHO_CMD) "Lint\t\t${GREEN}[OK]${RESET}"
|
||||||
.PHONY:lint
|
.PHONY:lint
|
||||||
|
|
||||||
lint-go:
|
golangci-lint: ## Run golangci-lint linter
|
||||||
go fmt ./...
|
@golangci-lint run
|
||||||
go vet ./...
|
@$(ECHO_CMD) "GolangCI Lint\t${GREEN}[OK]${RESET}"
|
||||||
.PHONY:lint-go
|
.PHONY:golangci-lint
|
||||||
|
|
||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
|
@ -7,14 +7,13 @@ import (
|
|||||||
|
|
||||||
// Последовательный запуск команд в ОС
|
// Последовательный запуск команд в ОС
|
||||||
func RunSequence(command ...*exec.Cmd) error {
|
func RunSequence(command ...*exec.Cmd) error {
|
||||||
var (
|
var errs []error
|
||||||
errs = []error{}
|
|
||||||
err error
|
|
||||||
)
|
|
||||||
for _, cmd := range command {
|
for _, cmd := range command {
|
||||||
if err = cmd.Run(); err != nil {
|
if err := cmd.Run(); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.Join(errs...)
|
return errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
@ -24,12 +24,14 @@ func New(opt ...Option) Exporter {
|
|||||||
for _, opt := range opt {
|
for _, opt := range opt {
|
||||||
opt.apply(options)
|
opt.apply(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewWithOptions(options)
|
return NewWithOptions(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Создать нового экспортёра с параметрами
|
// Создать нового экспортёра с параметрами
|
||||||
func NewWithOptions(opts *Options) Exporter {
|
func NewWithOptions(opts *Options) Exporter {
|
||||||
exp := Exporter{opts: opts}
|
exp := Exporter{opts: opts}
|
||||||
|
|
||||||
if opts.openFile == nil {
|
if opts.openFile == nil {
|
||||||
exp.openFile = func(name string) (io.ReadCloser, error) {
|
exp.openFile = func(name string) (io.ReadCloser, error) {
|
||||||
return os.Open(name)
|
return os.Open(name)
|
||||||
@ -37,13 +39,13 @@ func NewWithOptions(opts *Options) Exporter {
|
|||||||
} else {
|
} else {
|
||||||
exp.openFile = opts.openFile
|
exp.openFile = opts.openFile
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.readDir == nil {
|
if opts.readDir == nil {
|
||||||
exp.readDir = func(name string) ([]os.DirEntry, error) {
|
exp.readDir = os.ReadDir
|
||||||
return os.ReadDir(name)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
exp.readDir = opts.readDir
|
exp.readDir = opts.readDir
|
||||||
}
|
}
|
||||||
|
|
||||||
return exp
|
return exp
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,30 +60,37 @@ type Exporter struct {
|
|||||||
func (exp Exporter) Export(fileOrDir ...string) error {
|
func (exp Exporter) Export(fileOrDir ...string) error {
|
||||||
var (
|
var (
|
||||||
commands = []*exec.Cmd{}
|
commands = []*exec.Cmd{}
|
||||||
err error
|
|
||||||
errs = []error{}
|
errs = []error{}
|
||||||
args = exp.opts.Args()
|
args = exp.opts.Args()
|
||||||
info fs.FileInfo
|
info fs.FileInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, item := range fileOrDir {
|
for _, item := range fileOrDir {
|
||||||
|
var err error
|
||||||
if info, err = os.Stat(item); err != nil {
|
if info, err = os.Stat(item); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var addCommands []*exec.Cmd
|
var addCommands []*exec.Cmd
|
||||||
if info.IsDir() {
|
if info.IsDir() {
|
||||||
addCommands, err = exp.ExportDir(item, args)
|
addCommands, err = exp.ExportDir(item, args)
|
||||||
} else {
|
} else {
|
||||||
addCommands, err = exp.ExportFile(item, args)
|
addCommands, err = exp.ExportFile(item, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
commands = append(commands, addCommands...)
|
commands = append(commands, addCommands...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err = RunSequence(commands...); err != nil {
|
|
||||||
|
if err := RunSequence(commands...); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.Join(errs...)
|
return errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,12 +104,16 @@ func (exp Exporter) ExportDir(
|
|||||||
entries []fs.DirEntry
|
entries []fs.DirEntry
|
||||||
errs []error
|
errs []error
|
||||||
)
|
)
|
||||||
|
|
||||||
if entries, err = exp.readDir(dirPath); err != nil {
|
if entries, err = exp.readDir(dirPath); err != nil {
|
||||||
return commands, err
|
return commands, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
name := entry.Name()
|
name := entry.Name()
|
||||||
|
|
||||||
var addCommands []*exec.Cmd
|
var addCommands []*exec.Cmd
|
||||||
|
|
||||||
if entry.IsDir() {
|
if entry.IsDir() {
|
||||||
if exp.opts.Recursive {
|
if exp.opts.Recursive {
|
||||||
deep := len(subDir)
|
deep := len(subDir)
|
||||||
@ -114,11 +127,14 @@ func (exp Exporter) ExportDir(
|
|||||||
} else {
|
} else {
|
||||||
addCommands, err = exp.ExportFile(path.Join(dirPath, name), args, subDir...)
|
addCommands, err = exp.ExportFile(path.Join(dirPath, name), args, subDir...)
|
||||||
}
|
}
|
||||||
|
|
||||||
commands = append(commands, addCommands...)
|
commands = append(commands, addCommands...)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return commands, errors.Join(errs...)
|
return commands, errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,43 +142,57 @@ func (exp Exporter) ExportDir(
|
|||||||
func (exp Exporter) ExportFile(
|
func (exp Exporter) ExportFile(
|
||||||
filePath string, args []string, subDir ...string,
|
filePath string, args []string, subDir ...string,
|
||||||
) ([]*exec.Cmd, error) {
|
) ([]*exec.Cmd, error) {
|
||||||
|
const AdditionalArgsNumber = 10
|
||||||
|
|
||||||
var (
|
var (
|
||||||
commands = []*exec.Cmd{}
|
commands = []*exec.Cmd{}
|
||||||
err error
|
err error
|
||||||
file io.ReadCloser
|
file io.ReadCloser
|
||||||
diagrams []string
|
diagrams []string
|
||||||
)
|
)
|
||||||
|
|
||||||
if file, err = exp.openFile(filePath); err != nil {
|
if file, err = exp.openFile(filePath); err != nil {
|
||||||
return commands, err
|
return commands, err
|
||||||
}
|
}
|
||||||
defer file.Close()
|
|
||||||
|
defer func() { _ = file.Close() }()
|
||||||
|
|
||||||
if diagrams, err = Diagrams(file); err != nil {
|
if diagrams, err = Diagrams(file); err != nil {
|
||||||
return commands, err
|
return commands, err
|
||||||
}
|
}
|
||||||
|
|
||||||
outDirs := make([]string, 1, len(subDir)+1)
|
outDirs := make([]string, 1, len(subDir)+1)
|
||||||
outDirs[0] = exp.opts.OutDir()
|
outDirs[0] = exp.opts.OutDir()
|
||||||
outDirs = append(outDirs, subDir...)
|
outDirs = append(outDirs, subDir...)
|
||||||
output := path.Join(outDirs...)
|
output := path.Join(outDirs...)
|
||||||
for i, name := range diagrams {
|
|
||||||
|
for index, name := range diagrams {
|
||||||
outName := strings.TrimSuffix(path.Base(filePath), path.Ext(filePath))
|
outName := strings.TrimSuffix(path.Base(filePath), path.Ext(filePath))
|
||||||
|
|
||||||
if !exp.opts.RemovePageSuffix || len(diagrams) > 1 {
|
if !exp.opts.RemovePageSuffix || len(diagrams) > 1 {
|
||||||
outName += "-" + name
|
outName += "-" + name
|
||||||
}
|
}
|
||||||
|
|
||||||
outName += exp.opts.OutExt()
|
outName += exp.opts.OutExt()
|
||||||
drawioArgs := make([]string, len(args), len(args)+10)
|
drawioArgs := make([]string, len(args), len(args)+AdditionalArgsNumber)
|
||||||
|
|
||||||
copy(drawioArgs, args)
|
copy(drawioArgs, args)
|
||||||
|
|
||||||
drawioArgs = append(drawioArgs,
|
drawioArgs = append(drawioArgs,
|
||||||
"--page-index", strconv.Itoa(i),
|
"--page-index", strconv.Itoa(index),
|
||||||
"--output", path.Join(output, outName),
|
"--output", path.Join(output, outName),
|
||||||
"--export", filePath,
|
"--export", filePath,
|
||||||
)
|
)
|
||||||
|
|
||||||
if exp.opts.EnableXvfb {
|
if exp.opts.EnableXvfb {
|
||||||
drawioArgs = append(drawioArgs,
|
drawioArgs = append(drawioArgs,
|
||||||
"--disable-gpu", "--headless", "--no-sandbox")
|
"--disable-gpu", "--headless", "--no-sandbox")
|
||||||
}
|
}
|
||||||
cmd := exec.Command(exp.opts.App(), drawioArgs...)
|
|
||||||
|
cmd := exec.Command(exp.opts.App(), drawioArgs...) //nolint:gosec
|
||||||
commands = append(commands, cmd)
|
commands = append(commands, cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
return commands, err
|
return commands, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,15 +205,18 @@ func Diagrams(reader io.Reader) ([]string, error) {
|
|||||||
br, "mxfile", "diagram",
|
br, "mxfile", "diagram",
|
||||||
).ParseAttributesOnly("diagram")
|
).ParseAttributesOnly("diagram")
|
||||||
)
|
)
|
||||||
|
|
||||||
for xml := range parser.Stream() {
|
for xml := range parser.Stream() {
|
||||||
if xml.Err != nil {
|
if xml.Err != nil {
|
||||||
return result, xml.Err
|
return result, xml.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
if items, ok := xml.Childs["diagram"]; ok {
|
if items, ok := xml.Childs["diagram"]; ok {
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
result = append(result, item.Attrs["name"])
|
result = append(result, item.Attrs["name"])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.mousesoft.ru/ms/drawio-exporter/pkg/drawio"
|
"git.mousesoft.ru/ms/drawio-export/pkg/drawio"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ func TestExportFile(t *testing.T) {
|
|||||||
for _, test := range testData {
|
for _, test := range testData {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
for filePath, source := range test.files {
|
for filePath, source := range test.files {
|
||||||
var openOpt = drawio.WithNop()
|
var openOpt drawio.Option = drawio.WithNop()
|
||||||
if len(source.output) > 0 {
|
if len(source.output) > 0 {
|
||||||
openOpt = drawio.WithOutput(source.output)
|
openOpt = drawio.WithOutput(source.output)
|
||||||
}
|
}
|
||||||
|
@ -14,25 +14,25 @@ type Option interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ошибка "неподдерживаемый формат"
|
// Ошибка "неподдерживаемый формат"
|
||||||
type ErrUnsupportedFormat struct {
|
type UnsupportedFormatError struct {
|
||||||
Format string
|
Format string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Описание ошибки
|
// Описание ошибки
|
||||||
func (e ErrUnsupportedFormat) Error() string {
|
func (e UnsupportedFormatError) Error() string {
|
||||||
return fmt.Sprintf("unsupported format: '%s'", e.Format)
|
return fmt.Sprintf("unsupported format: '%s'", e.Format)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Проверка эквивалентности ошибок
|
// Проверка эквивалентности ошибок
|
||||||
func (e ErrUnsupportedFormat) Is(target error) bool {
|
func (e UnsupportedFormatError) Is(target error) bool {
|
||||||
switch t := target.(type) {
|
if t, ok := target.(UnsupportedFormatError); ok {
|
||||||
case ErrUnsupportedFormat:
|
|
||||||
return t.Format == e.Format
|
return t.Format == e.Format
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ error = (*ErrUnsupportedFormat)(nil) // Проверка реализации интерфейса
|
var _ error = (*UnsupportedFormatError)(nil) // Проверка реализации интерфейса
|
||||||
|
|
||||||
type Format string // Формат экспортированного файла
|
type Format string // Формат экспортированного файла
|
||||||
|
|
||||||
@ -55,10 +55,12 @@ func (f *Format) Set(str string) error {
|
|||||||
for _, fmt := range SupportedFormats() {
|
for _, fmt := range SupportedFormats() {
|
||||||
if str == string(fmt) {
|
if str == string(fmt) {
|
||||||
*f = Format(str)
|
*f = Format(str)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &ErrUnsupportedFormat{str}
|
|
||||||
|
return &UnsupportedFormatError{str}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Список всех поддерживаемых форматов экспорта
|
// Список всех поддерживаемых форматов экспорта
|
||||||
@ -108,9 +110,11 @@ func (opts Options) App() string {
|
|||||||
if opts.EnableXvfb {
|
if opts.EnableXvfb {
|
||||||
return "xvfb-run"
|
return "xvfb-run"
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.Application) == 0 {
|
if len(opts.Application) == 0 {
|
||||||
return "drawio"
|
return "drawio"
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts.Application
|
return opts.Application
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,6 +124,7 @@ func (opts Options) OutDir() string {
|
|||||||
if len(out) == 0 {
|
if len(out) == 0 {
|
||||||
out = "export"
|
out = "export"
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,12 +134,14 @@ func (opts Options) OutExt() string {
|
|||||||
if len(fmt) == 0 {
|
if len(fmt) == 0 {
|
||||||
fmt = Format("pdf")
|
fmt = Format("pdf")
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.ext()
|
return fmt.ext()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Аргументы командной строки drawio
|
// Аргументы командной строки drawio
|
||||||
func (opts Options) Args() []string {
|
func (opts Options) Args() []string {
|
||||||
args := []string{}
|
args := []string{}
|
||||||
|
|
||||||
if opts.EnableXvfb {
|
if opts.EnableXvfb {
|
||||||
var app string
|
var app string
|
||||||
if len(opts.Application) == 0 {
|
if len(opts.Application) == 0 {
|
||||||
@ -142,49 +149,63 @@ func (opts Options) Args() []string {
|
|||||||
} else {
|
} else {
|
||||||
app = opts.Application
|
app = opts.Application
|
||||||
}
|
}
|
||||||
|
|
||||||
args = append(args, "-a", "-l", app)
|
args = append(args, "-a", "-l", app)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(opts.Format) > 0 {
|
if len(opts.Format) > 0 {
|
||||||
args = append(args, "--format", string(opts.Format))
|
args = append(args, "--format", string(opts.Format))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Quality != 0 {
|
if opts.Quality != 0 {
|
||||||
args = append(args, "--quality", strconv.Itoa(int(opts.Quality)))
|
args = append(args, "--quality", strconv.Itoa(int(opts.Quality)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Transparent {
|
if opts.Transparent {
|
||||||
args = append(args, "--transparent")
|
args = append(args, "--transparent")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.EmbedDiagram {
|
if opts.EmbedDiagram {
|
||||||
args = append(args, "--embed-diagram")
|
args = append(args, "--embed-diagram")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.EmbedSvgImages {
|
if opts.EmbedSvgImages {
|
||||||
args = append(args, "--embed-svg-images")
|
args = append(args, "--embed-svg-images")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Border != 0 {
|
if opts.Border != 0 {
|
||||||
args = append(args, "--border", strconv.Itoa(int(opts.Border)))
|
args = append(args, "--border", strconv.Itoa(int(opts.Border)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Scale != 0 {
|
if opts.Scale != 0 {
|
||||||
args = append(args, "--scale", strconv.Itoa(int(opts.Scale)))
|
args = append(args, "--scale", strconv.Itoa(int(opts.Scale)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Width != 0 {
|
if opts.Width != 0 {
|
||||||
args = append(args, "--width", strconv.Itoa(int(opts.Width)))
|
args = append(args, "--width", strconv.Itoa(int(opts.Width)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Height != 0 {
|
if opts.Height != 0 {
|
||||||
args = append(args, "--height", strconv.Itoa(int(opts.Height)))
|
args = append(args, "--height", strconv.Itoa(int(opts.Height)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Crop {
|
if opts.Crop {
|
||||||
args = append(args, "--crop")
|
args = append(args, "--crop")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.Uncompressed {
|
if opts.Uncompressed {
|
||||||
args = append(args, "--uncompressed")
|
args = append(args, "--uncompressed")
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts.EnablePlugins {
|
if opts.EnablePlugins {
|
||||||
args = append(args, "--enable-plugins")
|
args = append(args, "--enable-plugins")
|
||||||
}
|
}
|
||||||
|
|
||||||
return args
|
return args
|
||||||
}
|
}
|
||||||
|
|
||||||
// Путь к приложению drawio
|
// Путь к приложению drawio
|
||||||
func WithAppPath(path string) Option {
|
func WithAppPath(path string) optionApplication {
|
||||||
return optionApplication(path)
|
return optionApplication(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +218,7 @@ func (opt optionApplication) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Запускать drawio внутри xvfb-run
|
// Запускать drawio внутри xvfb-run
|
||||||
func WithXvfb() Option {
|
func WithXvfb() optionXvfb {
|
||||||
return optionXvfb{}
|
return optionXvfb{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +231,7 @@ func (opt optionXvfb) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Путь к папке с экспортированными файлами
|
// Путь к папке с экспортированными файлами
|
||||||
func WithOutput(path string) Option {
|
func WithOutput(path string) optionOutput {
|
||||||
return optionOutput(path)
|
return optionOutput(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,18 +244,18 @@ func (opt optionOutput) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Формат экспортированных файлов
|
// Формат экспортированных файлов
|
||||||
func WithFormat(format Format) Option {
|
func WithFormat(format Format) Format {
|
||||||
return format
|
return format
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Option = (*Format)(nil) // Проверка реализации интерфейса
|
var _ Option = (*Format)(nil) // Проверка реализации интерфейса
|
||||||
|
|
||||||
func (opt Format) apply(opts *Options) {
|
func (f Format) apply(opts *Options) {
|
||||||
opts.Format = opt
|
opts.Format = f
|
||||||
}
|
}
|
||||||
|
|
||||||
// Рекурсивно сканировать вложенные папки с файлами
|
// Рекурсивно сканировать вложенные папки с файлами
|
||||||
func WithRecursive() Option {
|
func WithRecursive() optionRecursive {
|
||||||
return optionRecursive{}
|
return optionRecursive{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +268,7 @@ func (opt optionRecursive) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Удалять суффикс страницы, если это возможно
|
// Удалять суффикс страницы, если это возможно
|
||||||
func WithRemovePageSuffix() Option {
|
func WithRemovePageSuffix() optionRemovePageSuffix {
|
||||||
return optionRemovePageSuffix{}
|
return optionRemovePageSuffix{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -260,7 +281,7 @@ func (opt optionRemovePageSuffix) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Качество экспортированного изображения (только для JPEG)
|
// Качество экспортированного изображения (только для JPEG)
|
||||||
func WithQuality(q uint) Option {
|
func WithQuality(q uint) optionQuality {
|
||||||
return optionQuality(q)
|
return optionQuality(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +294,7 @@ func (opt optionQuality) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Прозрачный фона для PNG
|
// Прозрачный фона для PNG
|
||||||
func WithTransparent() Option {
|
func WithTransparent() optionTransparent {
|
||||||
return optionTransparent{}
|
return optionTransparent{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,7 +307,7 @@ func (opt optionTransparent) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Включать копию диаграммы в экспортированный файл для PDF, PNG и SVG
|
// Включать копию диаграммы в экспортированный файл для PDF, PNG и SVG
|
||||||
func WithEmbedDiagram() Option {
|
func WithEmbedDiagram() optionEmbedDiagram {
|
||||||
return optionEmbedDiagram{}
|
return optionEmbedDiagram{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +320,7 @@ func (opt optionEmbedDiagram) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Встраивать изображения в файл формата SVG
|
// Встраивать изображения в файл формата SVG
|
||||||
func WithEmbedSvgImages() Option {
|
func WithEmbedSvgImages() optionEmbedSvgImages {
|
||||||
return optionEmbedSvgImages{}
|
return optionEmbedSvgImages{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +333,7 @@ func (opt optionEmbedSvgImages) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ширина рамки вокруг диаграмм
|
// Ширина рамки вокруг диаграмм
|
||||||
func WithBorder(border uint) Option {
|
func WithBorder(border uint) optionBorder {
|
||||||
return optionBorder(border)
|
return optionBorder(border)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +346,7 @@ func (opt optionBorder) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Масштаб в процентах размера экспортированных диаграмм
|
// Масштаб в процентах размера экспортированных диаграмм
|
||||||
func WithScale(scale uint) Option {
|
func WithScale(scale uint) optionScale {
|
||||||
return optionScale(scale)
|
return optionScale(scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,7 +359,7 @@ func (opt optionScale) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ширина экспортированной диаграммы с сохранением масштаба
|
// Ширина экспортированной диаграммы с сохранением масштаба
|
||||||
func WithWidth(width uint) Option {
|
func WithWidth(width uint) optionWidth {
|
||||||
return optionWidth(width)
|
return optionWidth(width)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,7 +372,7 @@ func (opt optionWidth) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Высота экспортированной диаграммы с сохранением масштаба
|
// Высота экспортированной диаграммы с сохранением масштаба
|
||||||
func WithHeight(height uint) Option {
|
func WithHeight(height uint) optionHeight {
|
||||||
return optionHeight(height)
|
return optionHeight(height)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +385,7 @@ func (opt optionHeight) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Обрезать результирующий PDF до размера диаграммы
|
// Обрезать результирующий PDF до размера диаграммы
|
||||||
func WithCrop() Option {
|
func WithCrop() optionCrop {
|
||||||
return optionCrop{}
|
return optionCrop{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,7 +398,7 @@ func (opt optionCrop) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Выводить несжатый XML
|
// Выводить несжатый XML
|
||||||
func WithUncompressed() Option {
|
func WithUncompressed() optionUncompressed {
|
||||||
return optionUncompressed{}
|
return optionUncompressed{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +411,7 @@ func (opt optionUncompressed) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Включить подключаемые модули
|
// Включить подключаемые модули
|
||||||
func WithEnablePlugins() Option {
|
func WithEnablePlugins() optionEnablePlugins {
|
||||||
return optionEnablePlugins{}
|
return optionEnablePlugins{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +424,7 @@ func (opt optionEnablePlugins) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Открыть файл
|
// Открыть файл
|
||||||
func WithOpenFile(openFile OpenFileFunc) Option {
|
func WithOpenFile(openFile OpenFileFunc) optionOpenFile {
|
||||||
return optionOpenFile{openFile}
|
return optionOpenFile{openFile}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,7 +439,7 @@ func (opt optionOpenFile) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Прочитать папку на диске
|
// Прочитать папку на диске
|
||||||
func WithReadDir(readDir ReadDirFunc) Option {
|
func WithReadDir(readDir ReadDirFunc) optionReadDir {
|
||||||
return optionReadDir{readDir}
|
return optionReadDir{readDir}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,7 +454,7 @@ func (opt optionReadDir) apply(opts *Options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Пустой параметр
|
// Пустой параметр
|
||||||
func WithNop() Option {
|
func WithNop() optionNop {
|
||||||
return optionNop{}
|
return optionNop{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,6 +462,6 @@ type optionNop struct{}
|
|||||||
|
|
||||||
var _ Option = optionNop{}
|
var _ Option = optionNop{}
|
||||||
|
|
||||||
func (opt optionNop) apply(opts *Options) {
|
func (opt optionNop) apply(_ *Options) {
|
||||||
// Не требуется действий, так как это пустой параметр
|
// Не требуется действий, так как это пустой параметр
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package drawio_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"git.mousesoft.ru/ms/drawio-exporter/pkg/drawio"
|
"git.mousesoft.ru/ms/drawio-export/pkg/drawio"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ func TestFormat(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "svvg",
|
name: "svvg",
|
||||||
err: drawio.ErrUnsupportedFormat{"svvg"},
|
err: drawio.UnsupportedFormatError{"svvg"},
|
||||||
format: drawio.Format(""),
|
format: drawio.Format(""),
|
||||||
ext: "",
|
ext: "",
|
||||||
},
|
},
|
||||||
|
108
report.xml
Normal file
108
report.xml
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<checkstyle version="5.0">
|
||||||
|
<file name="cmd/drawio-export/main.go">
|
||||||
|
<error column="2" line="8" message="import 'git.mousesoft.ru/ms/drawio-exporter/pkg/drawio' is not allowed from list 'Main'" severity="error" source="depguard"></error>
|
||||||
|
<error column="3" line="23" message="use of `fmt.Println` forbidden by pattern `^(fmt\.Print(|f|ln)|print|println)$`" severity="error" source="forbidigo"></error>
|
||||||
|
<error column="2" line="12" message="appname is a global variable" severity="error" source="gochecknoglobals"></error>
|
||||||
|
</file>
|
||||||
|
<file name="cmd/drawio-export/options.go">
|
||||||
|
<error column="2" line="6" message="import 'git.mousesoft.ru/ms/drawio-exporter/pkg/drawio' is not allowed from list 'Main'" severity="error" source="depguard"></error>
|
||||||
|
<error column="21" line="13" message="drawio.Options is missing fields Application, EnableXvfb, Output, Format, Recursive, RemovePageSuffix, Quality, Transparent, EmbedDiagram, EmbedSvgImages, Border, Scale, Width, Height, Crop, Uncompressed, EnablePlugins" severity="error" source="exhaustruct"></error>
|
||||||
|
<error column="0" line="16" message="Function 'init' is too long (65 > 60)" severity="error" source="funlen"></error>
|
||||||
|
<error column="2" line="10" message="flagHelp is a global variable" severity="error" source="gochecknoglobals"></error>
|
||||||
|
<error column="2" line="11" message="flagVersion is a global variable" severity="error" source="gochecknoglobals"></error>
|
||||||
|
<error column="2" line="12" message="flagIgnoreErrors is a global variable" severity="error" source="gochecknoglobals"></error>
|
||||||
|
<error column="2" line="13" message="opts is a global variable" severity="error" source="gochecknoglobals"></error>
|
||||||
|
<error column="1" line="16" message="don't use `init` function" severity="error" source="gochecknoinits"></error>
|
||||||
|
<error column="41" line="18" message="string `Prints version information` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="46" line="21" message="string `Ignore Draw.IO errors` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="45" line="24" message="string `Draw.io Desktop Application` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="45" line="27" message="string `Run drawio inside xvfb-run` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="40" line="30" message="string `Exported folder name [default: export]` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="3" line="34" message="string `Exported format [default: pdf] [possible values: pdf, png, jpg, svg, vsdx, xml]` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="3" line="39" message="string `For a folder input, recursively convert all files in sub-folders also` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="38" line="46" message="string `Output image quality for JPEG [default: 90]` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="46" line="49" message="string `Set transparent background for PNG` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="3" line="53" message="string `Includes a copy of the diagram for PDF, PNG, or SVG` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="3" line="60" message="string `Sets the border width around the diagram [default: 0]` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="36" line="64" message="string `Scales the diagram size` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="47" line="75" message="string `Uncompressed XML output` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="38" line="80" message="string `Prints help information` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
</file>
|
||||||
|
<file name="pkg/drawio/execution.go">
|
||||||
|
<error column="0" line="1" message="Missed header for check" severity="error" source="goheader"></error>
|
||||||
|
<error column="2" line="19" message="return with no blank line before" severity="error" source="nlreturn"></error>
|
||||||
|
<error column="2" line="14" message="ranges should only be cuddled with assignments used in the iteration" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="19" message="return statements should not be cuddled if block has more than two lines" severity="error" source="wsl"></error>
|
||||||
|
</file>
|
||||||
|
<file name="pkg/drawio/export.go">
|
||||||
|
<error column="2" line="14" message="import 'github.com/tamerh/xml-stream-parser' is not allowed from list 'Main'" severity="error" source="depguard"></error>
|
||||||
|
<error column="14" line="19" message="drawio.Options is missing fields EnableXvfb, Recursive, RemovePageSuffix, Quality, Transparent, EmbedDiagram, EmbedSvgImages, Border, Scale, Width, Height, Crop, Uncompressed, EnablePlugins, openFile, readDir" severity="error" source="exhaustruct"></error>
|
||||||
|
<error column="9" line="32" message="drawio.Exporter is missing fields openFile, readDir" severity="error" source="exhaustruct"></error>
|
||||||
|
<error column="23" line="22" message="string `pdf` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="25" line="176" message="string `diagram` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="17" line="41" message="unlambda: replace `func(name string) ([]os.DirEntry, error) {
	return os.ReadDir(name)
}` with `os.ReadDir`" severity="error" source="gocritic"></error>
|
||||||
|
<error column="0" line="1" message="Missed header for check" severity="error" source="goheader"></error>
|
||||||
|
<error column="53" line="152" message="Magic number: 10, in <argument> detected" severity="error" source="mnd"></error>
|
||||||
|
<error column="2" line="27" message="return with no blank line before" severity="error" source="nlreturn"></error>
|
||||||
|
<error column="2" line="47" message="return with no blank line before" severity="error" source="nlreturn"></error>
|
||||||
|
<error column="4" line="69" message="continue with no blank line before" severity="error" source="nlreturn"></error>
|
||||||
|
<error column="6" line="146" message="variable name 'i' is too short for the scope of its usage" severity="error" source="varnamelen"></error>
|
||||||
|
<error column="2" line="66" message="ranges should only be cuddled with assignments used in the iteration" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="71" message="declarations should never be cuddled" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="72" message="only one cuddle assignment allowed before if statement" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="77" message="append only allowed to cuddle with appended value" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="78" message="only one cuddle assignment allowed before if statement" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="82" message="if statements should only be cuddled with assignments" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="85" message="return statements should not be cuddled if block has more than two lines" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="101" message="only one cuddle assignment allowed before range statement" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="103" message="declarations should never be cuddled" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="104" message="only one cuddle assignment allowed before if statement" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="117" message="append only allowed to cuddle with appended value" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="138" message="only one cuddle assignment allowed before defer statement" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="139" message="if statements should only be cuddled with assignments" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="142" message="assignments should only be cuddled with other assignments" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="146" message="only one cuddle assignment allowed before range statement" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="151" message="assignments should only be cuddled with other assignments" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="163" message="assignments should only be cuddled with other assignments" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="166" message="return statements should not be cuddled if block has more than two lines" severity="error" source="wsl"></error>
|
||||||
|
<error column="2" line="178" message="ranges should only be cuddled with assignments used in the iteration" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="182" message="if statements should only be cuddled with assignments" severity="error" source="wsl"></error>
|
||||||
|
</file>
|
||||||
|
<file name="pkg/drawio/options.go">
|
||||||
|
<error column="1" line="136" message="calculated cyclomatic complexity for function Args is 15, max is 10" severity="error" source="cyclop"></error>
|
||||||
|
<error column="6" line="17" message="the type name `ErrUnsupportedFormat` should conform to the `XxxError` format" severity="error" source="errname"></error>
|
||||||
|
<error column="16" line="414" message="drawio.optionOpenFile is missing field openFile" severity="error" source="exhaustruct"></error>
|
||||||
|
<error column="16" line="429" message="drawio.optionReadDir is missing field readDir" severity="error" source="exhaustruct"></error>
|
||||||
|
<error column="10" line="112" message="string `drawio` has 2 occurrences, make it a constant" severity="error" source="goconst"></error>
|
||||||
|
<error column="2" line="28" message="singleCaseSwitch: should rewrite switch statement to if statement" severity="error" source="gocritic"></error>
|
||||||
|
<error column="0" line="1" message="Missed header for check" severity="error" source="goheader"></error>
|
||||||
|
<error column="14" line="77" message="fieldalignment: struct of size 136 could be 120" severity="error" source="govet"></error>
|
||||||
|
<error column="1" line="187" message="WithAppPath returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="200" message="WithXvfb returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="213" message="WithOutput returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="226" message="WithFormat returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="237" message="WithRecursive returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="250" message="WithRemovePageSuffix returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="263" message="WithQuality returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="276" message="WithTransparent returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="289" message="WithEmbedDiagram returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="302" message="WithEmbedSvgImages returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="315" message="WithBorder returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="328" message="WithScale returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="341" message="WithWidth returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="354" message="WithHeight returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="367" message="WithCrop returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="380" message="WithUncompressed returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="393" message="WithEnablePlugins returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="406" message="WithOpenFile returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="421" message="WithReadDir returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="436" message="WithNop returns interface (git.mousesoft.ru/ms/drawio-exporter/pkg/drawio.Option)" severity="error" source="ireturn"></error>
|
||||||
|
<error column="1" line="232" message="receiver-naming: receiver name opt should be consistent with previous receiver name f for Format" severity="warning" source="revive"></error>
|
||||||
|
<error column="28" line="444" message="unused-parameter: parameter 'opts' seems to be unused, consider removing or renaming it as _" severity="warning" source="revive"></error>
|
||||||
|
<error column="18" line="54" message="ST1016: methods on the same type should have the same receiver name (seen 1x "opt", 3x "f")" severity="error" source="stylecheck"></error>
|
||||||
|
<error column="2" line="138" message="if statements should only be cuddled with assignments used in the if statement itself" severity="error" source="wsl"></error>
|
||||||
|
<error column="3" line="145" message="append only allowed to cuddle with appended value" severity="error" source="wsl"></error>
|
||||||
|
</file>
|
||||||
|
</checkstyle>
|
Loading…
Reference in New Issue
Block a user