From e68c6e82fa8bf086b59d31230054de3c9ad9d5c4 Mon Sep 17 00:00:00 2001 From: Volker Schukai <volker.schukai@schukai.com> Date: Wed, 28 May 2025 10:18:06 +0200 Subject: [PATCH] chore: update nix and go --- flake.lock | 8 ++-- flake.nix | 4 +- source/go.mod | 6 +-- source/go.sum | 4 ++ .../esbuild/internal/compat/css_table.go | 43 +++++++++++++++++++ .../evanw/esbuild/internal/compat/js_table.go | 15 ++++--- .../esbuild/internal/css_parser/css_decls.go | 35 +++++++++++++-- .../internal/js_parser/js_parser_lower.go | 2 +- .../esbuild/internal/js_parser/ts_parser.go | 21 ++++++--- .../esbuild/internal/resolver/resolver.go | 29 +++++++------ .../github.com/tdewolff/parse/v2/common.go | 24 +++++++++++ source/vendor/modules.txt | 4 +- 12 files changed, 153 insertions(+), 42 deletions(-) diff --git a/flake.lock b/flake.lock index 0c3545e..198ad88 100644 --- a/flake.lock +++ b/flake.lock @@ -2,16 +2,16 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1735563628, - "narHash": "sha256-OnSAY7XDSx7CtDoqNh8jwVwh4xNL/2HaJxGjryLWzX8=", + "lastModified": 1748162331, + "narHash": "sha256-rqc2RKYTxP3tbjA+PB3VMRQNnjesrT0pEofXQTrMsS8=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "b134951a4c9f3c995fd7be05f3243f8ecd65d798", + "rev": "7c43f080a7f28b2774f3b3f43234ca11661bf334", "type": "github" }, "original": { "id": "nixpkgs", - "ref": "nixos-24.05", + "ref": "nixos-25.05", "type": "indirect" } }, diff --git a/flake.nix b/flake.nix index 3e868bd..abbf88e 100644 --- a/flake.nix +++ b/flake.nix @@ -2,8 +2,8 @@ description = "Bob the builder for Go projects"; # Nixpkgs / NixOS version to use. - inputs.nixpkgs.url = "nixpkgs/nixos-24.05"; - + inputs.nixpkgs.url = "nixpkgs/nixos-25.05"; + outputs = { self, nixpkgs, diff --git a/source/go.mod b/source/go.mod index b0ff802..5612668 100644 --- a/source/go.mod +++ b/source/go.mod @@ -1,12 +1,12 @@ module gitlab.schukai.com/oss/bob -go 1.23.0 +go 1.24.0 require ( github.com/andybalholm/cascadia v1.3.3 github.com/charmbracelet/log v0.4.2 - github.com/evanw/esbuild v0.25.4 - github.com/tdewolff/parse/v2 v2.8.0 + github.com/evanw/esbuild v0.25.5 + github.com/tdewolff/parse/v2 v2.8.1 gitlab.schukai.com/oss/libraries/go/application/xflags.git v1.16.5 gitlab.schukai.com/oss/libraries/go/markup/html.git v0.4.7 gitlab.schukai.com/oss/libraries/go/utilities/pathfinder.git v0.9.5 // indirect diff --git a/source/go.sum b/source/go.sum index d312174..a32db2b 100644 --- a/source/go.sum +++ b/source/go.sum @@ -86,6 +86,8 @@ github.com/evanw/esbuild v0.25.0 h1:jRR9D1pfdb669VzdN4w0jwsDfrKE098nKMaDMKvMPyU= github.com/evanw/esbuild v0.25.0/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= github.com/evanw/esbuild v0.25.4 h1:k1bTSim+usBG27w7BfOCorhgx3tO+6bAfMj5pR+6SKg= github.com/evanw/esbuild v0.25.4/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= +github.com/evanw/esbuild v0.25.5 h1:E+JpeY5S/1LFmnX1vtuZqUKT7qDVcfXdhzMhM3uIKFs= +github.com/evanw/esbuild v0.25.5/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -124,6 +126,8 @@ github.com/tdewolff/parse/v2 v2.7.20 h1:Y33JmRLjyGhX5JRvYh+CO6Sk6pGMw3iO5eKGhUhx github.com/tdewolff/parse/v2 v2.7.20/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= github.com/tdewolff/parse/v2 v2.8.0 h1:jW0afj6zpUGXuZTwJ7/UfP2SddyLalb/SDryjaMTkA4= github.com/tdewolff/parse/v2 v2.8.0/go.mod h1:Hwlni2tiVNKyzR1o6nUs4FOF07URA+JLBLd6dlIXYqo= +github.com/tdewolff/parse/v2 v2.8.1 h1:J5GSHru6o3jF1uLlEKVXkDxxcVx6yzOlIVIotK4w2po= +github.com/tdewolff/parse/v2 v2.8.1/go.mod h1:Hwlni2tiVNKyzR1o6nUs4FOF07URA+JLBLd6dlIXYqo= github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52 h1:gAQliwn+zJrkjAHVcBEYW/RFvd2St4yYimisvozAYlA= github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= github.com/tdewolff/test v1.0.11 h1:FdLbwQVHxqG16SlkGveC0JVyrJN62COWTRyUFzfbtBE= diff --git a/source/vendor/github.com/evanw/esbuild/internal/compat/css_table.go b/source/vendor/github.com/evanw/esbuild/internal/compat/css_table.go index 951795d..0bc4cb9 100644 --- a/source/vendor/github.com/evanw/esbuild/internal/compat/css_table.go +++ b/source/vendor/github.com/evanw/esbuild/internal/compat/css_table.go @@ -220,6 +220,13 @@ var cssPrefixTable = map[css_ast.D][]prefixData{ {engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{20, 0, 0}}, {engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{9, 1, 0}}, }, + css_ast.DHeight: { + {engine: Chrome, prefix: WebkitPrefix}, + {engine: Edge, prefix: WebkitPrefix}, + {engine: IOS, prefix: WebkitPrefix}, + {engine: Opera, prefix: WebkitPrefix}, + {engine: Safari, prefix: WebkitPrefix}, + }, css_ast.DHyphens: { {engine: Edge, prefix: MsPrefix, withoutPrefix: v{79, 0, 0}}, {engine: Firefox, prefix: MozPrefix, withoutPrefix: v{43, 0, 0}}, @@ -273,6 +280,34 @@ var cssPrefixTable = map[css_ast.D][]prefixData{ {engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}}, {engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}}, }, + css_ast.DMaxHeight: { + {engine: Chrome, prefix: WebkitPrefix}, + {engine: Edge, prefix: WebkitPrefix}, + {engine: IOS, prefix: WebkitPrefix}, + {engine: Opera, prefix: WebkitPrefix}, + {engine: Safari, prefix: WebkitPrefix}, + }, + css_ast.DMaxWidth: { + {engine: Chrome, prefix: WebkitPrefix}, + {engine: Edge, prefix: WebkitPrefix}, + {engine: IOS, prefix: WebkitPrefix}, + {engine: Opera, prefix: WebkitPrefix}, + {engine: Safari, prefix: WebkitPrefix}, + }, + css_ast.DMinHeight: { + {engine: Chrome, prefix: WebkitPrefix}, + {engine: Edge, prefix: WebkitPrefix}, + {engine: IOS, prefix: WebkitPrefix}, + {engine: Opera, prefix: WebkitPrefix}, + {engine: Safari, prefix: WebkitPrefix}, + }, + css_ast.DMinWidth: { + {engine: Chrome, prefix: WebkitPrefix}, + {engine: Edge, prefix: WebkitPrefix}, + {engine: IOS, prefix: WebkitPrefix}, + {engine: Opera, prefix: WebkitPrefix}, + {engine: Safari, prefix: WebkitPrefix}, + }, css_ast.DPosition: { {engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{13, 0, 0}}, {engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{13, 0, 0}}, @@ -333,6 +368,14 @@ var cssPrefixTable = map[css_ast.D][]prefixData{ {engine: Safari, prefix: KhtmlPrefix, withoutPrefix: v{3, 0, 0}}, {engine: Safari, prefix: WebkitPrefix}, }, + css_ast.DWidth: { + {engine: Chrome, prefix: WebkitPrefix}, + {engine: Edge, prefix: WebkitPrefix}, + {engine: Firefox, prefix: MozPrefix}, + {engine: IOS, prefix: WebkitPrefix}, + {engine: Opera, prefix: WebkitPrefix}, + {engine: Safari, prefix: WebkitPrefix}, + }, } func CSSPrefixData(constraints map[Engine]Semver) (entries map[css_ast.D]CSSPrefix) { diff --git a/source/vendor/github.com/evanw/esbuild/internal/compat/js_table.go b/source/vendor/github.com/evanw/esbuild/internal/compat/js_table.go index 5cab807..d47101f 100644 --- a/source/vendor/github.com/evanw/esbuild/internal/compat/js_table.go +++ b/source/vendor/github.com/evanw/esbuild/internal/compat/js_table.go @@ -588,13 +588,14 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{ Node: {{start: v{16, 14, 0}, end: v{22, 0, 0}}}, }, ImportAttributes: { - Chrome: {{start: v{123, 0, 0}}}, - Deno: {{start: v{1, 37, 0}}}, - Edge: {{start: v{123, 0, 0}}}, - IOS: {{start: v{17, 2, 0}}}, - Node: {{start: v{18, 20, 0}, end: v{19, 0, 0}}, {start: v{20, 10, 0}}}, - Opera: {{start: v{109, 0, 0}}}, - Safari: {{start: v{17, 2, 0}}}, + Chrome: {{start: v{123, 0, 0}}}, + Deno: {{start: v{1, 37, 0}}}, + Edge: {{start: v{123, 0, 0}}}, + Firefox: {{start: v{138, 0, 0}}}, + IOS: {{start: v{17, 2, 0}}}, + Node: {{start: v{18, 20, 0}, end: v{19, 0, 0}}, {start: v{20, 10, 0}}}, + Opera: {{start: v{109, 0, 0}}}, + Safari: {{start: v{17, 2, 0}}}, }, ImportMeta: { Chrome: {{start: v{64, 0, 0}}}, diff --git a/source/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls.go b/source/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls.go index eaca876..4a15a74 100644 --- a/source/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls.go +++ b/source/vendor/github.com/evanw/esbuild/internal/css_parser/css_decls.go @@ -223,7 +223,7 @@ func (p *parser) processDeclarations(rules []css_ast.Rule, composesContext *comp case css_ast.DContainerName: p.processContainerName(decl.Value) - // Animation name + // Animation name case css_ast.DAnimation: p.processAnimationShorthand(decl.Value) case css_ast.DAnimationName: @@ -237,7 +237,7 @@ func (p *parser) processDeclarations(rules []css_ast.Rule, composesContext *comp p.processListStyleType(&decl.Value[0]) } - // Font + // Font case css_ast.DFont: if p.options.minifySyntax { decl.Value = p.mangleFont(decl.Value) @@ -253,7 +253,7 @@ func (p *parser) processDeclarations(rules []css_ast.Rule, composesContext *comp decl.Value[0] = p.mangleFontWeight(decl.Value[0]) } - // Margin + // Margin case css_ast.DMargin: if p.options.minifySyntax { margin.mangleSides(rewrittenRules, decl, p.options.minifyWhitespace) @@ -444,6 +444,13 @@ func (p *parser) insertPrefixedDeclaration(rules []css_ast.Rule, prefix string, if len(decl.Value) != 1 || decl.Value[0].Kind != css_lexer.TIdent || !strings.EqualFold(decl.Value[0].Text, "sticky") { return rules } + + case css_ast.DWidth, css_ast.DMinWidth, css_ast.DMaxWidth, + css_ast.DHeight, css_ast.DMinHeight, css_ast.DMaxHeight: + // The prefix is only needed for "width: stretch" + if len(decl.Value) != 1 || decl.Value[0].Kind != css_lexer.TIdent || !strings.EqualFold(decl.Value[0].Text, "stretch") { + return rules + } } value := css_ast.CloneTokensWithoutImportRecords(decl.Value) @@ -455,6 +462,19 @@ func (p *parser) insertPrefixedDeclaration(rules []css_ast.Rule, prefix string, keyText = decl.KeyText value[0].Text = "-webkit-sticky" + case css_ast.DWidth, css_ast.DMinWidth, css_ast.DMaxWidth, + css_ast.DHeight, css_ast.DMinHeight, css_ast.DMaxHeight: + // The prefix applies to the value, not the property + keyText = decl.KeyText + + // This currently only applies to "stretch" (already checked above) + switch prefix { + case "-webkit-": + value[0].Text = "-webkit-fill-available" + case "-moz-": + value[0].Text = "-moz-available" + } + case css_ast.DUserSelect: // The prefix applies to the value as well as the property if prefix == "-moz-" && len(value) == 1 && value[0].Kind == css_lexer.TIdent && strings.EqualFold(value[0].Text, "none") { @@ -481,6 +501,15 @@ func (p *parser) insertPrefixedDeclaration(rules []css_ast.Rule, prefix string, } } + // If we didn't change the key, manually search for a previous duplicate rule + if keyText == decl.KeyText { + for _, rule := range rules { + if prevDecl, ok := rule.Data.(*css_ast.RDeclaration); ok && prevDecl.KeyText == keyText && css_ast.TokensEqual(prevDecl.Value, value, nil) { + return rules + } + } + } + // Overwrite the latest declaration with the prefixed declaration rules[len(rules)-1] = css_ast.Rule{Loc: loc, Data: &css_ast.RDeclaration{ KeyText: keyText, diff --git a/source/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go b/source/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go index 89c7721..fbd7441 100644 --- a/source/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go +++ b/source/vendor/github.com/evanw/esbuild/internal/js_parser/js_parser_lower.go @@ -1892,7 +1892,6 @@ func (p *parser) lowerUsingDeclarationContext() lowerUsingDeclarationContext { } } -// If this returns "nil", then no lowering needed to be done func (ctx *lowerUsingDeclarationContext) scanStmts(p *parser, stmts []js_ast.Stmt) { for _, stmt := range stmts { if local, ok := stmt.Data.(*js_ast.SLocal); ok && local.Kind.IsUsing() { @@ -2116,6 +2115,7 @@ func (p *parser) lowerUsingDeclarationInForOf(loc logger.Loc, init *js_ast.SLoca id.Ref = tempRef } +// If this returns "nil", then no lowering needed to be done func (p *parser) maybeLowerUsingDeclarationsInSwitch(loc logger.Loc, s *js_ast.SSwitch) []js_ast.Stmt { // Check for a "using" declaration in any case shouldLower := false diff --git a/source/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go b/source/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go index 6338fa0..4b37be6 100644 --- a/source/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go +++ b/source/vendor/github.com/evanw/esbuild/internal/js_parser/ts_parser.go @@ -262,7 +262,8 @@ loop: p.lexer.Next() // "[import: number]" - if flags.has(allowTupleLabelsFlag) && p.lexer.Token == js_lexer.TColon { + // "[import?: number]" + if flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) { return } @@ -288,7 +289,8 @@ loop: p.lexer.Next() // "[new: number]" - if flags.has(allowTupleLabelsFlag) && p.lexer.Token == js_lexer.TColon { + // "[new?: number]" + if flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) { return } @@ -314,13 +316,15 @@ loop: // Valid: // "[keyof: string]" + // "[keyof?: string]" // "{[keyof: string]: number}" // "{[keyof in string]: number}" // // Invalid: // "A extends B ? keyof : string" // - if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TIn) || (!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) { + if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion && p.lexer.Token != js_lexer.TIn) || + (!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) { p.skipTypeScriptType(js_ast.LPrefix) } break loop @@ -332,7 +336,10 @@ loop: // "type Foo = Bar extends [infer T extends string] ? T : null" // "type Foo = Bar extends [infer T extends string ? infer T : never] ? T : null" // "type Foo = { [infer in Bar]: number }" - if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TIn) || (!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) { + // "type Foo = [infer: number]" + // "type Foo = [infer?: number]" + if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion && p.lexer.Token != js_lexer.TIn) || + (!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) { p.lexer.Expect(js_lexer.TIdentifier) if p.lexer.Token == js_lexer.TExtends { p.trySkipTypeScriptConstraintOfInferTypeWithBacktracking(flags) @@ -390,7 +397,8 @@ loop: p.lexer.Next() // "[typeof: number]" - if flags.has(allowTupleLabelsFlag) && p.lexer.Token == js_lexer.TColon { + // "[typeof?: number]" + if flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) { return } @@ -459,12 +467,13 @@ loop: default: // "[function: number]" + // "[function?: number]" if flags.has(allowTupleLabelsFlag) && p.lexer.IsIdentifierOrKeyword() { if p.lexer.Token != js_lexer.TFunction { p.log.AddError(&p.tracker, p.lexer.Range(), fmt.Sprintf("Unexpected %q", p.lexer.Raw())) } p.lexer.Next() - if p.lexer.Token != js_lexer.TColon { + if p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion { p.lexer.Expect(js_lexer.TColon) } return diff --git a/source/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go b/source/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go index 5625ea4..bd34c50 100644 --- a/source/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go +++ b/source/vendor/github.com/evanw/esbuild/internal/resolver/resolver.go @@ -1012,6 +1012,21 @@ func (r resolverQuery) resolveWithoutSymlinks(sourceDir string, sourceDirInfo *d strings.HasSuffix(importPath, "/.") || strings.HasSuffix(importPath, "/..") + // Check the "browser" map + if importDirInfo := r.dirInfoCached(r.fs.Dir(absPath)); importDirInfo != nil { + if remapped, ok := r.checkBrowserMap(importDirInfo, absPath, absolutePathKind); ok { + if remapped == nil { + return &ResolveResult{PathPair: PathPair{Primary: logger.Path{Text: absPath, Namespace: "file", Flags: logger.PathDisabled}}} + } + if remappedResult, ok, diffCase, sideEffects := r.resolveWithoutRemapping(importDirInfo.enclosingBrowserScope, *remapped); ok { + result = ResolveResult{PathPair: remappedResult, DifferentCase: diffCase, PrimarySideEffectsData: sideEffects} + hasTrailingSlash = false + checkRelative = false + checkPackage = false + } + } + } + if hasTrailingSlash { if absolute, ok, diffCase := r.loadAsDirectory(absPath); ok { checkPackage = false @@ -1020,20 +1035,6 @@ func (r resolverQuery) resolveWithoutSymlinks(sourceDir string, sourceDirInfo *d return nil } } else { - // Check the "browser" map - if importDirInfo := r.dirInfoCached(r.fs.Dir(absPath)); importDirInfo != nil { - if remapped, ok := r.checkBrowserMap(importDirInfo, absPath, absolutePathKind); ok { - if remapped == nil { - return &ResolveResult{PathPair: PathPair{Primary: logger.Path{Text: absPath, Namespace: "file", Flags: logger.PathDisabled}}} - } - if remappedResult, ok, diffCase, sideEffects := r.resolveWithoutRemapping(importDirInfo.enclosingBrowserScope, *remapped); ok { - result = ResolveResult{PathPair: remappedResult, DifferentCase: diffCase, PrimarySideEffectsData: sideEffects} - checkRelative = false - checkPackage = false - } - } - } - if checkRelative { if absolute, ok, diffCase := r.loadAsFileOrDirectory(absPath); ok { checkPackage = false diff --git a/source/vendor/github.com/tdewolff/parse/v2/common.go b/source/vendor/github.com/tdewolff/parse/v2/common.go index 05f8817..68863a5 100644 --- a/source/vendor/github.com/tdewolff/parse/v2/common.go +++ b/source/vendor/github.com/tdewolff/parse/v2/common.go @@ -544,3 +544,27 @@ func DecodeURL(b []byte) []byte { } return b } + +func AppendEscape(b, str, chars []byte, escape byte) []byte { + i := 0 + for j := 0; j < len(str); j++ { + has := false + for _, c := range chars { + if c == str[j] { + has = true + break + } + } + if has || str[j] == escape { + if i < j { + b = append(b, str[i:j]...) + } + b = append(b, escape) + i = j + } + } + if i < len(str) { + b = append(b, str[i:]...) + } + return b +} diff --git a/source/vendor/modules.txt b/source/vendor/modules.txt index 57bc76c..051373b 100644 --- a/source/vendor/modules.txt +++ b/source/vendor/modules.txt @@ -125,7 +125,7 @@ github.com/charmbracelet/x/cellbuf # github.com/charmbracelet/x/term v0.2.1 ## explicit; go 1.18 github.com/charmbracelet/x/term -# github.com/evanw/esbuild v0.25.4 +# github.com/evanw/esbuild v0.25.5 ## explicit; go 1.13 github.com/evanw/esbuild/internal/api_helpers github.com/evanw/esbuild/internal/ast @@ -172,7 +172,7 @@ github.com/muesli/termenv # github.com/rivo/uniseg v0.4.7 ## explicit; go 1.18 github.com/rivo/uniseg -# github.com/tdewolff/parse/v2 v2.8.0 +# github.com/tdewolff/parse/v2 v2.8.1 ## explicit; go 1.11 github.com/tdewolff/parse/v2 github.com/tdewolff/parse/v2/buffer -- GitLab