Cleaning things up to turn this into a proper parser
parent
0b2443c720
commit
c3b5d8e663
@ -0,0 +1,4 @@
|
|||||||
|
node_modules/*
|
||||||
|
package*.json
|
||||||
|
dist/*
|
||||||
|
reports/*
|
@ -0,0 +1,217 @@
|
|||||||
|
# This file is intended as a starting point for a customized makefile for a Go project.
|
||||||
|
#
|
||||||
|
# Targets:
|
||||||
|
# all: Format, check, build, and test the code
|
||||||
|
# setup: Install build/test toolchain dependencies (e.g. gox)
|
||||||
|
# lint: Run linters against source code
|
||||||
|
# bump-{major,minor,patch}: create a new semver git tag
|
||||||
|
# release-{major,minor,patch}: push a tagged release
|
||||||
|
# format: Format the source files
|
||||||
|
# build: Build the command(s) for target OS/arch combinations
|
||||||
|
# install: Install the command(s)
|
||||||
|
# clean: Clean the build/test artifacts
|
||||||
|
# report: Generate build/test reports
|
||||||
|
# check: Run tests
|
||||||
|
# bench: Run benchmarks
|
||||||
|
# dist: zip/tar binaries & documentation
|
||||||
|
# debug: print parameters
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
# VERSION: release version in semver format
|
||||||
|
# BUILD_TAGS: additional build tags to pass to go build
|
||||||
|
# DISTDIR: path to save distribution files
|
||||||
|
# RPTDIR: path to save build/test reports
|
||||||
|
#
|
||||||
|
# Assumptions:
|
||||||
|
# - Your package contains a cmd/ package, containing a directory for each produced binary.
|
||||||
|
# - You have cloc installed and accessible in the PATH.
|
||||||
|
# - Your GOPATH and GOROOT are set correctly.
|
||||||
|
# - Your makefile is in the root of your package and does not have a space in its file name.
|
||||||
|
# - Your root package contains global string variables Version and Build, to receive the bild version number and commit ID, respectively.
|
||||||
|
#
|
||||||
|
# Features:
|
||||||
|
# - report generates files that can be consumed by Jenkins, as well as a list of external dependencies.
|
||||||
|
# - setup installs all the tools aside from cloc.
|
||||||
|
# - Works on Windows and with paths containing spaces.
|
||||||
|
# - Works when executing from outside the makefile directory using -f.
|
||||||
|
# - Targets are useful both in CI and developer workstations.
|
||||||
|
# - Handles cross-compiation for multiple OSes and architectures.
|
||||||
|
# - Bundles binaries and documentation into compressed archives, using tar/gz for Linux and Darwin, and zip for Windows.
|
||||||
|
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
PKG = code.ndumas.com/ndumas/wikilink-parser
|
||||||
|
NAME = parse-wikilinks
|
||||||
|
DOC = README.md LICENSE
|
||||||
|
|
||||||
|
|
||||||
|
# Replace backslashes with forward slashes for use on Windows.
|
||||||
|
# Make is !@#$ing weird.
|
||||||
|
E :=
|
||||||
|
BSLASH := \$E
|
||||||
|
FSLASH := /
|
||||||
|
|
||||||
|
# Directories
|
||||||
|
WD := $(subst $(BSLASH),$(FSLASH),$(shell pwd))
|
||||||
|
MD := $(subst $(BSLASH),$(FSLASH),$(shell dirname "$(realpath $(lastword $(MAKEFILE_LIST)))"))
|
||||||
|
PKGDIR = $(MD)
|
||||||
|
CMDDIR = $(PKGDIR)/cmd
|
||||||
|
DISTDIR ?= $(WD)/dist
|
||||||
|
RPTDIR ?= $(WD)/reports
|
||||||
|
GP = $(subst $(BSLASH),$(FSLASH),$(GOPATH))
|
||||||
|
|
||||||
|
# Parameters
|
||||||
|
VERSION ?= $(shell git -C "$(MD)" describe --tags --dirty=-dev)
|
||||||
|
COMMIT_ID := $(shell git -C "$(MD)" rev-parse HEAD | head -c8)
|
||||||
|
BUILD_TAGS ?= release
|
||||||
|
CMDPKG = $(PKG)/cmd
|
||||||
|
CMDS := $(shell find "$(CMDDIR)/" -mindepth 1 -maxdepth 1 -type d | sed 's/ /\\ /g' | xargs -n1 basename)
|
||||||
|
BENCHCPUS ?= 1,2,4
|
||||||
|
|
||||||
|
# Commands
|
||||||
|
GOCMD = go
|
||||||
|
ARCHES ?= amd64 386
|
||||||
|
OSES ?= windows linux darwin
|
||||||
|
OUTTPL = $(DISTDIR)/$(NAME)-$(VERSION)-{{.OS}}_{{.Arch}}/{{.Dir}}
|
||||||
|
LDFLAGS = -X $(PKG).Version=$(VERSION) -X $(PKG).Build=$(COMMIT_ID)
|
||||||
|
GOBUILD = gox -osarch="!darwin/386" -rebuild -gocmd="$(GOCMD)" -arch="$(ARCHES)" -os="$(OSES)" -output="$(OUTTPL)" -tags "$(BUILD_TAGS)" -ldflags "$(LDFLAGS)"
|
||||||
|
GOCLEAN = $(GOCMD) clean
|
||||||
|
GOINSTALL = $(GOCMD) install -a -tags "$(BUILD_TAGS)" -ldflags "$(LDFLAGS)"
|
||||||
|
GOTEST = $(GOCMD) test -v -tags "$(BUILD_TAGS)"
|
||||||
|
DISABLED_LINTERS = varnamelen,interfacer,ifshort,exhaustivestruct,maligned,varcheck,scopelint,structcheck,deadcode,nosnakecase,golint,depguard
|
||||||
|
GOLINT = golangci-lint run --enable-all --disable "$(DISABLED_LINTERS)" --timeout=30s --tests
|
||||||
|
GODEP = $(GOCMD) get -d -t
|
||||||
|
GOFMT = goreturns -w
|
||||||
|
GOBENCH = $(GOCMD) test -v -tags "$(BUILD_TAGS)" -cpu=$(BENCHCPUS) -run=NOTHING -bench=. -benchmem -outputdir "$(RPTDIR)"
|
||||||
|
GZCMD = tar -czf
|
||||||
|
ZIPCMD = zip
|
||||||
|
SHACMD = sha256sum
|
||||||
|
SLOCCMD = cloc --by-file --xml --exclude-dir="vendor" --include-lang="Go"
|
||||||
|
XUCMD = go2xunit
|
||||||
|
DOCKER_CMD=docker --config ~/.docker/
|
||||||
|
|
||||||
|
# Dynamic Targets
|
||||||
|
INSTALL_TARGETS := $(addprefix install-,$(CMDS))
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
|
||||||
|
all: debug setup dep format lint test bench build dist
|
||||||
|
|
||||||
|
git-push:
|
||||||
|
git push origin main --tags
|
||||||
|
git push github main --tags
|
||||||
|
|
||||||
|
release-major: bump-major git-push
|
||||||
|
|
||||||
|
release-minor: bump-minor git-push
|
||||||
|
|
||||||
|
release-patch: bump-patch git-push
|
||||||
|
|
||||||
|
|
||||||
|
setup: setup-dirs setup-build setup-format setup-lint setup-reports setup-bump
|
||||||
|
|
||||||
|
setup-bump:
|
||||||
|
go install github.com/guilhem/bump@latest
|
||||||
|
|
||||||
|
bump-major: setup-bump
|
||||||
|
bump major
|
||||||
|
|
||||||
|
bump-minor: setup-bump
|
||||||
|
bump minor
|
||||||
|
|
||||||
|
bump-patch: setup-bump
|
||||||
|
bump patch
|
||||||
|
|
||||||
|
setup-reports: setup-dirs
|
||||||
|
go install github.com/tebeka/go2xunit@latest
|
||||||
|
|
||||||
|
setup-build: setup-dirs
|
||||||
|
go install github.com/mitchellh/gox@latest
|
||||||
|
|
||||||
|
setup-format: setup-dirs
|
||||||
|
go install github.com/sqs/goreturns@latest
|
||||||
|
|
||||||
|
setup-lint: setup-dirs
|
||||||
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.53.1
|
||||||
|
|
||||||
|
setup-dirs:
|
||||||
|
mkdir -p "$(RPTDIR)"
|
||||||
|
mkdir -p "$(DISTDIR)"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(GOCLEAN) $(PKG)
|
||||||
|
rm -vrf "$(DISTDIR)"/*
|
||||||
|
rm -vf "$(RPTDIR)"/*
|
||||||
|
|
||||||
|
format:
|
||||||
|
$(GOFMT) "$(PKGDIR)"
|
||||||
|
|
||||||
|
dep:
|
||||||
|
$(GODEP) $(PKG)/...
|
||||||
|
|
||||||
|
lint: setup-dirs dep
|
||||||
|
$(GOLINT) "$(PKGDIR)" | tee "$(RPTDIR)/lint.out"
|
||||||
|
|
||||||
|
check: setup-dirs clean dep
|
||||||
|
$(GOTEST) $$(go list "$(PKG)/..." | grep -v /vendor/) | tee "$(RPTDIR)/test.out"
|
||||||
|
|
||||||
|
bench: setup-dirs clean dep
|
||||||
|
$(GOBENCH) $$(go list "$(PKG)/..." | grep -v /vendor/) | tee "$(RPTDIR)/bench.out"
|
||||||
|
|
||||||
|
report: check
|
||||||
|
cd "$(PKGDIR)";$(SLOCCMD) --out="$(RPTDIR)/cloc.xml" . | tee "$(RPTDIR)/cloc.out"
|
||||||
|
cat "$(RPTDIR)/test.out" | $(XUCMD) -output "$(RPTDIR)/tests.xml"
|
||||||
|
go list -f '{{join .Deps "\n"}}' "$(CMDPKG)/..." | sort | uniq | xargs -I {} sh -c "go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' {} | tee -a '$(RPTDIR)/deps.out'"
|
||||||
|
|
||||||
|
build: $(CMDS)
|
||||||
|
$(CMDS): setup-dirs dep
|
||||||
|
$(GOBUILD) "$(CMDPKG)/$@" | tee "$(RPTDIR)/build-$@.out"
|
||||||
|
install: $(INSTALL_TARGETS)
|
||||||
|
$(INSTALL_TARGETS):
|
||||||
|
$(GOINSTALL) "$(CMDPKG)/$(subst install-,,$@)"
|
||||||
|
|
||||||
|
dist: clean build
|
||||||
|
for docfile in $(DOC); do \
|
||||||
|
for dir in "$(DISTDIR)"/*; do \
|
||||||
|
cp "$(PKGDIR)/$$docfile" "$$dir/"; \
|
||||||
|
done; \
|
||||||
|
done
|
||||||
|
cd "$(DISTDIR)"; for dir in ./*linux*; do $(GZCMD) "$(basename "$$dir").tar.gz" "$$dir"; done
|
||||||
|
cd "$(DISTDIR)"; for dir in ./*windows*; do $(ZIPCMD) "$(basename "$$dir").zip" "$$dir"; done
|
||||||
|
cd "$(DISTDIR)"; for dir in ./*darwin*; do $(GZCMD) "$(basename "$$dir").tar.gz" "$$dir"; done
|
||||||
|
cd "$(DISTDIR)"; find . -maxdepth 1 -type f -printf "$(SHACMD) %P | tee \"./%P.sha\"\n" | sh
|
||||||
|
$(info "Built v$(VERSION), build $(COMMIT_ID)")
|
||||||
|
|
||||||
|
|
||||||
|
.PHONY: docker
|
||||||
|
docker: docker-image docker-push
|
||||||
|
|
||||||
|
.PHONY: docker-push
|
||||||
|
docker-push:
|
||||||
|
$(DOCKER_CMD) tag code.ndumas.com/ndumas/wikilink-parser:$(VERSION) code.ndumas.com/ndumas/wikilink-parser:latest
|
||||||
|
$(DOCKER_CMD) push code.ndumas.com/ndumas/wikilink-parser:latest
|
||||||
|
$(DOCKER_CMD) push code.ndumas.com/ndumas/wikilink-parser:$(VERSION)
|
||||||
|
|
||||||
|
.PHONY: docker-image
|
||||||
|
docker-image:
|
||||||
|
$(DOCKER_CMD) build --build-arg VERSION=$(VERSION) -t code.ndumas.com/ndumas/wikilink-parser:$(VERSION) .
|
||||||
|
|
||||||
|
.PHONY: build-alpine
|
||||||
|
build-alpine:
|
||||||
|
# this version breaks build variable injection
|
||||||
|
# CGO_ENABLED=0 GOOS=linux go build -ldflags="buildmode=exe $(LDFLAGS) -linkmode external -w -extldflags '-static' " -o $(DISTDIR)/$(NAME)-$(VERSION)-alpine/obp cmd/obp/*.go
|
||||||
|
CGO_ENABLED=0 GOOS=linux go build -ldflags="$(LDFLAGS)" -o $(DISTDIR)/$(NAME)-$(VERSION)-alpine/obp cmd/obp/*.go
|
||||||
|
|
||||||
|
|
||||||
|
debug:
|
||||||
|
$(info MD=$(MD))
|
||||||
|
$(info WD=$(WD))
|
||||||
|
$(info PKG=$(PKG))
|
||||||
|
$(info PKGDIR=$(PKGDIR))
|
||||||
|
$(info DISTDIR=$(DISTDIR))
|
||||||
|
$(info VERSION=$(VERSION))
|
||||||
|
$(info COMMIT_ID=$(COMMIT_ID))
|
||||||
|
$(info BUILD_TAGS=$(BUILD_TAGS))
|
||||||
|
$(info CMDS=$(CMDS))
|
||||||
|
$(info BUILD_TARGETS=$(BUILD_TARGETS))
|
||||||
|
$(info INSTALL_TARGETS=$(INSTALL_TARGETS))
|
@ -1,3 +1,3 @@
|
|||||||
module wikilinks
|
module code.ndumas.com/ndumas/wikilink-parser
|
||||||
|
|
||||||
go 1.19
|
go 1.19
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"regexp"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
alias = regexp.MustCompile(`\|(.*)`)
|
|
||||||
link = regexp.MustCompile(`^([a-zA-Z ]+)?[\|\#\^\\]?`)
|
|
||||||
subsection = regexp.MustCompile(`#([\w\s]+)`)
|
|
||||||
block = regexp.MustCompile(`#\^([a-zA-Z ]+)`)
|
|
||||||
wholeLink = regexp.MustCompile(`\[\[(.*)\]\]`)
|
|
||||||
)
|
|
||||||
|
|
||||||
type Link struct {
|
|
||||||
Dest, Alias, Subsection, Block string
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExtractLink(raw string) Link {
|
|
||||||
var li Link
|
|
||||||
|
|
||||||
rawLinkMatch := wholeLink.FindAllStringSubmatch(raw, -1)
|
|
||||||
var rawLink string
|
|
||||||
if len(rawLinkMatch) > 0 {
|
|
||||||
rawLink = rawLinkMatch[0][1]
|
|
||||||
}
|
|
||||||
|
|
||||||
l := link.FindAllStringSubmatch(rawLink, -1)
|
|
||||||
if len(l) > 0 {
|
|
||||||
li.Dest = l[0][1]
|
|
||||||
}
|
|
||||||
|
|
||||||
a := alias.FindAllStringSubmatch(rawLink, -1)
|
|
||||||
if len(a) > 0 {
|
|
||||||
li.Alias = a[0][1]
|
|
||||||
}
|
|
||||||
|
|
||||||
s := subsection.FindAllStringSubmatch(rawLink, -1)
|
|
||||||
if len(s) > 0 {
|
|
||||||
li.Subsection = s[0][1]
|
|
||||||
}
|
|
||||||
|
|
||||||
b := block.FindAllStringSubmatch(rawLink, -1)
|
|
||||||
if len(b) > 0 {
|
|
||||||
li.Block = b[0][1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return li
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
log.Printf("%#v\n", ExtractLink(`Embedding a link in a bigger block of text [[Regular Link#^link to block]] shouldn't cause any problems `))
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Test_ExtractLink(t *testing.T) {
|
|
||||||
tcs := []struct {
|
|
||||||
name string
|
|
||||||
in string
|
|
||||||
expected Link
|
|
||||||
}{
|
|
||||||
{"link", `[[Regular Link]]`, Link{Dest: "Regular Link"}},
|
|
||||||
{"transclude+link", `![[Transcluded Link]]`, Link{Dest: "Transcluded Link"}},
|
|
||||||
{"link+alias", `[[Regular Link|Alias]]`, Link{Dest: "Regular Link", Alias: "Alias"}},
|
|
||||||
{"link+subsection", `[[Regular Link#Subsection of page]]`, Link{Dest: "Regular Link", Subsection: "Subsection of page"}},
|
|
||||||
{"link+block", `[[Regular Link#^link to block]]`, Link{Dest: "Regular Link", Block: "link to block"}},
|
|
||||||
{"link+subsection+alias", `[[Regular Link#Subsection of page|Alias]]`, Link{Dest: "Regular Link", Subsection: "Subsection of page", Alias: "Alias"}},
|
|
||||||
{"link+block+alias", `[[Regular Link#^link to block|Alias]]`, Link{Dest: "Regular Link", Block: "link to block", Alias: "Alias"}},
|
|
||||||
{"link+alias+escape", `[[Regular Link\|Alias]]`, Link{Dest: "Regular Link", Alias: "Alias"}},
|
|
||||||
{"link+subsection+alias+escape", `[[Regular Link#Subsection of page\|Alias]]`, Link{Dest: "Regular Link", Subsection: "Subsection of page", Alias: "Alias"}},
|
|
||||||
{"link+block+alias+escape", `[[Regular Link#^link to block\|Alias]]`, Link{Dest: "Regular Link", Block: "link to block", Alias: "Alias"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, tc := range tcs {
|
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
|
||||||
out := ExtractLink(tc.in)
|
|
||||||
if out != tc.expected {
|
|
||||||
t.Logf("got %#v\n", out)
|
|
||||||
t.Fail()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,18 @@
|
|||||||
|
package wikilink
|
||||||
|
|
||||||
|
import (
|
||||||
|
// "log"
|
||||||
|
// "github.com/13rac1/goldmark-wikilink"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Wikilink struct {
|
||||||
|
Link string
|
||||||
|
Fragment string
|
||||||
|
Alias string
|
||||||
|
}
|
||||||
|
|
||||||
|
func Extract(raw string) Wikilink {
|
||||||
|
var wl Wikilink
|
||||||
|
|
||||||
|
return wl
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
package wikilink_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"code.ndumas.com/ndumas/wikilink-parser"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_Extract_Link(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tcs := []struct {
|
||||||
|
name string
|
||||||
|
in string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{name: "wikilink", in: "[[wikilink]]", expected: "wikilink"},
|
||||||
|
{name: "wikilink|display name", in: "[[wikilink|display name]]", expected: "wikilink"},
|
||||||
|
{name: "wikilink|display name|second pipe", in: "[[wikilink|display name|second pipe]]", expected: "wikilink"},
|
||||||
|
{name: "wikilink with numeric alias|420|second pipe", in: "[[wikilink|420|second pipe]]", expected: "wikilink with numeric aliases"},
|
||||||
|
{name: "wikilink with spaces in filename", in: "[[wikilink spaces]]", expected: "wikilink"},
|
||||||
|
{name: "#heading", in: "[[#heading]]", expected: ""},
|
||||||
|
{name: "wikilink#heading", in: "[[wikilink#heading]]", expected: "wikilink"},
|
||||||
|
{name: "wikilink#heading|display name", in: "[[wikilink#heading|display name]]", expected: "wikilink"},
|
||||||
|
{name: "wikilink#heading|display name", in: "[[wikilink#heading|display name]]", expected: "wikilink"},
|
||||||
|
{name: "wikilink with numeric aliases#heading|420|display name", in: "[[wikilink#heading|420|second pipe]]", expected: "wikilink"},
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
"[[#^blockRef]]"
|
||||||
|
"[[wikilink#^blockRef]]"
|
||||||
|
"[[wikilink#^blockRef|display name]]"
|
||||||
|
"[[wikilink#^blockRef|display name|secondpipe]]"
|
||||||
|
|
||||||
|
"[[#^blockRef]]"
|
||||||
|
"[[wikilink#^blockRef]]"
|
||||||
|
"[[wikilink#^blockRef|display name|secondpipe]]"
|
||||||
|
*/
|
||||||
|
|
||||||
|
for _, tc := range tcs {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
out := wikilink.Extract(tc.in)
|
||||||
|
if out.Link != tc.expected {
|
||||||
|
t.Logf("got %#v\n", out)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue