From 00dfc937cec1b7eb9ebb1024fae5228ebf9f0341 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Wed, 11 Feb 2026 22:50:27 +0700 Subject: cmd/ciigo: add option to set base path and shutdown idle duration The `-base-path` option set the URL prefix for serving HTTP request. This allow serving the content under the prefix other than "/". The `-shutdown-idle` option set the duration when server will stop accepting new connections and shutting down. This option can be helpful to reduce the resources on local environment. --- CHANGELOG.adoc | 14 ++++++++++++++ ciigo.go | 2 +- cmd/ciigo/main.go | 47 ++++++++++++++++++++++++++++++++++------------- go.mod | 12 ++++++------ go.sum | 20 ++++++++++---------- server.go | 10 +++++----- 6 files changed, 70 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index a1c90f0..5563d38 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -12,6 +12,20 @@ Legend, * 🌼: Enhancement * 💧: Chores + +[#v0_17_0] +== ciigo v0.17.0 (2026-xx-xx) + +**🌱 cmd/ciigo**: add option to set base path and shutdown idle duration** + +The `-base-path` option set the URL prefix for serving HTTP request. +This allow serving the content under the prefix other than "/". + +The `-shutdown-idle` option set the duration when server will stop accepting +new connections and shutting down. +This option can be helpful to reduce the resources on local environment. + + [#v0_16_0] == ciigo v0.16.0 (2026-02-09) diff --git a/ciigo.go b/ciigo.go index ea25599..d4d8edf 100644 --- a/ciigo.go +++ b/ciigo.go @@ -28,7 +28,7 @@ const ( ) // Version define the latest tagged release of this module. -var Version = `0.16.0` +var Version = `0.17.0` // defExcludes define default files to be excludes on GoEmbed. var defExcludes = []string{ diff --git a/cmd/ciigo/main.go b/cmd/ciigo/main.go index 8dcf04b..f52c99d 100644 --- a/cmd/ciigo/main.go +++ b/cmd/ciigo/main.go @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2019 Shulhan // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2019 Shulhan // ciigo is a CLI to convert, embed, and/or serve a directory that contains // markup files, as HTML files. @@ -11,6 +11,7 @@ import ( "log" "os" "strings" + "time" "git.sr.ht/~shulhan/ciigo" libhttp "git.sr.ht/~shulhan/pakakeh.go/lib/http" @@ -26,20 +27,32 @@ const ( ) func main() { + var serveOpts = ciigo.ServeOptions{ + ServerOptions: libhttp.ServerOptions{ + EnableIndexHTML: true, + }, + IsDevelopment: true, + } var ( htmlTemplate *string outputFile *string - address *string exclude *string ) + var shutdownIdleDuration string flag.Usage = usage htmlTemplate = flag.String("template", "", "path to HTML template") outputFile = flag.String("out", "ciigo_static.go", "path to output of .go embed file") - address = flag.String(`address`, `127.0.0.1:6320`, - "the binding address for HTTP server") + + flag.StringVar(&serveOpts.Address, `address`, `127.0.0.1:6320`, + `Set the listening address for HTTP server.`) + flag.StringVar(&serveOpts.BasePath, `base-path`, ``, + `Set the base path (or prefix) for handling HTTP request.`) + flag.StringVar(&shutdownIdleDuration, `shutdown-idle`, ``, + `Set the duration when server will shutting down after idle.`) + exclude = flag.String("exclude", "", "a regex to exclude certain paths from being scanned during covert, embeded, watch, or serve") @@ -48,6 +61,14 @@ func main() { flag.Parse() + var err error + if shutdownIdleDuration != `` { + serveOpts.ShutdownIdleDuration, err = time.ParseDuration(shutdownIdleDuration) + if err != nil { + log.Fatalf(`invalid shutdown-idle %s: %s`, shutdownIdleDuration, err) + } + } + var ( command = strings.ToLower(flag.Arg(0)) convertOpts = ciigo.ConvertOptions{ @@ -55,7 +76,6 @@ func main() { HTMLTemplate: *htmlTemplate, Exclude: []string{*exclude}, } - err error ) if len(command) == 0 { @@ -86,13 +106,6 @@ func main() { usage() case cmdServe: - var serveOpts = ciigo.ServeOptions{ - ServerOptions: libhttp.ServerOptions{ - Address: *address, - EnableIndexHTML: true, - }, - IsDevelopment: true, - } err = ciigo.Serve(serveOpts, convertOpts) case cmdVersion: @@ -137,12 +150,20 @@ ciigo [-template ] [-exclude ] [-out ] The package name default to main. The variable name default to memFS. -ciigo [-template ] [-exclude ] [-address ] serve +ciigo [-template ] [-exclude ] [-address ] + [-base-path ] + [-shutdown-idle ] + serve Serve all files inside directory "dir" using HTTP server, watch changes on markup files and convert them to HTML files automatically. If the address is not set, its default to ":8080". + The -base-path set the base path or prefix for serving HTTP request. + + The -shutdown-idle set the duration when the serve will automatically + shutting down when idle. + ciigo version Print the current ciigo version.`) diff --git a/go.mod b/go.mod index c2fa4aa..757b3eb 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,5 @@ -// SPDX-FileCopyrightText: 2019 Shulhan // SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: 2019 Shulhan module git.sr.ht/~shulhan/ciigo @@ -7,7 +7,7 @@ go 1.25.0 require ( git.sr.ht/~shulhan/asciidoctor-go v0.7.3 - git.sr.ht/~shulhan/pakakeh.go v0.61.0 + git.sr.ht/~shulhan/pakakeh.go v0.61.1-0.20260211152820-e5a9e1e5314a github.com/yuin/goldmark v1.7.16 github.com/yuin/goldmark-meta v1.1.0 ) @@ -15,12 +15,12 @@ require ( require ( github.com/kr/pretty v0.3.1 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect - golang.org/x/mod v0.32.0 // indirect - golang.org/x/net v0.49.0 // indirect + golang.org/x/exp v0.0.0-20260209203927-2842357ff358 // indirect + golang.org/x/mod v0.33.0 // indirect + golang.org/x/net v0.50.0 // indirect golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect - golang.org/x/tools v0.41.0 // indirect + golang.org/x/tools v0.42.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 976c931..53da165 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ git.sr.ht/~shulhan/asciidoctor-go v0.7.3 h1:QjMMG3AgtnWkAIV2OqPfAksCdgonmY6cQXwyXp1c764= git.sr.ht/~shulhan/asciidoctor-go v0.7.3/go.mod h1:fdqQrwicDfRycH6ovYIQ5NzwbFIryNSsrFn5Gw0IsOk= -git.sr.ht/~shulhan/pakakeh.go v0.61.0 h1:a/8kcBX0/sCywDbHNrjTmZ4xdJZUZYoedpH1EVuUkPs= -git.sr.ht/~shulhan/pakakeh.go v0.61.0/go.mod h1:mGR0PxGu4X7Vr2U2/3k4phuPjiFC2seTwJnitk8B4LU= +git.sr.ht/~shulhan/pakakeh.go v0.61.1-0.20260211152820-e5a9e1e5314a h1:VpuI0dK82MqHO5yaDZyfTn3gOU6noFW1wcJBjSsI5Ms= +git.sr.ht/~shulhan/pakakeh.go v0.61.1-0.20260211152820-e5a9e1e5314a/go.mod h1:cU1ZnE54I0SaI3e1aHAmnMYIXq6N2c7yGbbMpFYOECI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -20,18 +20,18 @@ github.com/yuin/goldmark v1.7.16 h1:n+CJdUxaFMiDUNnWC3dMWCIQJSkxH4uz3ZwQBkAlVNE= github.com/yuin/goldmark v1.7.16/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc= github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0= -golang.org/x/exp v0.0.0-20260112195511-716be5621a96 h1:Z/6YuSHTLOHfNFdb8zVZomZr7cqNgTJvA8+Qz75D8gU= -golang.org/x/exp v0.0.0-20260112195511-716be5621a96/go.mod h1:nzimsREAkjBCIEFtHiYkrJyT+2uy9YZJB7H1k68CXZU= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= -golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= -golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/exp v0.0.0-20260209203927-2842357ff358 h1:kpfSV7uLwKJbFSEgNhWzGSL47NDSF/5pYYQw1V0ub6c= +golang.org/x/exp v0.0.0-20260209203927-2842357ff358/go.mod h1:R3t0oliuryB5eenPWl3rrQxwnNM3WTwnsRZZiXLAAW8= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/server.go b/server.go index f8270b8..b17cb5f 100644 --- a/server.go +++ b/server.go @@ -195,17 +195,17 @@ func (ciigo *Ciigo) onGet( ) (out *memfs.Node, statusCode int) { var ( logp = `onGet` - file string + file = req.URL.Path ) if node == nil { // File does not exist. - file = req.URL.Path - ext := path.Ext(file) + ext := path.Ext(req.URL.Path) if ext == `.adoc` || ext == `.md` { // Redirect to .html. - file = strings.TrimSuffix(file, ext) + `.html` - http.Redirect(w, req, file, http.StatusSeeOther) + req.URL.Path = strings.TrimSuffix(req.URL.Path, ext) + `.html` + req.URL.Path = path.Join(ciigo.serveOpts.BasePath, req.URL.Path) + http.Redirect(w, req, req.URL.String(), http.StatusSeeOther) return nil, http.StatusSeeOther } } else if ciigo.serveOpts.IsDevelopment { -- cgit v1.3