Skip to content

Commit

Permalink
writefs: add toml support
Browse files Browse the repository at this point in the history
DO NOT SUBMIT

Signed-off-by: Paul Jolly <[email protected]>
Change-Id: I361fb2547a9965ceb8d125b14f3d0d554ba78359
Dispatch-Trailer: {"type":"trybot","CL":1200710,"patchset":1,"ref":"refs/changes/10/1200710/1","targetBranch":"master"}
  • Loading branch information
myitcv authored and cueckoo committed Sep 5, 2024
1 parent d7a6535 commit 923b425
Show file tree
Hide file tree
Showing 6 changed files with 415 additions and 186 deletions.
98 changes: 45 additions & 53 deletions hugo/config/_default/params.toml
Original file line number Diff line number Diff line change
@@ -1,69 +1,61 @@
# Code generated site_tool.cue; DO NOT EDIT.
gcs_engine_id = '004591905419617723008:8rmik2a7xb3'
github_repo = 'https://github.com/cue-lang/cuelang.org'
images = ['img/social.png']
logo = 'svg/logo.svg'

# Site Params

# Fallback Twitter card image (if not set on page)
images = ["img/social.png"]

# Repository configuration (URLs for in-page links to opening issues and suggesting changes)
github_repo = "https://github.com/cue-lang/cuelang.org"

# Google Custom Search Engine ID. Remove or comment out to disable search.
gcs_engine_id = "004591905419617723008:8rmik2a7xb3"

# Which logo to use in main header
logo = "svg/logo.svg"

# Add a site-wide notification-bar
# Contents allows for markdown, leave out the button if you don't want a button
[notification]
type = 'cue-minor-release-v0.10'
content = '**CUE v0.10 is now available** -- learn more about its [new features and improvements](https://github.com/cue-lang/cue/releases/tag/v0.10.0)'
type = 'cue-minor-release-v0.10'

content = '**CUE v0.10 is now available** -- learn more about its [new features and improvements](https://github.com/cue-lang/cue/releases/tag/v0.10.0)'
[notification.button]
link = '/docs/introduction/installation/'
icon = 'download'
text = 'Install CUE'


# Tags
# The order of the tags in this file determines their relative positions
# on all rendered pages.
# Color can be one of: red, orange, green, pink, purple, lilac, blue, lavender
[notification.button]
icon = 'download'
link = '/docs/introduction/installation/'
text = 'Install CUE'

[[tags]]
name = "ecosystem"
color = "red"
color = 'red'
name = 'ecosystem'

[[tags]]
name = "encodings"
color = "green"
color = 'green'
name = 'encodings'

[[tags]]
name = "cue command"
color = "purple"
color = 'purple'
name = 'cue command'

[[tags]]
name = "language"
color = "blue"
color = 'blue'
name = 'language'

[[tags]]
name = "validation"
color = "lilac"
color = 'lilac'
name = 'validation'

[[tags]]
name = "tooling"
color = "orange"
color = 'orange'
name = 'tooling'

[[tags]]
name = "commented cue"
color = "pink"
color = 'pink'
name = 'commented cue'

[[tags]]
name = "user question"
color = "red"
color = 'red'
name = 'user question'

[[tags]]
name = "modules"
color = "red"
color = 'red'
name = 'modules'

[[tags]]
name = "go api"
color = "lavender"
color = 'lavender'
name = 'go api'

[[tags]]
name = "java api"
color = "blue"
color = 'blue'
name = 'java api'

[[tags]]
name = "workflow command"
color = "blue"
color = 'blue'
name = 'workflow command'
67 changes: 46 additions & 21 deletions internal/ci/ci.cue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
package ci

