| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- //go:build !wasm
- // +build !wasm
- package app
- import (
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "os"
- "path/filepath"
- "strings"
- "github.com/maxence-charriere/go-app/v9/pkg/errors"
- )
- // GenerateStaticWebsite generates the files to run a PWA built with go-app as a
- // static website in the specified directory. Static websites can be used with
- // hosts such as Github Pages.
- //
- // Note that app.wasm must still be built separately and put into the web
- // directory.
- func GenerateStaticWebsite(dir string, h *Handler, pages ...string) error {
- if dir == "" {
- dir = "."
- }
- resources := map[string]struct{}{
- "/": {},
- "/wasm_exec.js": {},
- "/app.js": {},
- "/app-worker.js": {},
- "/manifest.webmanifest": {},
- "/app.css": {},
- "/web": {},
- }
- for path := range routes.routes {
- resources[path] = struct{}{}
- }
- for _, p := range pages {
- if p == "" {
- continue
- }
- if !strings.HasPrefix(p, "/") {
- p = "/" + p
- }
- resources[p] = struct{}{}
- }
- server := httptest.NewServer(h)
- defer server.Close()
- for path := range resources {
- switch path {
- case "/web":
- if err := createStaticDir(filepath.Join(dir, path), ""); err != nil {
- return errors.New("creating web directory failed").Wrap(err)
- }
- default:
- filename := path
- if filename == "/" {
- filename = "/index.html"
- }
- f, err := createStaticFile(dir, filename)
- if err != nil {
- return errors.New("creating file failed").
- Tag("path", path).
- Tag("filename", filename).
- Wrap(err)
- }
- defer f.Close()
- page, err := createStaticPage(server.URL + path)
- if err != nil {
- return errors.New("creating page failed").
- Tag("path", path).
- Tag("filename", filename).
- Wrap(err)
- }
- if n, err := f.Write(page); err != nil {
- return errors.New("writing page failed").
- Tag("path", path).
- Tag("filename", filename).
- Tag("bytes-written", n).
- Wrap(err)
- }
- }
- }
- return nil
- }
- func createStaticDir(dir, path string) error {
- dir = filepath.Join(dir, filepath.Dir(path))
- if _, err := os.Stat(dir); !os.IsNotExist(err) {
- return nil
- }
- return os.MkdirAll(filepath.Join(dir), 0755)
- }
- func createStaticFile(dir, path string) (*os.File, error) {
- if err := createStaticDir(dir, path); err != nil {
- return nil, errors.New("creating file directory failed").Wrap(err)
- }
- filename := filepath.Join(dir, path)
- if filepath.Ext(filename) == "" {
- filename += ".html"
- }
- return os.Create(filename)
- }
- func createStaticPage(path string) ([]byte, error) {
- req, err := http.NewRequest(http.MethodGet, path, nil)
- if err != nil {
- return nil, errors.New("creating http request failed").
- Tag("path", path).
- Wrap(err)
- }
- res, err := http.DefaultClient.Do(req)
- if err != nil {
- return nil, errors.New("http request failed").
- Tag("path", path).
- Wrap(err)
- }
- defer res.Body.Close()
- body, err := ioutil.ReadAll(res.Body)
- if err != nil {
- return nil, errors.New("reading request body failed").
- Tag("path", path).
- Wrap(err)
- }
- return body, nil
- }
|