Skip to content

Commit 0bfc478

Browse files
committed
play: incorporate the playground into the main site
The playground was initially developed as a proof of concept over a weekend, in a separate repo/module. However, it has proved to be quite popular. The current situation involves a rather awkward "dance" of running scripts from the playground module within the cuelang.org main module. Having this additional dependency is unncessary, and introduces more development effort. Moving the playground code to the same repository helps eliminate a dependency, and hence the admin associated with maintaining that additional dependency. As part of some enhancements for the GerritHub -> GitHub setup for the main CUE repositroy, we need to establish a new serverless function. By eliminating the playground dependency and housing the code alongside the cuelang.org site, we can simplify our approach to serverless functions, making the addition of future serverless functions easier, including that required to improve the GerritHub -> GitHub setup. This change is incorporates the playground alongside the cuelang.org site. The contents of play/ very closely mirror the contents of github.com/cue-sh/[email protected]. We detail exceptions below. There is still tidy up that can be done, but in the interests of making minimal changes to the playground code, that is deferred for a later date. * .gitignore and .gitattributes files from both repositories have been consolidated. * The GitHub test workflow from both repositories have been combined. * /serve.sh is added to make it easier to locally serve the cuelang.org Hugo site. * /play/run.sh is added to make it easier to locally serve the playground. * /build.sh is changed to reflect the fact the playground is no longer a dependency. * /play/README.md is identical to the playground source version, but for dropping the instructions on how to develop and run the playground locally, instructions which are now in /README.md * /play/dist.sh is slimmed down to reflect the code that was extracted to /play/run.sh. * /play/go.{mod,sum} are exact copies of the playground originals, but appear as diffs because /play/go.{mod,sum} existed before in order to capture the playground dependency separate from the cuelang.org dependencies. This previously allowed the playground to depend on a different version of CUE to the main cuelang.org site. This separation remains now the playground is incorporated with the main cuelang.org site for the same reason. * /play/package.json is changed slightly to drop the "serve" command for the playground in favour of "watch". Because with the playground incorporated into the cuelang.org repo, the hugo command serves the site and playground. Hence the watch command allows for hot-reload-like behaviour of the playground portion. * /play/tools.go is deleted; this was previously used to declare the dependency on the playground module. * /play/webpack.config.js is updated from the playground original to alter the distRoot. * The cuelang.org README is updated to reflect how to develop and run the entire site locally, including the playground. Further tidy up is captured in cue-lang#253. For reference, the diff between the playground repo at 4c9bd3cf5202 and the play directory in this commit is: Only in /home/myitcv/cue/playground/: .git Only in /home/myitcv/cue/playground/: .gitattributes Only in /home/myitcv/cue/playground/: .github Only in /home/myitcv/cue/playground/: .gitignore Only in /home/myitcv/cue/playground/: LICENSE diff -ruw /home/myitcv/cue/playground/README.md ./play/README.md --- /home/myitcv/cue/playground/README.md 2021-11-22 12:33:13.436985000 +0000 +++ ./play/README.md 2022-07-05 19:41:07.728977874 +0100 @@ -20,16 +20,6 @@ The output is the JSON-marshalled result of the CUE input. -### Developing locally - -To develop the application locally, within the `play` directory at the repo root: - -```bash -# Running dist.sh outside of the netlify environment works in a "dev" -# mode which ultimately results in running npm run serve -./dist.sh -``` - ### Details * The TypeScript single-page application entry point is `src/index.tsx` diff -ruw /home/myitcv/cue/playground/dist.sh ./play/dist.sh --- /home/myitcv/cue/playground/dist.sh 2022-07-05 09:28:18.932827261 +0100 +++ ./play/dist.sh 2022-07-12 05:35:19.806465471 +0100 @@ -15,12 +15,6 @@ # be a cache directory # * CUELANG_ORG_DIST - the directory into which we should run dist -if [ "${NETLIFY:-}" != "true" ] -then - trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT - echo "running in 'dev' mode" -fi - # cd to the directory containing the script cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" @@ -48,27 +42,13 @@ rsync -a node_modules/ $NETLIFY_BUILD_BASE/cache/playground_node_modules fi -if [ "${NETLIFY:-}" == "true" ] -then # Dist echo "Install serverless functions" go install -tags netlify github.com/cue-sh/playground/functions/snippets -else - echo "Running serverless functions (background)" - go run github.com/cue-sh/playground/functions/snippets >/dev/null 2>&1 & -fi echo "Building WASM backend" GOOS=js GOARCH=wasm go build -o main.wasm cp $(go env GOROOT)/misc/wasm/wasm_exec.js ./src - -if [ "${NETLIFY:-}" == "true" ] -then echo "Running dist into $CUELANG_ORG_DIST" npm run dist -else - echo "Running npm run serve" - npm run serve -fi - diff -ruw /home/myitcv/cue/playground/package.json ./play/package.json --- /home/myitcv/cue/playground/package.json 2022-07-05 20:38:34.100123583 +0100 +++ ./play/package.json 2022-07-05 14:08:15.559549887 +0100 @@ -31,6 +31,6 @@ "name": "CUEplayground", "scripts": { "dist": "webpack --mode production", - "serve": "webpack serve --mode development --open --hot --host 0.0.0.0" + "watch": "webpack watch --mode development" } } Only in ./play/: run.sh diff -ruw /home/myitcv/cue/playground/webpack.config.js ./play/webpack.config.js --- /home/myitcv/cue/playground/webpack.config.js 2022-07-05 20:38:34.100123583 +0100 +++ ./play/webpack.config.js 2022-07-12 05:35:19.810465740 +0100 @@ -2,7 +2,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); -let distRoot = __dirname; +let distRoot = path.join(__dirname, ".."); if (process.env.NETLIFY == "true") { if (process.env.CUELANG_ORG_DIST == "") { Signed-off-by: Paul Jolly <[email protected]>
1 parent 921474b commit 0bfc478

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+24885
-42
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/content/en/docs/tutorials/kubernetes.md linguist-generated
22
/content/en/pkg.go.dev.md linguist-generated
3+
/play/internal/cuelang_org_go_internal/**/* linguist-generated
34

