From a8849b4dc60b682910aa6654f140a2788d290934 Mon Sep 17 00:00:00 2001 From: Brian Goff Date: Fri, 17 May 2024 00:30:58 +0000 Subject: [PATCH] Add method to easily spin up doc server This uses dagger to build the website and serve on a local port. Example usage: go -C ./website run . This will, by default, make the server available on port 3000. Signed-off-by: Brian Goff --- README.md | 20 +++++++++ website/go.mod | 26 ++++++++++++ website/go.sum | 55 ++++++++++++++++++++++++ website/main.go | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 website/go.mod create mode 100644 website/go.sum create mode 100644 website/main.go diff --git a/README.md b/README.md index df3cadccd..08b59694f 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,26 @@ targets: # ... ``` +## Docs + +Docs are available at [https://azure.github.io/dalec/](https://azure.github.io/dalec/). + + +### Building the docs + +You can view the docs locally by running: + +```console +$ go -C website run . +``` + +This will, by default, make the docs available on `http://localhost:3000/dalec/`. +You can customize the port with `--port `. + +```console +$ go -C website run . --port 3001 +``` + ## Contributing diff --git a/website/go.mod b/website/go.mod new file mode 100644 index 000000000..f482d2a63 --- /dev/null +++ b/website/go.mod @@ -0,0 +1,26 @@ +module github.com/Azure/dalec/website + +go 1.22.3 + +require ( + dagger.io/dagger v0.11.4 + github.com/pkg/errors v0.9.1 +) + +require ( + github.com/99designs/gqlgen v0.17.44 // indirect + github.com/Khan/genqlient v0.7.0 // indirect + github.com/adrg/xdg v0.4.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/sosodev/duration v1.2.0 // indirect + github.com/vektah/gqlparser/v2 v2.5.11 // indirect + go.opentelemetry.io/otel v1.24.0 // indirect + go.opentelemetry.io/otel/metric v1.24.0 // indirect + go.opentelemetry.io/otel/trace v1.24.0 // indirect + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.17.0 // indirect +) diff --git a/website/go.sum b/website/go.sum new file mode 100644 index 000000000..c0a687898 --- /dev/null +++ b/website/go.sum @@ -0,0 +1,55 @@ +dagger.io/dagger v0.11.4 h1:br81yt7S/KWrxieajFyzleOMBccevhi3TSSxmBp2lu0= +dagger.io/dagger v0.11.4/go.mod h1:YyHN9NpFZ0U70vLfGR9RQw1ppwxzXG7q/DPn7kn25Oc= +github.com/99designs/gqlgen v0.17.44 h1:OS2wLk/67Y+vXM75XHbwRnNYJcbuJd4OBL76RX3NQQA= +github.com/99designs/gqlgen v0.17.44/go.mod h1:UTCu3xpK2mLI5qcMNw+HKDiEL77it/1XtAjisC4sLwM= +github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= +github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= +github.com/adrg/xdg v0.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls= +github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sosodev/duration v1.2.0 h1:pqK/FLSjsAADWY74SyWDCjOcd5l7H8GSnnOGEB9A1Us= +github.com/sosodev/duration v1.2.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/vektah/gqlparser/v2 v2.5.11 h1:JJxLtXIoN7+3x6MBdtIP59TP1RANnY7pXOaDnADQSf8= +github.com/vektah/gqlparser/v2 v2.5.11/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/website/main.go b/website/main.go new file mode 100644 index 000000000..7370cc7dc --- /dev/null +++ b/website/main.go @@ -0,0 +1,108 @@ +package main + +import ( + "context" + "embed" + "flag" + "fmt" + "io/fs" + "os" + "os/signal" + "strconv" + "syscall" + "time" + + "dagger.io/dagger" + "github.com/pkg/errors" +) + +var ( + //go:embed static src docs *.js *.ts *.json yarn.lock + docsfs embed.FS +) + +func main() { + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) + defer cancel() + + portFl := flag.Int("port", 3000, "port to run the website on") + flag.Parse() + + go func() { + <-ctx.Done() + + <-time.After(30 * time.Second) + os.Exit(128 + int(syscall.SIGINT)) + }() + + client, err := dagger.Connect(ctx, dagger.WithLogOutput(os.Stderr)) + if err != nil { + panic(err) + } + + if err := website(ctx, client, *portFl); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func website(ctx context.Context, client *dagger.Client, port int) error { + defer client.Close() + client = client.Pipeline("website") + + docsDir, err := gofsToDagger(client) + if err != nil { + return errors.Wrap(err, "failed to create docs directory") + } + + base := client.Container().From("docker.io/library/node:22-bookworm") + + _, err = base. + WithDirectory("/website", docsDir). + WithWorkdir("/website"). + WithMountedCache("/website/node_modules", client.CacheVolume("node_modules")). + WithMountedCache("/root/.npm", client.CacheVolume("node-docusaurus-root")). + WithExec([]string{"npm", "install"}). + // Set the port in the container as well just so the port in the logs matches. + WithExec([]string{"yarn", "start", "--host=0.0.0.0", "--port=" + strconv.Itoa(port)}). + AsService(). + Up(ctx, dagger.ServiceUpOpts{ + Ports: []dagger.PortForward{ + {Backend: port, Frontend: port}, + }, + }) + + if err != nil { + return errors.Wrap(err, "failed to start website service") + } + + return nil +} + +func gofsToDagger(client *dagger.Client) (*dagger.Directory, error) { + root := client.Directory() + + err := fs.WalkDir(docsfs, ".", func(path string, entry fs.DirEntry, err error) error { + if err != nil { + return err + } + + info, err := entry.Info() + if err != nil { + return err + } + + if entry.IsDir() { + root = root.WithNewDirectory(path, dagger.DirectoryWithNewDirectoryOpts{Permissions: int(info.Mode().Perm())}) + return nil + } + + dt, err := docsfs.ReadFile(path) + if err != nil { + return err + } + root = root.WithNewFile(path, string(dt), dagger.DirectoryWithNewFileOpts{Permissions: int(info.Mode().Perm())}) + return nil + }) + return root, err +}