aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2026-02-11 22:50:27 +0700
committerShulhan <ms@kilabit.info>2026-02-11 22:50:53 +0700
commit00dfc937cec1b7eb9ebb1024fae5228ebf9f0341 (patch)
treeb0aaca000ad59993a0a862dda17a7fd778cf1518
parent1e833ea2a7d0300915c4c8a5c7bef09909ada915 (diff)
downloadciigo-00dfc937cec1b7eb9ebb1024fae5228ebf9f0341.tar.xz
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.
-rw-r--r--CHANGELOG.adoc14
-rw-r--r--ciigo.go2
-rw-r--r--cmd/ciigo/main.go47
-rw-r--r--go.mod12
-rw-r--r--go.sum20
-rw-r--r--server.go10
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 <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
// 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 <file>] [-exclude <regex>] [-out <file>]
The package name default to main.
The variable name default to memFS.
-ciigo [-template <file>] [-exclude <regex>] [-address <ip:port>] serve <dir>
+ciigo [-template <file>] [-exclude <regex>] [-address <ip:port>]
+ [-base-path <string>]
+ [-shutdown-idle <duration>]
+ serve <dir>
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 <ms@kilabit.info>
// SPDX-License-Identifier: GPL-3.0-or-later
+// SPDX-FileCopyrightText: 2019 Shulhan <ms@kilabit.info>
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 {