.github/workflows/test.yml

+27-2
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,48 @@ jobs:
1414
steps:
1515
- name: Checkout code
1616
uses: actions/checkout@v2
17+
- name: Install Node
18+
uses: actions/setup-node@v2
19+
with:
20+
node-version: '16.14.2'
1721
- name: Install Go
1822
uses: actions/setup-go@v2
1923
with:
20-
go-version: '1.17.3'
24+
go-version: '1.18.1'
2125
- name: Ensure latest CUE
2226
# The latest git clean check ensures that this call is effectively
2327
# side effect-free. Using GOPROXY=direct ensures we don't accidentally
2428
# hit a stale cache in the proxy.
2529
run: |
2630
GOPROXY=direct go get -d cuelang.org/go@latest
31+
go mod tidy
2732
cd play
28-
GOPROXY=direct go get -d github.com/cue-sh/playground@latest
33+
GOPROXY=direct go get -d cuelang.org/go@latest
34+
go mod tidy
35+
- name: Re-vendor play
36+
run: ./_scripts/revendorToolsInternal.sh
37+
working-directory: ./play
2938
- name: Regenerate
3039
run: go generate ./...
40+
- name: Regenerate play
41+
run: go generate $(go list ./... | grep -v cuelang_org_go_internal)
42+
working-directory: ./play
3143
- name: Test
3244
run: go test ./...
45+
- name: Test play dist
46+
run: NETLIFY=true NETLIFY_BUILD_BASE=$(mktemp -d) CUELANG_ORG_DIST=$(mktemp -d) bash dist.sh
47+
working-directory: ./play
3348
- name: Check module is tidy
3449
run: go mod tidy
50+
- name: Check play module is tidy
51+
run: go mod tidy
52+
working-directory: ./play
3553
- name: Verify commit is clean
3654
run: test -z "$(git status --porcelain)" || (git status; git diff; false)
55+
- name: Test play dist at tip
56+
# Note we intentially run this after the porcelain check because
57+
# this step intentionally updates the play/go.{mod,sum}. This step
58+
# purely exists to exercise this code path and determine whether it
59+
# passes/fails.
60+
run: NETLIFY=true NETLIFY_BUILD_BASE=$(mktemp -d) CUELANG_ORG_DIST=$(mktemp -d) BRANCH=tip bash dist.sh
61+
working-directory: ./play

