@@ -5,7 +5,10 @@ import (
"context"
"flag"
"fmt"
+ "io"
"net"
+ "net/http"
+ "net/url"
"os"
"path/filepath"
"strings"
@@ -25,6 +28,7 @@ import (
"github.com/charmbracelet/soft-serve/server/store/database"
"github.com/charmbracelet/soft-serve/server/test"
"github.com/rogpeppe/go-internal/testscript"
+ "github.com/spf13/cobra"
"golang.org/x/crypto/ssh"
_ "modernc.org/sqlite" // sqlite Driver
)
@@ -55,6 +59,7 @@ func TestScript(t *testing.T) {
"soft": cmdSoft(admin1.Signer()),
"usoft": cmdSoft(user1.Signer()),
"git": cmdGit(key),
+ "curl": cmdCurl,
"mkfile": cmdMkfile,
"envfile": cmdEnvfile,
"readfile": cmdReadfile,
@@ -295,3 +300,90 @@ func cmdEnvfile(ts *testscript.TestScript, neg bool, args []string) {
ts.Setenv(key, strings.TrimSpace(ts.ReadFile(file)))
}
}
+
+func cmdCurl(ts *testscript.TestScript, neg bool, args []string) {
+ var verbose bool
+ var headers []string
+ var data string
+ method := http.MethodGet
+
+ cmd := &cobra.Command{
+ Use: "curl",
+ Args: cobra.MinimumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ url, err := url.Parse(args[0])
+ if err != nil {
+ return err
+ }
+
+ req, err := http.NewRequest(method, url.String(), nil)
+ if err != nil {
+ return err
+ }
+
+ if data != "" {
+ req.Body = io.NopCloser(strings.NewReader(data))
+ }
+
+ if verbose {
+ fmt.Fprintf(cmd.ErrOrStderr(), "< %s %s\n", req.Method, url.String())
+ }
+
+ for _, header := range headers {
+ parts := strings.SplitN(header, ":", 2)
+ if len(parts) != 2 {
+ return fmt.Errorf("invalid header: %s", header)
+ }
+ req.Header.Add(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]))
+ }
+
+ if userInfo := url.User; userInfo != nil {
+ password, _ := userInfo.Password()
+ req.SetBasicAuth(userInfo.Username(), password)
+ }
+
+ if verbose {
+ for key, values := range req.Header {
+ for _, value := range values {
+ fmt.Fprintf(cmd.ErrOrStderr(), "< %s: %s\n", key, value)
+ }
+ }
+ }
+
+ resp, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return err
+ }
+
+ if verbose {
+ fmt.Fprintf(ts.Stderr(), "> %s\n", resp.Status)
+ for key, values := range resp.Header {
+ for _, value := range values {
+ fmt.Fprintf(cmd.ErrOrStderr(), "> %s: %s\n", key, value)
+ }
+ }
+ }
+
+ defer resp.Body.Close()
+ buf, err := io.ReadAll(resp.Body)
+ if err != nil {
+ return err
+ }
+
+ cmd.Print(string(buf))
+
+ return nil
+ },
+ }
+
+ cmd.SetArgs(args)
+ cmd.SetOut(ts.Stdout())
+ cmd.SetErr(ts.Stderr())
+
+ cmd.Flags().BoolVarP(&verbose, "verbose", "v", verbose, "verbose")
+ cmd.Flags().StringArrayVarP(&headers, "header", "H", nil, "HTTP header")
+ cmd.Flags().StringVarP(&method, "request", "X", method, "HTTP method")
+ cmd.Flags().StringVarP(&data, "data", "d", data, "HTTP data")
+
+ check(ts, cmd.Execute(), neg)
+}
@@ -1,5 +1,8 @@
# vi: set ft=conf
+# FIXME: don't skip windows
+[windows] skip 'curl makes github actions hang'
+
# convert crlf to lf on windows
[windows] dos2unix http1.txt http2.txt http3.txt goget.txt gitclone.txt
@@ -36,70 +39,70 @@ git -C repo2 push origin HEAD
git -C repo2 push origin HEAD --tags
# dumb http git
-exec curl -s -XGET http://localhost:$HTTP_PORT/repo2.git/info/refs
+curl -XGET http://localhost:$HTTP_PORT/repo2.git/info/refs
stdout '[0-9a-z]{40} refs/heads/master\n[0-9a-z]{40} refs/tags/v0.1.0'
# http errors
-exec curl -s -XGET http://localhost:$HTTP_PORT/repo2111foobar.git/foo/bar
+curl -XGET http://localhost:$HTTP_PORT/repo2111foobar.git/foo/bar
stdout '404.*'
-exec curl -s -XGET http://localhost:$HTTP_PORT/repo2111/foobar.git/foo/bar
+curl -XGET http://localhost:$HTTP_PORT/repo2111/foobar.git/foo/bar
stdout '404.*'
-exec curl -s -XGET http://localhost:$HTTP_PORT/repo2.git/foo/bar
+curl -XGET http://localhost:$HTTP_PORT/repo2.git/foo/bar
stdout '404.*'
-exec curl -s -XPOST http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/foo
+curl -XPOST http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/foo
stdout '404.*'
-exec curl -s -XGET http://localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XGET http://localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*Method Not Allowed.*'
-exec curl -s -XPOST http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*Not Acceptable.*'
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*validation error.*'
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*no objects found.*'
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"download","transfers":["foo"]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"download","transfers":["foo"]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*unsupported transfer.*'
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"bar","objects":[{}]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"bar","objects":[{}]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*unsupported operation.*'
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"download","objects":[{}]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"download","objects":[{}]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
cmp stdout http1.txt
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"upload","objects":[{}]}' http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"upload","objects":[{}]}' http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*write access required.*'
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"upload","objects":[{}]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' -d '{"operation":"upload","objects":[{}]}' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
cmp stdout http1.txt
# go-get allow (public repo)
-exec curl -s http://localhost:$HTTP_PORT/repo2.git?go-get=1
+curl http://localhost:$HTTP_PORT/repo2.git?go-get=1
cmpenv stdout goget.txt
-exec curl -s http://localhost:$HTTP_PORT/repo2.git/subpackage?go-get=1
+curl http://localhost:$HTTP_PORT/repo2.git/subpackage?go-get=1
cmpenv stdout goget.txt
-exec curl -s http://localhost:$HTTP_PORT/repo2/subpackage?go-get=1
+curl http://localhost:$HTTP_PORT/repo2/subpackage?go-get=1
cmpenv stdout goget.txt
# go-get not found (invalid method)
-exec curl -s -XPOST http://localhost:$HTTP_PORT/repo2/subpackage?go-get=1
+curl -XPOST http://localhost:$HTTP_PORT/repo2/subpackage?go-get=1
stdout '404.*'
# set private
soft repo private repo2 true
# allow access private
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' http://$TOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
cmp stdout http2.txt
-exec curl -s -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' http://$ETOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl -XPOST -H 'Accept: application/vnd.git-lfs+json' -H 'Content-Type: application/vnd.git-lfs+json' http://$ETOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
cmp stdout http3.txt
# deny access private
-exec curl -s http://localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl http://localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*credentials needed.*'
-exec curl -s http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl http://$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
stdout '.*credentials needed.*'
-exec curl -s http://0$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
+curl http://0$UTOKEN@localhost:$HTTP_PORT/repo2.git/info/lfs/objects/batch
cmp stdout http3.txt
# deny dumb http git
-exec curl -s -XGET http://localhost:$HTTP_PORT/repo2.git/info/refs
+curl -XGET http://localhost:$HTTP_PORT/repo2.git/info/refs
stdout '404.*'
# deny access ask for credentials
@@ -111,19 +114,19 @@ cmpenv stderr gitclone.txt
stderr '.*403.*'
# go-get not found (private repo)
-exec curl -s http://localhost:$HTTP_PORT/repo2.git?go-get=1
+curl http://localhost:$HTTP_PORT/repo2.git?go-get=1
stdout '404.*'
# go-get forbidden (private repo & expired token)
-exec curl -s http://$ETOKEN@localhost:$HTTP_PORT/repo2.git?go-get=1
+curl http://$ETOKEN@localhost:$HTTP_PORT/repo2.git?go-get=1
stdout '403.*'
# go-get not found (private repo & different user)
-exec curl -s http://$UTOKEN@localhost:$HTTP_PORT/repo2.git?go-get=1
+curl http://$UTOKEN@localhost:$HTTP_PORT/repo2.git?go-get=1
stdout '404.*'
# go-get with creds
-exec curl -s http://$TOKEN@localhost:$HTTP_PORT/repo2.git?go-get=1
+curl http://$TOKEN@localhost:$HTTP_PORT/repo2.git?go-get=1
cmpenv stdout goget.txt
-- http1.txt --
@@ -1,7 +1,7 @@
# vi: set ft=conf
# convert crlf to lf on windows
-[windows] dos2unix tree.txt readme.md branch_list.1.txt info.txt
+[windows] dos2unix readme.md branch_list.1.txt info.txt
# create a repo
soft repo create repo1 -d 'description' -H -p -n 'repo11'
@@ -30,6 +30,7 @@ git -C repo1 push origin HEAD --tags
# create lfs files, use ssh git-lfs-transfer
git -C repo1 lfs install --local
git -C repo1 lfs track '*.png'
+git -C repo1 lfs track '*.mp4'
mkfile ./repo1/foo.png 'foo'
mkfile ./repo1/bar.png 'bar'
git -C repo1 add -A
@@ -51,7 +52,11 @@ soft repo tag list repo1
# print tree
soft repo tree repo1
-cmp stdout tree.txt
+cp stdout tree.txt
+grep '.gitattributes' tree.txt
+grep 'README.md' tree.txt
+grep 'foo.png' tree.txt
+grep 'bar.png' tree.txt
# cat blob
soft repo blob repo1 README.md
@@ -85,11 +90,6 @@ soft repo branch delete repo1 master
soft repo branch list repo1
stdout branch1
--- tree.txt --
--rw-r--r-- 42 B .gitattributes
--rw-r--r-- 14 B README.md
--rw-r--r-- 126 B bar.png
--rw-r--r-- 126 B foo.png
-- readme.md --
# Project\nfoo
-- branch_list.1.txt --