Skip to content

Commit

Permalink
chore: make UI dev easier (#1478)
Browse files Browse the repository at this point in the history
* chore: generate index.html

* chore: add index.html to .gitignore

* chore: error msgs; dont clean cache

* chore: go workspace

* chore: add instructions after build

* chore: update Develoment.md

* chore: add back ui/index.html for passing dev build

* chore: re-add index.html to .gitignore
  • Loading branch information
markphelps authored Apr 10, 2023
1 parent be09e4e commit f81670c
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 158 deletions.
2 changes: 1 addition & 1 deletion DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Before starting, make sure you have the following installed:
1. Clone this repo: `git clone https://github.com/flipt-io/flipt`
1. Run `mage bootstrap` to install required development tools. See [#bootstrap](#bootstrap) below.
1. Run `mage test` to execute the test suite
1. Run `mage build` to build the binary with embedded assets.
1. Run `mage` to build the binary with embedded assets.
1. Run `mage -l` to see a full list of possible commands

## Go
Expand Down
74 changes: 1 addition & 73 deletions go.work.sum

Large diffs are not rendered by default.

140 changes: 88 additions & 52 deletions magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ package main

import (
"fmt"
"html/template"
"os"
"os/exec"
"path/filepath"
"time"

"github.com/fatih/color"
"github.com/magefile/mage/mg"
"github.com/magefile/mage/sh"
)
Expand Down Expand Up @@ -47,7 +49,7 @@ func Bench() error {
func Bootstrap() error {
fmt.Println("Bootstrapping tools...")
if err := os.MkdirAll("_tools", 0755); err != nil {
return fmt.Errorf("failed to create dir: %w", err)
return fmt.Errorf("creating dir: %w", err)
}

// create module if go.mod doesnt exist
Expand All @@ -73,15 +75,16 @@ func Bootstrap() error {

// Build builds the project similar to a release build
func Build() error {
mg.Deps(Prep)
mg.Deps(Clean)
fmt.Println("Building...")

if err := build([]string{"-tags", "assets"}...); err != nil {
if err := build(buildModeProd); err != nil {
return err
}

fmt.Println("Done.")
fmt.Println("Run `./bin/flipt [--config config/local.yml]` to start Flipt")
fmt.Printf("\nRun the following to start Flipt:\n")
fmt.Printf("\n%v\n", color.CyanString(`./bin/flipt --config config/local.yml`))
return nil
}

Expand All @@ -90,24 +93,96 @@ func Dev() error {
mg.Deps(Clean)
fmt.Println("Building...")

if err := build(); err != nil {
if err := build(buildModeDev); err != nil {
return err
}

fmt.Println("Done.")
fmt.Println("Run `./bin/flipt [--config config/local.yml]` to start Flipt")
fmt.Printf("\nRun the following to start Flipt server:\n")
fmt.Printf("\n%v\n", color.CyanString(`./bin/flipt --config config/local.yml`))
fmt.Printf("\nIn another shell, run the following to start the UI in dev mode:\n")
fmt.Printf("\n%v\n", color.CyanString(`cd ui && npm run dev`))
return nil
}

func build(args ...string) error {
type buildMode uint8

const (
// buildModeDev builds the project for development, without bundling assets
buildModeDev buildMode = iota
// BuildModeProd builds the project similar to a release build
buildModeProd
)

func ui(mode buildMode) error {
// use template to determine if we should inject dev scripts
// required to proxy to vite dev server
// see: https://vitejs.dev/guide/backend-integration.html
tmplt := template.Must(template.ParseFiles("ui/index.html.tmpl"))

v := struct {
IsDev bool
}{
IsDev: mode == buildModeDev,
}

f, err := os.Create(filepath.Join("ui", "index.html"))
if err != nil {
return fmt.Errorf("creating file: %w", err)
}

if err := tmplt.Execute(f, v); err != nil {
return fmt.Errorf("executing template: %w", err)
}

if err := f.Close(); err != nil {
return fmt.Errorf("closing file: %w", err)
}

if mode == buildModeDev {
return nil
}

fmt.Println("Installing UI deps...")

// TODO: only install if package.json has changed
cmd := exec.Command("npm", "ci")
cmd.Dir = "ui"
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
return fmt.Errorf("installing UI deps: %w", err)
}

fmt.Println("Generating assets...")

cmd = exec.Command("npm", "run", "build")
cmd.Dir = "ui"
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

return cmd.Run()
}

func build(mode buildMode) error {
if err := ui(mode); err != nil {
return fmt.Errorf("build UI: %w", err)
}

buildDate := time.Now().UTC().Format(time.RFC3339)
buildArgs := make([]string, 0)

switch mode {
case buildModeProd:
buildArgs = append(buildArgs, "-tags", "assets")
}

gitCommit, err := sh.Output("git", "rev-parse", "HEAD")
if err != nil {
return fmt.Errorf("failed to get git commit: %w", err)
return fmt.Errorf("getting git commit: %w", err)
}

buildArgs := append([]string{"build", "-trimpath", "-ldflags", fmt.Sprintf("-X main.commit=%s -X main.date=%s", gitCommit, buildDate)}, args...)
buildArgs = append([]string{"build", "-trimpath", "-ldflags", fmt.Sprintf("-X main.commit=%s -X main.date=%s", gitCommit, buildDate)}, buildArgs...)
buildArgs = append(buildArgs, "-o", "./bin/flipt", "./cmd/flipt/")

return sh.RunV("go", buildArgs...)
Expand All @@ -118,17 +193,13 @@ func Clean() error {
fmt.Println("Cleaning...")

if err := sh.RunV("go", "mod", "tidy"); err != nil {
return fmt.Errorf("failed to tidy go.mod: %w", err)
}

if err := sh.RunV("go", "clean", "-i", "./..."); err != nil {
return fmt.Errorf("failed to clean cache: %w", err)
return fmt.Errorf("tidying go.mod: %w", err)
}

clean := []string{"dist/*", "pkg/*", "bin/*", "ui/dist"}
for _, dir := range clean {
if err := os.RemoveAll(dir); err != nil {
return fmt.Errorf("failed to remove dir %q: %w", dir, err)
return fmt.Errorf("removing dir %q: %w", dir, err)
}
}

Expand Down Expand Up @@ -157,7 +228,7 @@ func Fmt() error {
return filepath.Ext(path) == ".go"
})
if err != nil {
return fmt.Errorf("failed to find files: %w", err)
return fmt.Errorf("finding files: %w", err)
}

args := append([]string{"-w"}, files...)
Expand All @@ -169,20 +240,12 @@ func Lint() error {
fmt.Println("Linting...")

if err := sh.RunV("golangci-lint", "run"); err != nil {
return fmt.Errorf("failed to lint: %w", err)
return fmt.Errorf("linting: %w", err)
}

return sh.RunV("buf", "lint")
}

// Prep prepares the project for building
func Prep() error {
fmt.Println("Preparing...")
mg.Deps(Clean)
mg.Deps(UI.Build)
return nil
}

// Proto generates protobuf files and gRPC stubs
func Proto() error {
mg.Deps(Bootstrap)
Expand All @@ -205,33 +268,6 @@ func Test() error {
return sh.RunWithV(env, "go", "test", "-v", "-covermode=atomic", "-count=1", "-coverprofile=coverage.txt", "-timeout=60s", "./...")
}

type UI mg.Namespace

// Build generates UI assets
func (u UI) Build() error {
mg.Deps(u.Deps)
fmt.Println("Generating assets...")

cmd := exec.Command("npm", "run", "build")
cmd.Dir = "ui"
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

return cmd.Run()
}

// Deps installs UI deps
func (u UI) Deps() error {
fmt.Println("Installing UI deps...")

// TODO: only install if package.json has changed
cmd := exec.Command("npm", "ci")
cmd.Dir = "ui"
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}

// findFilesRecursive recursively traverses from the CWD and invokes the given
// match function on each regular file to determine if the given path should be
// returned as a match. It ignores files in .git directories.
Expand Down
3 changes: 3 additions & 0 deletions ui/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ dist-ssr
/test-results/
/playwright-report/
/playwright/.cache/

# Generated
index.html
2 changes: 1 addition & 1 deletion ui/dev.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package ui
import "embed"

var (
//go:embed dev.html
//go:embed index.html
UI embed.FS
Mount = "."
)
21 changes: 0 additions & 21 deletions ui/dev.html

This file was deleted.

35 changes: 25 additions & 10 deletions ui/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
<!DOCTYPE html>
<html lang="en" class="h-full w-auto bg-white">
<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Flipt</title>
</head>
<body class="h-full antialiased">
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Flipt</title>

<script type="module">
import RefreshRuntime from 'http://localhost:5173/@react-refresh';
RefreshRuntime.injectIntoGlobalHook(window);
window.$RefreshReg$ = () => { };
window.$RefreshSig$ = () => (type) => type;
window.__vite_plugin_react_preamble_installed__ = true;
</script>
<script type="module" src="http://localhost:5173/@vite/client"></script>

</head>

<body class="h-full antialiased">
<div id="root"></div>

<script type="module" src="http://localhost:5173/src/main.tsx"></script>

</body>

</html>
30 changes: 30 additions & 0 deletions ui/index.html.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en" class="h-full w-auto bg-white">

<head>
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Flipt</title>
{{if .IsDev}}
<script type="module">
import RefreshRuntime from 'http://localhost:5173/@react-refresh';
RefreshRuntime.injectIntoGlobalHook(window);
window.$RefreshReg$ = () => { };
window.$RefreshSig$ = () => (type) => type;
window.__vite_plugin_react_preamble_installed__ = true;
</script>
<script type="module" src="http://localhost:5173/@vite/client"></script>
{{end}}
</head>

<body class="h-full antialiased">
<div id="root"></div>
{{if .IsDev}}
<script type="module" src="http://localhost:5173/src/main.tsx"></script>
{{else}}
<script type="module" src="/src/main.tsx"></script>
{{end}}
</body>

</html>

0 comments on commit f81670c

Please sign in to comment.