Remove dependency on packr (#597)

* Embed files

* Build CLI

* Remove packr

* Embed view directory

* Embed static files

* Make view engine

* Populate build info
This commit is contained in:
Sung Won Cho 2022-05-09 20:34:23 +10:00 committed by GitHub
commit 5bba57fd29
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
67 changed files with 789 additions and 789 deletions

View file

@ -1,4 +1,3 @@
PACKR2 := $(shell command -v packr2 2> /dev/null)
NPM := $(shell command -v npm 2> /dev/null)
HUB := $(shell command -v hub 2> /dev/null)
@ -12,11 +11,6 @@ install: install-go install-js
.PHONY: install
install-go:
ifndef PACKR2
@echo "==> installing packr2"
@go get -u github.com/gobuffalo/packr/v2/packr2
endif
@echo "==> installing go dependencies"
@go mod download
.PHONY: install-go

54
go.mod
View file

@ -1,43 +1,47 @@
module github.com/dnote/dnote
go 1.13
go 1.17
require (
github.com/PuerkitoBio/goquery v1.6.0 // indirect
github.com/andybalholm/cascadia v1.2.0 // indirect
github.com/aymerick/douceur v0.2.0
github.com/dnote/actions v0.2.0
github.com/dnote/color v1.7.0
github.com/gobuffalo/packr/v2 v2.8.1
github.com/google/go-cmp v0.5.4
github.com/google/go-cmp v0.5.8
github.com/google/go-github v17.0.0+incompatible
github.com/google/uuid v1.1.3
github.com/gorilla/csrf v1.6.2
github.com/google/uuid v1.3.0
github.com/gorilla/csrf v1.7.1
github.com/gorilla/mux v1.8.0
github.com/gorilla/schema v1.2.0
github.com/jinzhu/gorm v1.9.16
github.com/joho/godotenv v1.3.0
github.com/karrick/godirwalk v1.16.1 // indirect
github.com/lib/pq v1.9.0
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-sqlite3 v1.14.6
github.com/nadproject/nad v0.0.0-20200124233812-f1a4e763ee2f
github.com/joho/godotenv v1.4.0
github.com/lib/pq v1.10.5
github.com/mattn/go-sqlite3 v1.14.12
github.com/pkg/errors v0.9.1
github.com/radovskyb/watcher v1.0.7
github.com/robfig/cron v1.2.0
github.com/rogpeppe/go-internal v1.6.2 // indirect
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351
github.com/rubenv/sql-migrate v1.1.1
github.com/sergi/go-diff v1.1.0
github.com/sirupsen/logrus v1.7.0 // indirect
github.com/spf13/cobra v1.1.1
github.com/yuin/goldmark v1.4.0
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a // indirect
golang.org/x/sys v0.0.0-20201231184435-2d18734c6014 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
github.com/spf13/cobra v1.4.0
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122
golang.org/x/time v0.0.0-20220411224347-583f2d630306
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/yaml.v2 v2.4.0
)
require (
github.com/PuerkitoBio/goquery v1.8.0 // indirect
github.com/andybalholm/cascadia v1.3.1 // indirect
github.com/go-gorp/gorp/v3 v3.0.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
golang.org/x/term v0.0.0-20220411215600-e5f449aeb171 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
)

765
go.sum

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ assert_http_status() {
fi
}
assert_http_status http://localhost:2300 "200"
assert_http_status http://localhost:2300/api/health "200"
assert_http_status http://localhost:2300 "302"
assert_http_status http://localhost:2300/health "200"
echo "======== [SUCCESS] TEST PASSED! ========"

View file

@ -1,3 +1,5 @@
//go:build linux || darwin
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
*
* This file is part of Dnote.
@ -15,7 +17,6 @@
* You should have received a copy of the GNU General Public License
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
*/
// +build linux darwin
package dirs

View file

@ -1,3 +1,5 @@
//go:build linux || darwin
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
*
* This file is part of Dnote.
@ -15,7 +17,6 @@
* You should have received a copy of the GNU General Public License
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
*/
// +build linux darwin
package dirs

View file

@ -1,3 +1,5 @@
//go:build windows
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
*
* This file is part of Dnote.
@ -16,8 +18,6 @@
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
*/
// +build windows
package dirs
import (

View file

@ -1,3 +1,5 @@
//go:build windows
/* Copyright (C) 2019, 2020, 2021 Monomax Software Pty Ltd
*
* This file is part of Dnote.
@ -16,8 +18,6 @@
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
*/
// +build windows
package dirs
import (

View file

@ -37,6 +37,8 @@ var (
ErrEmptyEmailTemplates = errors.New("No EmailTemplate store was provided")
// ErrEmptyEmailBackend is an error for missing EmailBackend content in the app configuration
ErrEmptyEmailBackend = errors.New("No EmailBackend was provided")
// ErrEmptyHTTP500Page is an error for missing HTTP 500 page content
ErrEmptyHTTP500Page = errors.New("No HTTP 500 error page was set")
)
// App is an application context
@ -47,6 +49,7 @@ type App struct {
EmailBackend mailer.Backend
Config config.Config
Files map[string][]byte
HTTP500Page []byte
}
// Validate validates the app configuration
@ -66,6 +69,9 @@ func (a *App) Validate() error {
if a.DB == nil {
return ErrEmptyDB
}
if a.HTTP500Page == nil {
return ErrEmptyHTTP500Page
}
return nil
}

View file

@ -20,7 +20,6 @@ package app
import (
"fmt"
"os"
"github.com/dnote/dnote/pkg/clock"
"github.com/dnote/dnote/pkg/server/config"
@ -30,16 +29,16 @@ import (
// NewTest returns an app for a testing environment
func NewTest(appParams *App) App {
emailTmplDir := os.Getenv("DNOTE_TEST_EMAIL_TEMPLATE_DIR")
c := config.Load()
c.SetOnPremise(false)
a := App{
DB: testutils.DB,
Clock: clock.NewMock(),
EmailTemplates: mailer.NewTemplates(&emailTmplDir),
EmailTemplates: mailer.NewTemplates(),
EmailBackend: &testutils.MockEmailbackendImplementation{},
Config: c,
HTTP500Page: []byte("<html></html>"),
}
// Allow to override with appParams
@ -61,9 +60,6 @@ func NewTest(appParams *App) App {
if appParams != nil && appParams.Config.DisableRegistration {
a.Config.DisableRegistration = appParams.Config.DisableRegistration
}
if appParams != nil && appParams.Config.PageTemplateDir != "" {
a.Config.PageTemplateDir = appParams.Config.PageTemplateDir
}
fmt.Printf("%+v\n", appParams)
fmt.Printf("%+v\n", a)

7
pkg/server/assets/.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
# Ignore CSS and JS files in static directory because
# those files are built from the sources
/static/*.css
/static/*.css.map
/static/*.js
/static/*.js.map

View file

@ -0,0 +1,31 @@
package assets
import (
"embed"
"github.com/pkg/errors"
"io/fs"
)
//go:embed static
var staticFiles embed.FS
// GetStaticFS returns a filesystem for static files, with
// all files situated in the root of the filesystem
func GetStaticFS() (fs.FS, error) {
subFs, err := fs.Sub(staticFiles, "static")
if err != nil {
return nil, errors.Wrap(err, "getting sub filesystem")
}
return subFs, nil
}
// MustGetHTTP500ErrorPage returns the content of HTML file for HTTP 500 error
func MustGetHTTP500ErrorPage() []byte {
ret, err := staticFiles.ReadFile("static/500.html")
if err != nil {
panic(errors.Wrap(err, "reading HTML file for 500 HTTP error"))
}
return ret
}

View file

@ -5,7 +5,7 @@ set -ex
dir=$(dirname "${BASH_SOURCE[0]}")
basePath="$dir/../../.."
serverDir="$dir/../.."
outputDir="$serverDir/static"
outputDir="$serverDir/assets/static"
inputDir="$dir/src"
task="cp $inputDir/main.js $outputDir"

View file

@ -4,7 +4,7 @@ set -ex
dir=$(dirname "${BASH_SOURCE[0]}")
serverDir="$dir/../.."
outputDir="$serverDir/static"
outputDir="$serverDir/assets/static"
inputDir="$dir/src"
rm -rf "${outputDir:?}/*"

View file

@ -20,9 +20,11 @@ package config
import (
"fmt"
"github.com/pkg/errors"
"net/url"
"os"
"github.com/dnote/dnote/pkg/server/assets"
"github.com/pkg/errors"
)
const (
@ -103,9 +105,8 @@ type Config struct {
DisableRegistration bool
Port string
DB PostgresConfig
PageTemplateDir string
StaticDir string
AssetBaseURL string
HTTP500Page []byte
}
func getAppEnv() string {
@ -133,6 +134,7 @@ func Load() Config {
DisableRegistration: readBoolEnv("DisableRegistration"),
DB: loadDBConfig(),
AssetBaseURL: "",
HTTP500Page: assets.MustGetHTTP500ErrorPage(),
}
if err := validate(c); err != nil {
@ -147,16 +149,6 @@ func (c *Config) SetOnPremise(val bool) {
c.OnPremise = val
}
// SetPageTemplateDir sets page template dir for the config
func (c *Config) SetPageTemplateDir(d string) {
c.PageTemplateDir = d
}
// SetStaticDir sets static dir for the confi
func (c *Config) SetStaticDir(d string) {
c.StaticDir = d
}
// SetAssetBaseURL sets static dir for the confi
func (c *Config) SetAssetBaseURL(d string) {
c.AssetBaseURL = d

View file

@ -40,10 +40,8 @@ func TestGetBooks(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -125,10 +123,8 @@ func TestGetBooksByName(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -188,10 +184,8 @@ func TestGetBook(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -248,10 +242,8 @@ func TestGetBookNonOwner(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -287,10 +279,8 @@ func TestCreateBook(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -347,10 +337,8 @@ func TestCreateBook(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -438,10 +426,8 @@ func TestUpdateBook(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -525,10 +511,8 @@ func TestDeleteBook(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()

View file

@ -2,7 +2,7 @@ package controllers
import (
"github.com/dnote/dnote/pkg/server/app"
"github.com/dnote/dnote/pkg/server/log"
"github.com/dnote/dnote/pkg/server/views"
)
// Controllers is a group of controllers
@ -16,16 +16,16 @@ type Controllers struct {
}
// New returns a new group of controllers
func New(app *app.App, baseDir string) *Controllers {
log.Info(app.Config.PageTemplateDir)
func New(app *app.App) *Controllers {
c := Controllers{}
c.Users = NewUsers(app, baseDir)
viewEngine := views.NewDefaultEngine()
c.Users = NewUsers(app, viewEngine)
c.Notes = NewNotes(app)
c.Books = NewBooks(app)
c.Sync = NewSync(app)
c.Static = NewStatic(app, baseDir)
c.Static = NewStatic(app, viewEngine)
c.Health = NewHealth(app)
return &c

View file

@ -32,9 +32,7 @@ func TestHealth(t *testing.T) {
defer testutils.ClearData(testutils.DB)
server := MustNewServer(t, &app.App{
Config: config.Config{
PageTemplateDir: "../views",
},
Config: config.Config{},
})
defer server.Close()

View file

@ -60,10 +60,8 @@ func TestGetNotes(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -177,10 +175,8 @@ func TestGetNote(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -376,10 +372,8 @@ func TestCreateNote(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -459,10 +453,8 @@ func TestDeleteNote(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -699,10 +691,8 @@ func TestUpdateNote(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()

View file

@ -4,6 +4,7 @@ import (
"net/http"
"github.com/dnote/dnote/pkg/server/app"
"github.com/dnote/dnote/pkg/server/assets"
mw "github.com/dnote/dnote/pkg/server/middleware"
"github.com/gorilla/mux"
"github.com/pkg/errors"
@ -109,7 +110,12 @@ func NewRouter(app *app.App, rc RouteConfig) (http.Handler, error) {
router.PathPrefix("/api/v2").Handler(mw.ApplyLimit(mw.NotSupported, true))
// static
staticHandler := http.StripPrefix("/static/", http.FileServer(http.Dir(app.Config.StaticDir)))
staticFs, err := assets.GetStaticFS()
if err != nil {
return nil, errors.Wrap(err, "getting the filesystem for static files")
}
staticHandler := http.StripPrefix("/static/", http.FileServer(http.FS(staticFs)))
router.PathPrefix("/static/").Handler(staticHandler)
router.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) {

View file

@ -57,10 +57,8 @@ func TestNotSupportedVersions(t *testing.T) {
// setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()

View file

@ -9,9 +9,9 @@ import (
)
// NewStatic creates a new Static controller.
func NewStatic(app *app.App, baseDir string) *Static {
func NewStatic(app *app.App, viewEngine *views.Engine) *Static {
return &Static{
NotFoundView: views.NewView(baseDir, app, views.Config{Title: "Not Found", Layout: "base"}, "static/not_found"),
NotFoundView: viewEngine.NewView(app, views.Config{Title: "Not Found", Layout: "base"}, "static/not_found"),
}
}

View file

@ -40,7 +40,7 @@ func MustNewServer(t *testing.T, appParams *app.App) *httptest.Server {
func NewServer(appParams *app.App) (*httptest.Server, error) {
a := app.NewTest(appParams)
ctl := New(&a, a.Config.PageTemplateDir)
ctl := New(&a)
rc := RouteConfig{
WebRoutes: NewWebRoutes(&a, ctl),
APIRoutes: NewAPIRoutes(&a, ctl),

View file

@ -34,33 +34,33 @@ var commonHelpers = map[string]interface{}{
// NewUsers creates a new Users controller.
// It panics if the necessary templates are not parsed.
func NewUsers(app *app.App, baseDir string) *Users {
func NewUsers(app *app.App, viewEngine *views.Engine) *Users {
return &Users{
NewView: views.NewView(baseDir, app,
NewView: viewEngine.NewView(app,
views.Config{Title: "Join", Layout: "base", HelperFuncs: commonHelpers, AlertInBody: true},
"users/new",
),
LoginView: views.NewView(baseDir, app,
LoginView: viewEngine.NewView(app,
views.Config{Title: "Sign In", Layout: "base", HelperFuncs: commonHelpers, AlertInBody: true},
"users/login",
),
PasswordResetView: views.NewView(baseDir, app,
PasswordResetView: viewEngine.NewView(app,
views.Config{Title: "Reset Password", Layout: "base", HelperFuncs: commonHelpers, AlertInBody: true},
"users/password_reset",
),
PasswordResetConfirmView: views.NewView(baseDir, app,
PasswordResetConfirmView: viewEngine.NewView(app,
views.Config{Title: "Reset Password", Layout: "base", HelperFuncs: commonHelpers, AlertInBody: true},
"users/password_reset_confirm",
),
SettingView: views.NewView(baseDir, app,
SettingView: viewEngine.NewView(app,
views.Config{Layout: "base", HelperFuncs: commonHelpers, HeaderTemplate: "navbar"},
"users/settings",
),
AboutView: views.NewView(baseDir, app,
AboutView: viewEngine.NewView(app,
views.Config{Title: "About", Layout: "base", HelperFuncs: commonHelpers, HeaderTemplate: "navbar"},
"users/settings_about",
),
EmailVerificationView: views.NewView(baseDir, app,
EmailVerificationView: viewEngine.NewView(app,
views.Config{Layout: "base", HelperFuncs: commonHelpers, HeaderTemplate: "navbar"},
"users/email_verification",
),

View file

@ -99,8 +99,7 @@ func TestJoin(t *testing.T) {
Clock: clock.NewMock(),
EmailBackend: &emailBackend,
Config: config.Config{
OnPremise: tc.onPremise,
PageTemplateDir: "../views",
OnPremise: tc.onPremise,
},
})
defer server.Close()
@ -145,10 +144,8 @@ func TestJoinError(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -175,10 +172,8 @@ func TestJoinError(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -205,10 +200,8 @@ func TestJoinError(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -238,10 +231,8 @@ func TestJoinDuplicateEmail(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -281,7 +272,6 @@ func TestJoinDisabled(t *testing.T) {
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
DisableRegistration: true,
},
})
@ -312,10 +302,8 @@ func TestLogin(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
u := testutils.SetupUserData()
@ -374,10 +362,8 @@ func TestLogin(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
u := testutils.SetupUserData()
@ -415,10 +401,8 @@ func TestLogin(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -456,10 +440,8 @@ func TestLogin(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -490,10 +472,8 @@ func TestLogout(t *testing.T) {
setupLogoutTest := func(t *testing.T) (*httptest.Server, *database.Session, *database.Session) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
aliceUser := testutils.SetupUserData()
@ -605,10 +585,8 @@ func TestResetPassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -691,10 +669,8 @@ func TestResetPassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -734,10 +710,8 @@ func TestResetPassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -776,10 +750,8 @@ func TestResetPassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -829,10 +801,8 @@ func TestResetPassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -874,10 +844,8 @@ func TestCreateResetToken(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -910,10 +878,8 @@ func TestCreateResetToken(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -942,10 +908,8 @@ func TestUpdatePassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -975,10 +939,8 @@ func TestUpdatePassword(t *testing.T) {
defer testutils.ClearData(testutils.DB)
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1007,10 +969,8 @@ func TestUpdatePassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1039,10 +999,8 @@ func TestUpdatePassword(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1073,10 +1031,8 @@ func TestUpdateEmail(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1110,10 +1066,8 @@ func TestUpdateEmail(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1149,10 +1103,8 @@ func TestVerifyEmail(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1190,10 +1142,8 @@ func TestVerifyEmail(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1234,10 +1184,8 @@ func TestVerifyEmail(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1276,10 +1224,8 @@ func TestVerifyEmail(t *testing.T) {
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()
@ -1322,10 +1268,8 @@ func TestCreateVerificationToken(t *testing.T) {
// Setup
emailBackend := testutils.MockEmailbackendImplementation{}
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
EmailBackend: &emailBackend,
})
defer server.Close()
@ -1358,10 +1302,8 @@ func TestCreateVerificationToken(t *testing.T) {
defer testutils.ClearData(testutils.DB)
// Setup
server := MustNewServer(t, &app.App{
Clock: clock.NewMock(),
Config: config.Config{
PageTemplateDir: "../views",
},
Clock: clock.NewMock(),
Config: config.Config{},
})
defer server.Close()

View file

@ -20,8 +20,9 @@ package database
import (
"log"
"net/http"
"github.com/gobuffalo/packr/v2"
"github.com/dnote/dnote/pkg/server/database/migrations"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
"github.com/rubenv/sql-migrate"
@ -29,8 +30,8 @@ import (
// Migrate runs the migrations
func Migrate(db *gorm.DB) error {
migrations := &migrate.PackrMigrationSource{
Box: packr.New("migrations", "../database/migrations/"),
migrations := &migrate.HttpFileSystemMigrationSource{
FileSystem: http.FileSystem(http.FS(migrations.Files)),
}
migrate.SetTable(MigrationTableName)

View file

@ -0,0 +1,6 @@
package migrations
import "embed"
//go:embed *.sql
var Files embed.FS

View file

@ -21,13 +21,13 @@ package mailer
import (
"bytes"
"embed"
"fmt"
htemplate "html/template"
"io"
ttemplate "text/template"
"github.com/aymerick/douceur/inliner"
"github.com/gobuffalo/packr/v2"
"github.com/pkg/errors"
)
@ -62,6 +62,9 @@ type template interface {
// Templates holds the parsed email templates
type Templates map[string]template
//go:embed templates/src
var templateDir embed.FS
func getTemplateKey(name, kind string) string {
return fmt.Sprintf("%s.%s", name, kind)
}
@ -82,36 +85,28 @@ func (tmpl Templates) set(name, kind string, t template) {
}
// NewTemplates initializes templates
func NewTemplates(srcDir *string) Templates {
var box *packr.Box
if srcDir != nil {
box = packr.Folder(*srcDir)
} else {
box = packr.New("emailTemplates", "./templates/src")
}
welcomeText, err := initTextTmpl(box, EmailTypeWelcome)
func NewTemplates() Templates {
welcomeText, err := initTextTmpl(EmailTypeWelcome)
if err != nil {
panic(errors.Wrap(err, "initializing welcome template"))
}
verifyEmailText, err := initTextTmpl(box, EmailTypeEmailVerification)
verifyEmailText, err := initTextTmpl(EmailTypeEmailVerification)
if err != nil {
panic(errors.Wrap(err, "initializing email verification template"))
}
passwordResetText, err := initTextTmpl(box, EmailTypeResetPassword)
passwordResetText, err := initTextTmpl(EmailTypeResetPassword)
if err != nil {
panic(errors.Wrap(err, "initializing password reset template"))
}
passwordResetAlertText, err := initTextTmpl(box, EmailTypeResetPasswordAlert)
passwordResetAlertText, err := initTextTmpl(EmailTypeResetPasswordAlert)
if err != nil {
panic(errors.Wrap(err, "initializing password reset template"))
}
inactiveReminderText, err := initTextTmpl(box, EmailTypeInactiveReminder)
inactiveReminderText, err := initTextTmpl(EmailTypeInactiveReminder)
if err != nil {
panic(errors.Wrap(err, "initializing password reset template"))
}
subscriptionConfirmationText, err := initTextTmpl(box, EmailTypeSubscriptionConfirmation)
subscriptionConfirmationText, err := initTextTmpl(EmailTypeSubscriptionConfirmation)
if err != nil {
panic(errors.Wrap(err, "initializing password reset template"))
}
@ -129,30 +124,30 @@ func NewTemplates(srcDir *string) Templates {
// initHTMLTmpl returns a template instance by parsing the template with the
// given name along with partials
func initHTMLTmpl(box *packr.Box, templateName string) (template, error) {
filename := fmt.Sprintf("%s.html", templateName)
func initHTMLTmpl(templateName string) (template, error) {
filename := fmt.Sprintf("templates/src/%s.html", templateName)
content, err := box.FindString(filename)
content, err := templateDir.ReadFile(filename)
if err != nil {
return nil, errors.Wrap(err, "reading template")
}
headerContent, err := box.FindString("header.html")
headerContent, err := templateDir.ReadFile("templates/header.html")
if err != nil {
return nil, errors.Wrap(err, "reading header template")
}
footerContent, err := box.FindString("footer.html")
footerContent, err := templateDir.ReadFile("templates/footer.html")
if err != nil {
return nil, errors.Wrap(err, "reading footer template")
}
t := htemplate.New(templateName)
if _, err = t.Parse(content); err != nil {
if _, err = t.Parse(string(content)); err != nil {
return nil, errors.Wrap(err, "parsing template")
}
if _, err = t.Parse(headerContent); err != nil {
if _, err = t.Parse(string(headerContent)); err != nil {
return nil, errors.Wrap(err, "parsing template")
}
if _, err = t.Parse(footerContent); err != nil {
if _, err = t.Parse(string(footerContent)); err != nil {
return nil, errors.Wrap(err, "parsing template")
}
@ -160,16 +155,16 @@ func initHTMLTmpl(box *packr.Box, templateName string) (template, error) {
}
// initTextTmpl returns a template instance by parsing the template with the given name
func initTextTmpl(box *packr.Box, templateName string) (template, error) {
filename := fmt.Sprintf("%s.txt", templateName)
func initTextTmpl(templateName string) (template, error) {
filename := fmt.Sprintf("templates/src/%s.txt", templateName)
content, err := box.FindString(filename)
content, err := templateDir.ReadFile(filename)
if err != nil {
return nil, errors.Wrap(err, "reading template")
}
t := ttemplate.New(templateName)
if _, err = t.Parse(content); err != nil {
if _, err = t.Parse(string(content)); err != nil {
return nil, errors.Wrap(err, "parsing template")
}

View file

@ -20,7 +20,6 @@ package mailer
import (
"fmt"
"os"
"strings"
"testing"
@ -42,8 +41,7 @@ func TestEmailVerificationEmail(t *testing.T) {
},
}
tmplPath := os.Getenv("DNOTE_TEST_EMAIL_TEMPLATE_DIR")
tmpl := NewTemplates(&tmplPath)
tmpl := NewTemplates()
for _, tc := range testCases {
t.Run(fmt.Sprintf("with WebURL %s", tc.webURL), func(t *testing.T) {
@ -81,8 +79,7 @@ func TestResetPasswordEmail(t *testing.T) {
},
}
tmplPath := os.Getenv("DNOTE_TEST_EMAIL_TEMPLATE_DIR")
tmpl := NewTemplates(&tmplPath)
tmpl := NewTemplates()
for _, tc := range testCases {
t.Run(fmt.Sprintf("with WebURL %s", tc.webURL), func(t *testing.T) {

View file

@ -126,7 +126,7 @@ func main() {
log.Println("Email template development server running on http://127.0.0.1:2300")
tmpl := mailer.NewTemplates(nil)
tmpl := mailer.NewTemplates()
ctx := Context{DB: db, Tmpl: tmpl}
http.HandleFunc("/", ctx.homeHandler)

View file

@ -21,7 +21,6 @@ package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
@ -33,14 +32,12 @@ import (
"github.com/dnote/dnote/pkg/server/database"
"github.com/dnote/dnote/pkg/server/job"
"github.com/dnote/dnote/pkg/server/mailer"
"github.com/dnote/dnote/pkg/server/views"
"github.com/jinzhu/gorm"
"github.com/pkg/errors"
)
var pageDir = flag.String("pageDir", "views", "the path to a directory containing page templates")
var staticDir = flag.String("staticDir", "./static/", "the path to the static directory ")
var port = flag.String("port", "3000", "port to connect to")
func initDB(c config.Config) *gorm.DB {
db, err := gorm.Open("postgres", c.DB.GetConnectionStr())
@ -52,28 +49,16 @@ func initDB(c config.Config) *gorm.DB {
return db
}
func mustReadFile(path string) []byte {
ret, err := ioutil.ReadFile(path)
if err != nil {
panic(errors.Wrap(err, "reading file"))
}
return ret
}
func initApp(cfg config.Config) app.App {
db := initDB(cfg)
files := map[string][]byte{}
files[views.ServerErrorPageFileKey] = mustReadFile(fmt.Sprintf("%s/500.html", cfg.StaticDir))
return app.App{
DB: db,
Clock: clock.New(),
EmailTemplates: mailer.NewTemplates(nil),
EmailTemplates: mailer.NewTemplates(),
EmailBackend: &mailer.SimpleBackendImplementation{},
Config: cfg,
Files: files,
HTTP500Page: cfg.HTTP500Page,
}
}
@ -91,8 +76,6 @@ func runJob(a app.App) error {
func startCmd() {
cfg := config.Load()
cfg.SetPageTemplateDir(*pageDir)
cfg.SetStaticDir(*staticDir)
cfg.SetAssetBaseURL("/static")
app := initApp(cfg)
@ -105,7 +88,7 @@ func startCmd() {
panic(errors.Wrap(err, "running job"))
}
ctl := controllers.New(&app, *pageDir)
ctl := controllers.New(&app)
rc := controllers.RouteConfig{
WebRoutes: controllers.NewWebRoutes(&app, ctl),
APIRoutes: controllers.NewAPIRoutes(&app, ctl),
@ -117,8 +100,8 @@ func startCmd() {
panic(errors.Wrap(err, "initializing router"))
}
log.Printf("Dnote version %s is running on port %s", buildinfo.Version, cfg.Port)
log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%s", cfg.Port), r))
log.Printf("Dnote version %s is running on port %s", buildinfo.Version, *port)
log.Fatalln(http.ListenAndServe(fmt.Sprintf(":%s", *port), r))
}
func versionCmd() {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,8 @@
package views
import (
"embed"
)
//go:embed templates
var TemplateFs embed.FS

View file

@ -0,0 +1,99 @@
package views
import (
"fmt"
"html/template"
"io/fs"
"github.com/dnote/dnote/pkg/server/app"
"github.com/pkg/errors"
)
// Engine is responsible for instantiating a new View
type Engine struct {
filePatterns []string
fileSystem fs.FS
}
// NewEngine returns a new Engine
func NewEngine(filePatterns []string, fileSystem fs.FS) *Engine {
return &Engine{
filePatterns: filePatterns,
fileSystem: fileSystem,
}
}
// NewDefaultEngine returns a new default Engine
func NewDefaultEngine() *Engine {
patterns := []string{}
patterns = append(patterns, iconFiles())
patterns = append(patterns, layoutFiles())
patterns = append(patterns, partialFiles())
return NewEngine(patterns, TemplateFs)
}
// getTargetFiles returns an array of files needed for rendering
func (e Engine) getTargetFiles(files []string) []string {
addTemplatePath(files)
addTemplateExt(files)
return append(files, e.filePatterns...)
}
// NewView returns a new view by parsing the given layout and files
func (e Engine) NewView(app *app.App, viewConfig Config, files ...string) *View {
viewHelpers := initHelpers(viewConfig, app)
t := template.New(viewConfig.Title).Funcs(viewHelpers)
targetFiles := e.getTargetFiles(files)
t, err := t.ParseFS(e.fileSystem, targetFiles...)
if err != nil {
panic(errors.Wrap(err, "instantiating view"))
}
return &View{
Template: t,
Layout: viewConfig.getLayout(),
AlertInBody: viewConfig.AlertInBody,
App: app,
}
}
// layoutFiles returns a slice of strings representing
// the layout files used in our application.
func layoutFiles() string {
return fmt.Sprintf("templates/layouts/*%s", TemplateExt)
}
// iconFiles returns a slice of strings representing
// the icon files used in our application.
func iconFiles() string {
return fmt.Sprintf("templates/icons/*%s", TemplateExt)
}
func partialFiles() string {
return fmt.Sprintf("templates/partials/*%s", TemplateExt)
}
// addTemplatePath takes in a slice of strings
// representing file paths for templates.
func addTemplatePath(files []string) {
for i, f := range files {
files[i] = fmt.Sprintf("templates/%s", f)
}
}
// addTemplateExt takes in a slice of strings
// representing file paths for templates and it appends
// the templateExt extension to each string in the slice
//
// Eg the input {"home"} would result in the output
// {"home.gohtml"} if templateExt == ".gohtml"
func addTemplateExt(files []string) {
for i, f := range files {
files[i] = f + TemplateExt
}
}

View file

@ -27,7 +27,7 @@
<div class="footer">
<div class="callout">Don&#39;t have an account?</div>
<a href="/join" class="cta">
<a href="/join" class="cta" id="T-join-link">
Create account
</a>
</div>

View file

@ -6,7 +6,6 @@ import (
"html/template"
"io"
"net/http"
"path/filepath"
"github.com/dnote/dnote/pkg/clock"
"github.com/dnote/dnote/pkg/server/app"
@ -14,22 +13,17 @@ import (
"github.com/dnote/dnote/pkg/server/context"
"github.com/dnote/dnote/pkg/server/log"
"github.com/gorilla/csrf"
"github.com/pkg/errors"
)
const (
// templateExt is the template extension
templateExt string = ".gohtml"
// TemplateExt is the template extension
TemplateExt string = ".gohtml"
)
const (
siteTitle = "Dnote"
)
const (
ServerErrorPageFileKey = "500"
)
// Config is a view config
type Config struct {
Title string
@ -68,38 +62,13 @@ func (c Config) getClock() clock.Clock {
return clock.New()
}
// NewView returns a new view by parsing the given layout and files
func NewView(baseDir string, app *app.App, viewConfig Config, files ...string) *View {
addTemplatePath(baseDir, files)
addTemplateExt(files)
files = append(files, iconFiles(baseDir)...)
files = append(files, layoutFiles(baseDir)...)
files = append(files, partialFiles(baseDir)...)
viewHelpers := initHelpers(viewConfig, app)
t := template.New(viewConfig.Title).Funcs(viewHelpers)
t, err := t.ParseFiles(files...)
if err != nil {
panic(errors.Wrap(err, "instantiating view"))
}
return &View{
Template: t,
Layout: viewConfig.getLayout(),
AlertInBody: viewConfig.AlertInBody,
Files: app.Files,
}
}
// View holds the information about a view
type View struct {
Template *template.Template
Layout string
// AlertInBody specifies if alert should be set in the body instead of the header
AlertInBody bool
Files map[string][]byte
App *app.App
}
func (v *View) ServeHTTP(w http.ResponseWriter, r *http.Request) {
@ -149,55 +118,10 @@ func (v *View) Render(w http.ResponseWriter, r *http.Request, data *Data, status
if err := tpl.ExecuteTemplate(&buf, v.Layout, vd); err != nil {
log.ErrorWrap(err, fmt.Sprintf("executing template for URI '%s'", r.RequestURI))
w.WriteHeader(http.StatusInternalServerError)
w.Write(v.Files[ServerErrorPageFileKey])
w.Write(v.App.HTTP500Page)
return
}
w.WriteHeader(statusCode)
io.Copy(w, &buf)
}
func getFiles(pattern string) []string {
files, err := filepath.Glob(pattern)
if err != nil {
panic(err)
}
return files
}
// layoutFiles returns a slice of strings representing
// the layout files used in our application.
func layoutFiles(baseDir string) []string {
return getFiles(fmt.Sprintf("%s/layouts/*%s", baseDir, templateExt))
}
// iconFiles returns a slice of strings representing
// the icon files used in our application.
func iconFiles(baseDir string) []string {
return getFiles(fmt.Sprintf("%s/icons/*%s", baseDir, templateExt))
}
func partialFiles(baseDir string) []string {
return getFiles(fmt.Sprintf("%s/partials/*%s", baseDir, templateExt))
}
// addTemplatePath takes in a slice of strings
// representing file paths for templates.
func addTemplatePath(baseDir string, files []string) {
for i, f := range files {
files[i] = fmt.Sprintf("%s/%s", baseDir, f)
}
}
// addTemplateExt takes in a slice of strings
// representing file paths for templates and it appends
// the templateExt extension to each string in the slice
//
// Eg the input {"home"} would result in the output
// {"home.gohtml"} if templateExt == ".gohtml"
func addTemplateExt(files []string) {
for i, f := range files {
files[i] = f + templateExt
}
}

View file

@ -52,6 +52,7 @@ func splitCommandParts(cmd string) []string {
}
func command(binary string, args []string, entryPoint string) *exec.Cmd {
log.Printf("executing command: %s %s", binary, args)
cmd := exec.Command(binary, args...)
// Notice this change.

View file

@ -19,11 +19,6 @@ projectDir="$dir/../.."
basedir="$projectDir/pkg/cli"
outputDir="$projectDir/build/cli"
# xgo has issues when using modules
# https://github.com/karalabe/xgo/issues/176
# bypass it by copying the project inside a GOPATH
goPathBasedir="$GOPATH/src/github.com/dnote/dnote"
command_exists () {
command -v "$1" >/dev/null 2>&1;
}
@ -41,7 +36,7 @@ if [[ $1 == v* ]]; then
exit 1
fi
goVersion=1.13.x
goVersion=go-1.17.x
get_binary_name() {
platform=$1
@ -62,9 +57,11 @@ build() {
# build binary
destDir="$outputDir/$platform-$arch"
ldflags="-X main.apiEndpoint=https://api.getdnote.com -X main.versionTag=$version"
ldflags="-X main.apiEndpoint=https://api.getdnote.com -X github.com/dnote/dnote/pkg/server/buildinfo.Version=$version"
tags="fts5"
pushd "$projectDir"
mkdir -p "$destDir"
if [ "$native" == true ]; then
@ -75,17 +72,25 @@ build() {
-o="$destDir/cli-$platform-$arch" \
"$basedir"
else
flags=()
if [ "$platform" == "windows" ]; then
flags+=("-buildmode=exe")
fi
xgo \
-go "$goVersion" \
--targets="$platform/$arch" \
-targets="$platform/$arch" \
-ldflags "$ldflags" \
--tags "$tags" \
--dest="$destDir" \
-x \
-v \
"$goPathBasedir/pkg/cli"
-dest="$destDir" \
-out="cli" \
"${flags[@]}" \
-tags "$tags" \
-pkg pkg/cli \
.
fi
popd
binaryName=$(get_binary_name "$platform")
mv "$destDir/cli-${platform}-"* "$destDir/$binaryName"
@ -105,11 +110,8 @@ build() {
}
if [ -z "$GOOS" ] && [ -z "$GOARCH" ]; then
# fetch tool
go get -u github.com/dnote/xgo
rm -rf "$GOPATH/src/github.com/dnote/dnote"
cp -R "$projectDir" "$goPathBasedir"
# install the tool
go install src.techknowlogick.com/xgo@latest
build linux amd64
build linux arm64

View file

@ -35,16 +35,15 @@ build() {
mkdir -p "$destDir"
# build binary
packr2
moduleName="github.com/dnote/dnote"
ldflags="-X '$moduleName/pkg/server/buildinfo.CSSFiles=main.css' -X '$moduleName/pkg/server/buildinfo.JSFiles=main.js' -X '$moduleName/pkg/server/buildinfo.Version=$version' -X '$moduleName/pkg/server/buildinfo.Standalone=true'"
GOOS="$platform" \
GOARCH="$arch" go build \
-o "$destDir/dnote-server" \
-ldflags "-X main.versionTag=$version" \
-ldflags "$ldflags" \
"$basedir"/*.go
packr2 clean
popd
# build tarball

View file

@ -6,9 +6,6 @@ set -ex
dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
pushd "$dir/../../pkg/server"
emailTemplateDir=$(realpath "$dir/../../pkg/server/mailer/templates/src")
export DNOTE_TEST_EMAIL_TEMPLATE_DIR="$emailTemplateDir"
function run_test {
if [ -z "$1" ]; then
go test ./... -cover -p 1

View file

@ -2,7 +2,7 @@
# shellcheck disable=SC1091
set -eux
VERSION=1.13.4
VERSION=1.17.9
OS=linux
ARCH=amd64