.gitignore

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
_public/
2-
node_modules/
3-
resources/
4-
content/en/docs/references/spec.md
5-
content/en/docs/tutorials/tour/*/*.md
6-
!content/en/docs/tutorials/tour/*/_index.md
1+
/_public/
2+
/node_modules/
3+
/resources/
4+
/content/en/docs/references/spec.md
5+
/content/en/docs/tutorials/tour/*/*.md
6+
!/content/en/docs/tutorials/tour/*/_index.md
77
/_functions
88
/play/mod
99
/play/moddownload/
10+
/play/node_modules/
11+
/play/src/wasm_exec.js
12+
/play/*.wasm
1013
/.hugo_build.lock

README.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ git submodule update -f --init --recursive
2424

2525
# Install Hugo's Node requirements
2626
npm install
27+
```
2728

28-
# Generate the language spec and tour
29-
go generate ./...
29+
To serve the site locally run:
3030

31-
# Serve (with auto-reload)
32-
hugo serve -D
31+
```
32+
./serve.sh # In one terminal
33+
./play/run.sh # In another terminal
3334
```
3435

3536
### Updating the language spec and tour for cuelang.org

build.sh

+1-11
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@ then
2222
# Now force cuelang.org/go through the proxy so that the /pkg.go.dev redirect works
2323
go get -d cuelang.org/go@$(go list -m -f={{.Version}} cuelang.org/go)
2424
go mod tidy
25-
26-
# Update the playground. The dist.sh script run below upgrades to the tip of
27-
# CUE
28-
cd play
29-
GOPROXY=direct go get -d github.com/cue-sh/playground@main
30-
cd ..
3125
fi
3226

3327
# Main site
@@ -44,8 +38,4 @@ if [ "$modCache" = "" ]
4438
then
4539
modCache=${GOPATH%%:*}/pkg/mod
4640
fi
47-
cd play
48-
go mod download
49-
mkdir moddownload
50-
unzip -d moddownload $modCache/cache/download/$(go list -m -f={{.Path}}/@v/{{.Version}} github.com/cue-sh/playground).zip
51-
bash moddownload/$(go list -m -f={{.Path}}@{{.Version}} github.com/cue-sh/playground)/dist.sh
41+
bash play/dist.sh

play/README.md

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
## CUE Playground
2+
3+
The CUE Playground is a [TypeScript](https://www.typescriptlang.org/) application that is backed by a [WASM-compiled
4+
Go](https://github.com/golang/go/wiki/WebAssembly) application. [React](https://reactjs.org/) is used to render the UI,
5+
with [Bootstrap](https://getbootstrap.com/) providing the styling.
6+
7+
For now we use a simple three-pane UI:
8+
9+
```
10+
+------------------------------------------------------------------+
11+
| |
12+
| Header |
13+
| |
14+
+---------------------------------+--------------------------------+
15+
| | |
16+
| Input | Output |
17+
| | |
18+
+---------------------------------+--------------------------------+
19+
```
20+
21+
The output is the JSON-marshalled result of the CUE input.
22+
23+
### Details
24+
25+
* The TypeScript single-page application entry point is `src/index.tsx`
26+
* The entire application runs via a [Webpack](https://webpack.js.org/) pipeline
27+
* ...
28+
29+
### Requirements for local development
30+
31+
* [NodeJS](https://nodejs.org/) `>= v12.14.1`
32+
* [Go](https://golang.org/dl/) (stable version)
33+
34+
### TODO
35+
36+
* UI/UX
37+
* Support `fmt` and `trim` dropdown button option for the input pane contents
38+
* Support `txtar` input that then gets used as an overlay
39+
* Extend input dropdown to support different types of input (CUE, JSON, Yaml, Go)
40+
* Extend output dropdown modes
41+
* Development improvements
42+
* Integrate automatic recompilation of `main.wasm` into the webpack watch pipeline
43+
* Ensure, via GitHub Action checks, that `.go` and `.tsx` files are formatted
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
3+
set -eux
4+
5+
# Change the running directory when revendoring internal parts of CUE. Note we
6+
# cannot use the git root directory here, because we might be running this
7+
# script from its location inside the Go module cache (at least this is how it
8+
# is used from the cuelang.org repo).
9+
command cd "$( command cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/.."
10+
11+
go mod download
12+
path="cuelang.org/go"
13+
version=$(go list -m -f={{.Version}} $path)
14+
15+
td=$(mktemp -d)
16+
trap "rm -rf $td" EXIT
17+
18+
pushd $td > /dev/null
19+
modCache=$(go env GOMODCACHE)
20+
if [ "$modCache" = "" ]
21+
then
22+
modCache=${GOPATH%%:*}/pkg/mod
23+
fi
24+
unzip -q $modCache/cache/download/$path/@v/$version.zip
25+
popd > /dev/null
26+
27+
regex='s+cuelang.org/go/internal+github.com/cue-sh/playground/internal/cuelang_org_go_internal+g'
28+
29+
for i in "" filetypes encoding third_party/yaml
30+
do
31+
rsync -a --relative --delete $td/$path@$version/internal/./$i/ ./internal/cuelang_org_go_internal/
32+
find ./internal/cuelang_org_go_internal/$i -mindepth 1 -maxdepth 1 -type d -exec rm -rf {} +
33+
done
34+
35+
find ./internal/cuelang_org_go_internal -name "*.go" -exec sed -i $regex {} +
36+
find ./internal/cuelang_org_go_internal/ -name "*_test.go" -exec rm {} +
37+
cp $td/$path@$version/LICENSE ./internal/cuelang_org_go_internal
38+
39+
# 2022-02-09 - at the time of writing CUE tip causes
40+
# a plain go mod tidy in the playground to fail because
41+
# go1.16 would select one version, and go1.17 another.
42+
# So we keep this extended form in place until we drop
43+
# support for go1.16
44+
go mod tidy -go=1.16 && go mod tidy -go=1.17

play/dist.sh

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env bash
2+
set -eux
3+
4+
# dist.sh is used by netlify when deploying the CUE playground within the wider
5+
# cuelang.org site. It will, therefore, be run with a working directory that is
6+
# within the module cache. Given we need to run npm install etc, this will fail
7+
# because in this context all files/directories are read-only. Hence we make a
8+
# copy of "ourselves" to a temp directory, make that writable, then run through
9+
# all our dist steps.
10+
#
11+
# This script expects the following environment variables to have been set:
12+
#
13+
# * GOBIN - the target for serverless functions
14+
# * NETLIFY_BUILD_BASE - the root of the netlify build, within which there will
15+
# be a cache directory
16+
# * CUELANG_ORG_DIST - the directory into which we should run dist
17+
18+
# cd to the directory containing the script
19+
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
20+
21+
if [ "${NETLIFY:-}" == "true" ] && [ "${BRANCH:-}" == "tip" ]
22+
then
23+
# We need to update our dependencies (as the main module)
24+
# to the tip of CUE
25+
go get -d cuelang.org/go@master
26+
bash ./_scripts/revendorToolsInternal.sh
27+
go generate $(go list ./... | grep -v cuelang_org_go_internal)
28+
fi
29+
30+
if [ "${NETLIFY:-}" == "true" ]
31+
then
32+
# Use the cache of playground node_modules
33+
mkdir -p $NETLIFY_BUILD_BASE/cache/playground_node_modules
34+
rsync -a $NETLIFY_BUILD_BASE/cache/playground_node_modules/ node_modules
35+
fi
36+
37+
npm install
38+
39+
if [ "${NETLIFY:-}" == "true" ]
40+
then
41+
npm rebuild node-sass
42+
rsync -a node_modules/ $NETLIFY_BUILD_BASE/cache/playground_node_modules
43+
fi
44+
45+
# Dist
46+
echo "Install serverless functions"
47+
go install -tags netlify github.com/cue-sh/playground/functions/snippets
48+
49+
echo "Building WASM backend"
50+
GOOS=js GOARCH=wasm go build -o main.wasm
51+
cp $(go env GOROOT)/misc/wasm/wasm_exec.js ./src
52+
53+
echo "Running dist into $CUELANG_ORG_DIST"
54+
npm run dist

play/functions/snippets/main.go

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright 2020 The CUE Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package main
16+
17+
import (
18+
"fmt"
19+
"io"
20+
"net/http"
21+
)
22+
23+
const userAgent = "cuelang.org/play/ playground snippet fetcher"
24+
25+
func handle(w http.ResponseWriter, r *http.Request) {
26+
cors(w)
27+
f := func(format string, args ...interface{}) {
28+
fmt.Fprintf(w, format, args...)
29+
}
30+
client := &http.Client{}
31+
if r.Method == "POST" {
32+
// Share
33+
url := fmt.Sprintf("https://play.golang.org/share")
34+
req, err := http.NewRequest("POST", url, nil)
35+
if err != nil {
36+
w.WriteHeader(http.StatusInternalServerError)
37+
f("Failed to create onwards GET URL: %v", err)
38+
return
39+
}
40+
req.Header.Add("User-Agent", userAgent)
41+
req.Body = r.Body
42+
resp, err := client.Do(req)
43+
if err != nil {
44+
w.WriteHeader(http.StatusInternalServerError)
45+
f("Failed in onward request: %v", err)
46+
return
47+
}
48+
io.Copy(w, resp.Body)
49+
} else {
50+
// Retrieve via the parameter id
51+
url := fmt.Sprintf("https://play.golang.org/p/%v.go", r.FormValue("id"))
52+
req, err := http.NewRequest("GET", url, nil)
53+
if err != nil {
54+
w.WriteHeader(http.StatusInternalServerError)
55+
f("Failed to create onwards GET URL: %v", err)
56+
return
57+
}
58+
req.Header.Add("User-Agent", userAgent)
59+
resp, err := client.Do(req)
60+
if err != nil {
61+
w.WriteHeader(http.StatusInternalServerError)
62+
f("Failed in onward request: %v", err)
63+
return
64+
}
65+
io.Copy(w, resp.Body)
66+
}
67+
}
68+
69+
func main() {
70+
http.HandleFunc("/.netlify/functions/snippets", handle)
71+
serve()
72+
}
+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2020 The CUE Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//go:build !netlify
16+
// +build !netlify
17+
18+
package main
19+
20+
import (
21+
"log"
22+
"net/http"
23+
)
24+
25+
func serve() {
26+
log.Fatal(http.ListenAndServe(":8081", nil))
27+
}
28+
29+
func cors(w http.ResponseWriter) {
30+
w.Header().Set("Access-Control-Allow-Origin", "*")
31+
}
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2020 The CUE Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
//go:build netlify
16+
// +build netlify
17+
18+
package main
19+
20+
import (
21+
"log"
22+
"net/http"
23+
24+
"github.com/apex/gateway"
25+
)
26+
27+
func serve() {
28+
log.Fatal(gateway.ListenAndServe(":8080", nil))
29+
}
30+
31+
func cors(w http.ResponseWriter) {
32+
}

0 commit comments

Comments
 (0)