import (
"encoding/yaml"
"encoding/json"
"strings"

"github.com/cue-lang/cuelang.org/internal/ci/base"
Expand All @@ -27,38 +27,63 @@ import (
// #writefs mirrors the type of the arguments expected by
// internal/cmd/writefs
#writefs: {
Remove: [...string]
Create: [string]: {
Type: "symlink" | *"file"
Contents: *"" | string
// Tool is the name of the tool that generated the files declared in Create
Tool!: string

// Remove is the set of globs of filepaths to remove prior to Create
Remove?: [...string]

// Create is the set of files to create.
Create?: [filepath=string]: {
Type: "symlink"
Contents: string
} | *{
Type: "file"

// In case filepath has an extension known to CUE (and writefs), the
// concrete CUE value of Contents can be of any type. Otherwise, Contents
// must be a string.
Contents: _
}
}

fs: #writefs & {
Tool: "internal/ci/ci_tool.cue"

Remove: [
"../../.github/workflows/*.yaml",
]

Create: {
[_]: {
// TODO: do not hardcode this to ci_tool
let donotedit = base.doNotEditMessage & {#generatedBy: "internal/ci/ci_tool.cue", _}
_res: string
Contents: "# \(donotedit)\n\n\(strings.TrimSpace(_res))\n"
let donotedit = base.doNotEditMessage & {#generatedBy: "internal/ci/ci_tool.cue", _}

// GitHub workflows
let concreteWorkflows = json.Unmarshal(json.Marshal(github.workflows))
for _name, _workflow in concreteWorkflows {
"../../.github/workflows/\(_name).yaml": Contents: _workflow
}
for _name, _workflow in github.workflows {
"../../.github/workflows/\(_name).yaml": {
_res: yaml.Marshal(_workflow)
}

// Netlify config
"../../netlify.toml": Contents: _netlify.config

"../../hugo/layouts/index.redir": {
let contents = _netlify.#toRedirects & {#input: _netlify.config, _}
Contents: """
# \(donotedit)
\(strings.TrimSpace(contents))
"""
}

"../../codereview.cfg": {
_res: base.toCodeReviewCfg & {#input: repo.codeReview, _}
}
"../../netlify.toml": {
_res: _netlify.#toToml & {#input: _netlify.config, _}
}
"../../hugo/layouts/index.redir": {
_res: _netlify.#toRedirects & {#input: _netlify.config, _}
let contents = base.toCodeReviewCfg & {#input: repo.codeReview, _}
Contents: """
# \(donotedit)
\(strings.TrimSpace(contents))
"""
}
}
}
7 changes: 0 additions & 7 deletions internal/ci/github/workflows.cue
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,8 @@ workflows: close({
// [string]: json.#Workflow

_repo.trybotWorkflows

trybot: _
trybot_dispatch: #dummyDispatch: dummyDispatch
})

_linuxWorkflow: {
jobs: [string]: "runs-on": _repo.linuxMachine
}

dummyDispatch: _repo.#dispatch & {
type: _repo.trybot.key
}
81 changes: 59 additions & 22 deletions internal/cmd/writefs/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,31 @@ package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
)

type file struct {
Type string

// If typ == "symlink" this is the filepath of the target
// otherwise it is the Contents of the file
Contents string
// If typ == "symlink" the contents will be of type string and this is the
// filepath of the target.
//
// Otherwise it is the Contents of the file, in which case the type is
// whatever the contents of the JSON represented. If the extension of the
// file is .json or .toml, a filetype known to CUE then raw JSON is
// evaluated to the target filetype (a noop in the case of JSON) via
// cmd/cue. If the file extension is unknown, then the type must be string.
Contents json.RawMessage
}

type args struct {
// Tool is the name of the tool that initiated the writefs call
Tool string

// Remove is a list of globs of files to remove. File
// removal happens before file creation.
Remove []string
Expand Down Expand Up @@ -67,7 +78,12 @@ func main() {
}
switch f.Type {
case "symlink":
target := filepath.FromSlash(f.Contents)
// f.Contents must be a string
var contents string
if err := json.Unmarshal(f.Contents, &contents); err != nil {
log.Fatalf("%s: Type is symlink, but Contents not a string type", fp)
}
target := filepath.FromSlash(contents)
actualTarget, err := os.Readlink(fp)
if err == nil && actualTarget == target {
continue
Expand All @@ -76,26 +92,47 @@ func main() {
log.Fatalf("failed to symlink %s -> %s: %v", fp, target, err)
}
case "file":
// If we have a .json file, normalise the contents first
// as a special case.
//
// TODO: this actually belongs as an option in CUE.
contents := []byte(f.Contents)
if filepath.Ext(fp) == ".json" {
var i any
err := json.Unmarshal(contents, &i)
if err == nil {
var b bytes.Buffer
enc := json.NewEncoder(&b)
enc.SetEscapeHTML(false)
enc.SetIndent("", " ")
if err := enc.Encode(i); err == nil {
// Add a trailing newline
contents = b.Bytes()
}
var toWrite bytes.Buffer

// TODO: more principled checking of whether this filetype is known to
// CUE.

// TODO: parsing input JSON into a cue.Value, and properly prepending
// a comment with the "generated by" header. Also requires the filetype
// known to CUE to be able to export comments.

switch ext := filepath.Ext(fp); ext {
case ".json", ".yaml", ".toml":
filetype := ext[1:]
// Can be any type, just encode the JSON as TOML
// We have concrete JSON; export as TOML
in := bytes.NewReader(f.Contents)
var out bytes.Buffer
cmd := exec.Command("go", "run", "cuelang.org/go/cmd/cue", "export", "--out="+filetype, "json:", "-")
cmd.Stdin = in
cmd.Stdout = &out
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
log.Fatalf("failed to run %v: %v\n%s", cmd, err, out.Bytes())
}

// Gross: hack in a "code generated by" header for filetypes that support comments
//
// TODO: remove this gross hack
switch filetype {
case "yaml", "toml":
fmt.Fprintf(&toWrite, "# Code generated %s; DO NOT EDIT.\n\n", todo.Tool)
}
toWrite.Write(out.Bytes())
default:
// Must be string
var contents string
if err := json.Unmarshal(f.Contents, &contents); err != nil {
log.Fatalf("%s: unknown file type, Contents must be a string", fp)
}
toWrite.WriteString(contents)
}
if err := os.WriteFile(fp, []byte(contents), 0o666); err != nil {
if err := os.WriteFile(fp, toWrite.Bytes(), 0o666); err != nil {
log.Fatalf("failed to write file %s: %v", fp, err)
}
}
Expand Down
Loading

0 comments on commit 923b425

Please sign in to comment.