]> Cypherpunks.ru repositories - gocheese.git/commitdiff
Refactor -help, remove -root
authorSergey Matveev <stargrave@stargrave.org>
Sun, 26 Sep 2021 12:18:44 +0000 (15:18 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Sun, 26 Sep 2021 17:15:43 +0000 (20:15 +0300)
README
doc/ucspi.texi
fileutils.go
hr.go
integrity.go
json.go
list.go
main.go
refresh.go
upload.go
usage.go [new file with mode: 0644]

diff --git a/README b/README
index bd87b59be1efb329da990cc6cf81955f92b67806..16122c99287e18a8db500621e234ba3fff8d01c7 100644 (file)
--- a/README
+++ b/README
@@ -1,2 +1,2 @@
 GoCheese is Python private package repository and caching proxy.
-See gocheese.{info,texi} and INSTALL for more documentation.
+See doc/gocheese.info and INSTALL for more documentation.
index 45d8fe3e57bd6f874e84f3af4fc9f2ee3fbb4772..0927113539ab3e98cbc443c7ce3d2fee66c506f6 100644 (file)
@@ -17,7 +17,7 @@ umask 077
 umask 022
 mkdir -p packages
 exec setuidgid gocheese tcpserver -DRH -l 0 ::0 8080 \
-    gocheese -ucspi -passwd passwd
+    gocheese -ucspi -passwd passwd /path/to/packages
 EOF
 
 # cat > log/run <<EOF
index b37b99ce4c79aa01c2e56534c9a2887767e0e6a8..218b800156d086093dea82767ee351a3c0b289de 100644 (file)
@@ -79,7 +79,7 @@ func WriteFileSync(dirPath, filePath string, data []byte, mtime time.Time) error
 }
 
 func mkdirForPkg(w http.ResponseWriter, r *http.Request, pkgName string) bool {
-       path := filepath.Join(*Root, pkgName)
+       path := filepath.Join(Root, pkgName)
        if _, err := os.Stat(path); os.IsNotExist(err) {
                if err = os.Mkdir(path, os.FileMode(0777)); err != nil {
                        log.Println("error", r.RemoteAddr, "mkdir", pkgName, err)
diff --git a/hr.go b/hr.go
index 845a13e5fb98d043a924c13d1657519673212e9c..286fc2f0dc8ecc89fe4ab6a93da4f1380d4462e0 100644 (file)
--- a/hr.go
+++ b/hr.go
@@ -32,7 +32,7 @@ var (
        HRRootTmpl = template.Must(template.New("hr-root").Parse(`<!DOCTYPE html>
 <html>
   <head>
-    <title>{{.Version}}: human readable listing</title>
+    <title>{{.Version}}: packages</title>
   </head>
   <body>
     <ul>{{range .Packages}}
@@ -123,7 +123,7 @@ var (
 )
 
 func serveHRRoot(w http.ResponseWriter, r *http.Request) {
-       files, err := ioutil.ReadDir(*Root)
+       files, err := ioutil.ReadDir(Root)
        if err != nil {
                log.Println("error", r.RemoteAddr, "hr-root", err)
                http.Error(w, err.Error(), http.StatusInternalServerError)
index 84011fe23acafec4310d0d0892c281cdd1bd9967..ac7500e7c656bdd27da062aea16bb1c96d3fe5d1 100644 (file)
@@ -64,7 +64,7 @@ func checkFile(
 }
 
 func goodIntegrity() bool {
-       dirs, err := ioutil.ReadDir(*Root)
+       dirs, err := ioutil.ReadDir(Root)
        if err != nil {
                log.Fatal(err)
        }
@@ -75,7 +75,7 @@ func goodIntegrity() bool {
        isGood := true
        var pkgName string
        for _, dir := range dirs {
-               files, err := ioutil.ReadDir(filepath.Join(*Root, dir.Name()))
+               files, err := ioutil.ReadDir(filepath.Join(Root, dir.Name()))
                if err != nil {
                        log.Fatal(err)
                }
@@ -84,8 +84,8 @@ func goodIntegrity() bool {
                                pkgName = strings.TrimSuffix(file.Name(), "."+HashAlgoSHA256)
                                if !checkFile(
                                        pkgName,
-                                       filepath.Join(*Root, dir.Name(), pkgName),
-                                       filepath.Join(*Root, dir.Name(), file.Name()),
+                                       filepath.Join(Root, dir.Name(), pkgName),
+                                       filepath.Join(Root, dir.Name(), file.Name()),
                                        "SHA256", hasherSHA256, digestSHA256,
                                ) {
                                        isGood = false
@@ -96,8 +96,8 @@ func goodIntegrity() bool {
                                pkgName = strings.TrimSuffix(file.Name(), "."+HashAlgoBLAKE2b256)
                                if !checkFile(
                                        pkgName,
-                                       filepath.Join(*Root, dir.Name(), pkgName),
-                                       filepath.Join(*Root, dir.Name(), file.Name()),
+                                       filepath.Join(Root, dir.Name(), pkgName),
+                                       filepath.Join(Root, dir.Name(), file.Name()),
                                        "BLAKE2b-256", hasherBLAKE2b256, digestBLAKE2b256,
                                ) {
                                        isGood = false
diff --git a/json.go b/json.go
index 7ccb14287ab77cbddd63ba5631544918a7076e03..a9a21a8024e97470c47a9aa0f0e47d15f4c29c8f 100644 (file)
--- a/json.go
+++ b/json.go
@@ -35,7 +35,7 @@ func getMetadata(pkgName, version string) (*PkgMeta, []*PkgReleaseInfo, error) {
        if err != nil {
                return nil, nil, err
        }
-       metadata, err := ioutil.ReadFile(filepath.Join(*Root, pkgName, MetadataFile))
+       metadata, err := ioutil.ReadFile(filepath.Join(Root, pkgName, MetadataFile))
        if err != nil {
                if !os.IsNotExist(err) {
                        return nil, nil, err
diff --git a/list.go b/list.go
index d8bd0732459d04fc805e1f6562418d71dae4c00b..48a9d71498fc7cbaebe315bd76cba7d76b1871d2 100644 (file)
--- a/list.go
+++ b/list.go
@@ -66,7 +66,7 @@ var (
 )
 
 func listRoot(w http.ResponseWriter, r *http.Request) {
-       files, err := ioutil.ReadDir(*Root)
+       files, err := ioutil.ReadDir(Root)
        if err != nil {
                log.Println("error", r.RemoteAddr, "root", err)
                http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -138,7 +138,7 @@ func filenameToVersion(fn string) string {
 }
 
 func listDir(pkgName string, doSize bool) (int, []*PkgReleaseInfo, error) {
-       dirPath := filepath.Join(*Root, pkgName)
+       dirPath := filepath.Join(Root, pkgName)
        entries, err := os.ReadDir(dirPath)
        if err != nil {
                return 0, nil, err
@@ -215,7 +215,7 @@ func serveListDir(
        pkgName string,
        autorefresh, gpgUpdate bool,
 ) {
-       dirPath := filepath.Join(*Root, pkgName)
+       dirPath := filepath.Join(Root, pkgName)
        if autorefresh {
                if !refreshDir(w, r, pkgName, "", gpgUpdate) {
                        return
diff --git a/main.go b/main.go
index 76f4b8a9908936e14114e45fcf92a2d611eda1f3..417c2c1675c2fc5177bcd4b17de289e7dc6f5163 100644 (file)
--- a/main.go
+++ b/main.go
@@ -46,53 +46,41 @@ import (
 const (
        Version   = "3.0.0"
        UserAgent = "GoCheese/" + Version
-
-       Warranty = `This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, version 3 of the License.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.`
 )
 
 var (
-       Root       = flag.String("root", "./packages", "Path to packages directory")
-       Bind       = flag.String("bind", "[::]:8080", "Address to bind to")
-       MaxClients = flag.Int("maxclients", 128, "Maximal amount of simultaneous clients")
-       DoUCSPI    = flag.Bool("ucspi", false, "Work as UCSPI-TCP service")
+       Root       string
+       Bind       = flag.String("bind", DefaultBind, "")
+       MaxClients = flag.Int("maxclients", DefaultMaxClients, "")
+       DoUCSPI    = flag.Bool("ucspi", false, "")
 
-       TLSCert = flag.String("tls-cert", "", "Path to TLS X.509 certificate")
-       TLSKey  = flag.String("tls-key", "", "Path to TLS X.509 private key")
+       TLSCert = flag.String("tls-cert", "", "")
+       TLSKey  = flag.String("tls-key", "", "")
 
-       NoRefreshURLPath = flag.String("norefresh", "/norefresh/", "Non-refreshing URL path")
-       RefreshURLPath   = flag.String("refresh", "/simple/", "Auto-refreshing URL path")
-       GPGUpdateURLPath = flag.String("gpgupdate", "/gpgupdate/", "GPG forceful refreshing URL path")
-       JSONURLPath      = flag.String("json", "/pypi/", "JSON API URL path")
+       NoRefreshURLPath = flag.String("norefresh", DefaultNoRefreshURLPath, "")
+       RefreshURLPath   = flag.String("refresh", DefaultRefreshURLPath, "")
+       GPGUpdateURLPath = flag.String("gpgupdate", DefaultGPGUpdateURLPath, "")
+       JSONURLPath      = flag.String("json", DefaultJSONURLPath, "")
 
-       PyPIURL      = flag.String("pypi", "https://pypi.org/simple/", "Upstream (PyPI) URL")
-       PyPICertHash = flag.String("pypi-cert-hash", "", "Authenticate upstream by its X.509 certificate's SPKI SHA256 hash")
-       JSONURL      = flag.String("pypi-json", "https://pypi.org/pypi/", "Enable and use specified JSON API upstream URL")
+       PyPIURL      = flag.String("pypi", DefaultPyPIURL, "")
+       JSONURL      = flag.String("pypi-json", DefaultJSONURL, "")
+       PyPICertHash = flag.String("pypi-cert-hash", "", "")
 
-       PasswdPath     = flag.String("passwd", "", "Path to FIFO for upload authentication")
-       PasswdListPath = flag.String("passwd-list", "", "Path to FIFO for login listing")
-       PasswdCheck    = flag.Bool("passwd-check", false, "Run password checker")
+       PasswdPath     = flag.String("passwd", "", "")
+       PasswdListPath = flag.String("passwd-list", "", "")
+       PasswdCheck    = flag.Bool("passwd-check", false, "")
 
-       LogTimestamped = flag.Bool("log-timestamped", false, "Prepend timestmap to log messages")
-       FSCK           = flag.Bool("fsck", false, "Check integrity of all packages (errors are in stderr)")
-       DoVersion      = flag.Bool("version", false, "Print version information")
-       DoWarranty     = flag.Bool("warranty", false, "Print warranty information")
+       LogTimestamped = flag.Bool("log-timestamped", false, "")
+       FSCK           = flag.Bool("fsck", false, "")
+       DoVersion      = flag.Bool("version", false, "")
+       DoWarranty     = flag.Bool("warranty", false, "")
 
        Killed bool
 )
 
 func servePkg(w http.ResponseWriter, r *http.Request, pkgName, filename string) {
        log.Println(r.RemoteAddr, "get", filename)
-       path := filepath.Join(*Root, pkgName, filename)
+       path := filepath.Join(Root, pkgName, filename)
        if _, err := os.Stat(path); os.IsNotExist(err) {
                if !refreshDir(w, r, pkgName, filename, false) {
                        return
@@ -143,6 +131,7 @@ func handler(w http.ResponseWriter, r *http.Request) {
 }
 
 func main() {
+       flag.Usage = usage
        flag.Parse()
        if *DoWarranty {
                fmt.Println(Warranty)
@@ -162,6 +151,15 @@ func main() {
                log.SetOutput(os.Stdout)
        }
 
+       if len(flag.Args()) != 1 {
+               usage()
+               os.Exit(1)
+       }
+       Root = flag.Args()[0]
+       if _, err := os.Stat(Root); err != nil {
+               log.Fatalln(err)
+       }
+
        if *FSCK {
                if !goodIntegrity() {
                        os.Exit(1)
@@ -287,11 +285,9 @@ func main() {
 
        log.Println(
                UserAgent, "ready:",
-               "root:", *Root,
+               "root:", Root,
                "bind:", *Bind,
                "pypi:", *PyPIURL,
-               "json:", *JSONURL,
-               "hr: /",
        )
        if *TLSCert == "" {
                err = server.Serve(ln)
index 67efe578d1c53891c42204c21c64fae11d63a488..b97d2becfac6b71ee10c8466179f496533211910 100644 (file)
@@ -85,11 +85,11 @@ func refreshDir(
        pkgName, filenameGet string,
        gpgUpdate bool,
 ) bool {
-       if _, err := os.Stat(filepath.Join(*Root, pkgName, InternalFlag)); err == nil {
+       if _, err := os.Stat(filepath.Join(Root, pkgName, InternalFlag)); err == nil {
                return true
        }
        c := http.Client{Transport: &PyPIHTTPTransport}
-       dirPath := filepath.Join(*Root, pkgName)
+       dirPath := filepath.Join(Root, pkgName)
        now := time.Now()
 
        var allReleases map[string][]*PkgReleaseInfo
index 669e414e81e07be2cd37fe12a1c427bcd20fd3c7..9ce55407e04021ae8644c99000aecd599d79407f 100644 (file)
--- a/upload.go
+++ b/upload.go
@@ -67,7 +67,7 @@ func serveUpload(w http.ResponseWriter, r *http.Request) {
                return
        }
        pkgName := strings.ToLower(NormalizationRe.ReplaceAllString(pkgNames[0], "-"))
-       dirPath := filepath.Join(*Root, pkgName)
+       dirPath := filepath.Join(Root, pkgName)
        gpgSigsExpected := make(map[string]struct{})
        now := time.Now().UTC()
 
diff --git a/usage.go b/usage.go
new file mode 100644 (file)
index 0000000..3959d6a
--- /dev/null
+++ b/usage.go
@@ -0,0 +1,94 @@
+/*
+GoCheese -- Python private package repository and caching proxy
+Copyright (C) 2019-2021 Sergey Matveev <stargrave@stargrave.org>
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package main
+
+import (
+       "fmt"
+       "os"
+)
+
+const (
+       DefaultBind             = "[::]:8080"
+       DefaultMaxClients       = 128
+       DefaultNoRefreshURLPath = "/norefresh/"
+       DefaultRefreshURLPath   = "/simple/"
+       DefaultGPGUpdateURLPath = "/gpgupdate/"
+       DefaultJSONURLPath      = "/pypi/"
+       DefaultPyPIURL          = "https://pypi.org/simple/"
+       DefaultJSONURL          = "https://pypi.org/pypi/"
+
+       Warranty = `This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 3 of the License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.`
+)
+
+func usage() {
+       fmt.Fprintf(os.Stderr, `Usage: gocheese [OPTIONS ...] /path/to/packages
+
+Network transport options:
+  -ucspi          -- Work as UCSPI-TCP service instead of listening
+  -bind HOST:PORT -- TCP address to bind to (default: %s)
+  -maxclients N   -- Maximal amount of simultaneous clients (default: %d)
+
+TLS enabling options:
+  -tls-cert PEM -- Path to TLS X.509 certificate
+  -tls-key PEM  -- Path to TLS X.509 private key
+
+HTTP endpoints:
+  -norefresh URLPATH -- Non-refreshing Simple API path (default: %s)
+  -refresh URLPATH   -- Auto-refreshing Simple API path (default: %s)
+  -gpgupdate URLPATH -- GPG forceful refreshing path (default: %s)
+  -json URLPATH      -- JSON API path (default: %s)
+
+Upstream PyPI:
+  -pypi URL      -- Upstream Simple API (default: %s)
+  -pypi-json URL -- Enable and use specified JSON API (default: %s)
+                    Disabled if empty.
+  -pypi-cert-hash HEX(SHA256(SPKI)) -- Authenticate upstream by its
+                                       X.509 certificate's hash
+Password management:
+  -passwd PATH      -- Path to readable FIFO for loading passwords
+  -passwd-list PATH -- Path to writeable FIFO for listing logins
+  -passwd-check     -- Verify passwords format from stdin, then exit
+
+Other options:
+  -log-timestamped -- Prepend timestamp to log messages
+  -fsck            -- Run integrity check of all packages
+  -version         -- Print version information
+  -warranty        -- Print warranty information
+
+GOCHEESE_NO_SYNC=1 environment variable disable filesystem fsyncs.
+`,
+               DefaultBind,
+               DefaultMaxClients,
+               DefaultNoRefreshURLPath,
+               DefaultRefreshURLPath,
+               DefaultGPGUpdateURLPath,
+               DefaultJSONURLPath,
+               DefaultPyPIURL,
+               DefaultJSONURLPath,
+       )
+}