mirror of
https://github.com/dnote/dnote
synced 2026-03-14 22:45:50 +01:00
Use go module (#303)
* Migrate to gomodule * Fix install * Update makefile
This commit is contained in:
parent
cf62033fe7
commit
2124e28a9f
26 changed files with 399 additions and 720 deletions
109
scripts/cli/build.sh
Executable file
109
scripts/cli/build.sh
Executable file
|
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# build.sh compiles dnote binary for target platforms. It is resonsible for creating
|
||||
# distributable files that can be released by a human or a script.
|
||||
#
|
||||
# It can either cross-compile for different platforms using xgo, simply target a specific
|
||||
# platform. Set GOOS and GOARCH environment variables to disable xgo and instead
|
||||
# compile for a specific platform.
|
||||
#
|
||||
# use:
|
||||
# ./scripts/build.sh 0.4.8
|
||||
# GOOS=linux GOARCH=amd64 ./scripts/build.sh 0.4.8
|
||||
set -ex
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
|
||||
version=$1
|
||||
projectDir="$dir/../.."
|
||||
basedir="$projectDir/pkg/cli"
|
||||
outputDir="$projectDir/build/cli"
|
||||
|
||||
command_exists () {
|
||||
command -v "$1" >/dev/null 2>&1;
|
||||
}
|
||||
|
||||
if ! command_exists shasum; then
|
||||
echo "please install shasum"
|
||||
exit 1
|
||||
fi
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "no version specified."
|
||||
exit 1
|
||||
fi
|
||||
if [[ $1 == v* ]]; then
|
||||
echo "do not prefix version with v"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
goVersion=1.12.x
|
||||
|
||||
get_binary_name() {
|
||||
platform=$1
|
||||
|
||||
if [ "$platform" == "windows" ]; then
|
||||
echo "dnote.exe"
|
||||
else
|
||||
echo "dnote"
|
||||
fi
|
||||
}
|
||||
|
||||
build() {
|
||||
platform=$1
|
||||
arch=$2
|
||||
# native indicates if the compilation is to take place natively on the host platform
|
||||
# if not true, use xgo with Docker to cross-compile
|
||||
native=$3
|
||||
|
||||
# build binary
|
||||
destDir="$outputDir/$platform-$arch"
|
||||
ldflags="-X main.apiEndpoint=https://api.dnote.io -X main.versionTag=$version"
|
||||
tags="fts5"
|
||||
|
||||
mkdir -p "$destDir"
|
||||
|
||||
if [ "$native" == true ]; then
|
||||
GOOS="$platform" GOARCH="$arch" \
|
||||
go build \
|
||||
-ldflags "$ldflags" \
|
||||
--tags "$tags" \
|
||||
-o="$destDir/cli-$platform-$arch" \
|
||||
"$basedir"
|
||||
else
|
||||
xgo \
|
||||
-go "$goVersion" \
|
||||
--targets="$platform/$arch" \
|
||||
-ldflags "$ldflags" \
|
||||
--tags "$tags" \
|
||||
--dest="$destDir" \
|
||||
"$basedir"
|
||||
fi
|
||||
|
||||
binaryName=$(get_binary_name "$platform")
|
||||
mv "$destDir/cli-${platform}-"* "$destDir/$binaryName"
|
||||
|
||||
# build tarball
|
||||
tarballName="dnote_${version}_${platform}_${arch}.tar.gz"
|
||||
tarballPath="$outputDir/$tarballName"
|
||||
|
||||
cp "$projectDir/licenses/GPLv3.txt" "$destDir"
|
||||
cp "$basedir/README.md" "$destDir"
|
||||
tar -C "$destDir" -zcvf "$tarballPath" "."
|
||||
rm -rf "$destDir"
|
||||
|
||||
# calculate checksum
|
||||
pushd "$outputDir"
|
||||
shasum -a 256 "$tarballName" >> "$outputDir/dnote_${version}_checksums.txt"
|
||||
popd
|
||||
}
|
||||
|
||||
if [ -z "$GOOS" ] && [ -z "$GOARCH" ]; then
|
||||
# fetch tool
|
||||
go get -u github.com/karalabe/xgo
|
||||
|
||||
build linux amd64
|
||||
build darwin amd64
|
||||
build windows amd64
|
||||
else
|
||||
build "$GOOS" "$GOARCH" true
|
||||
fi
|
||||
11
scripts/cli/dev.sh
Executable file
11
scripts/cli/dev.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
# dev.sh builds a new binary and replaces the old one in the PATH with it
|
||||
set -eux
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
sudo rm -rf "$(which dnote)" "$GOPATH/bin/cli"
|
||||
|
||||
# change tags to darwin if on macos
|
||||
go install -ldflags "-X main.apiEndpoint=http://127.0.0.1:5000" --tags "linux fts5" "$dir/../../pkg/cli"
|
||||
|
||||
sudo ln -s "$GOPATH/bin/cli" /usr/local/bin/dnote
|
||||
5
scripts/cli/dump_schema.sh
Executable file
5
scripts/cli/dump_schema.sh
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
# dump_schema.sh dumps the current system's dnote schema
|
||||
set -eux
|
||||
|
||||
sqlite3 ~/.dnote/dnote.db .schema
|
||||
14
scripts/cli/test.sh
Executable file
14
scripts/cli/test.sh
Executable file
|
|
@ -0,0 +1,14 @@
|
|||
#!/usr/bin/env bash
|
||||
# test.sh runs test files sequentially
|
||||
# https://stackoverflow.com/questions/23715302/go-how-to-run-tests-for-multiple-packages
|
||||
set -eux
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
pushd "$dir/../../pkg/cli"
|
||||
# clear tmp dir in case not properly torn down
|
||||
rm -rf "./tmp"
|
||||
|
||||
go test -a ./... \
|
||||
-p 1\
|
||||
--tags "fts5"
|
||||
popd
|
||||
|
|
@ -55,9 +55,10 @@ agpl="/* Copyright (C) 2019 Monomax Software Pty Ltd
|
|||
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/"
|
||||
|
||||
pkgPath="$GOPATH/src/github.com/dnote/dnote/pkg"
|
||||
serverPath="$GOPATH/src/github.com/dnote/dnote/pkg/server"
|
||||
browserPath="$GOPATH/src/github.com/dnote/dnote/browser"
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
pkgPath="$dir/pkg"
|
||||
serverPath="$dir/pkg/server"
|
||||
browserPath="$dir/browser"
|
||||
|
||||
gplFiles=$(find "$pkgPath" "$browserPath" -type f \( -name "*.go" -o -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.scss" -o -name "*.css" \) ! -path "**/vendor/*" ! -path "**/node_modules/*" ! -path "$serverPath/*")
|
||||
|
||||
|
|
@ -66,8 +67,8 @@ for file in $gplFiles; do
|
|||
add_notice "$file" "$gpl"
|
||||
done
|
||||
|
||||
webPath="$GOPATH"/src/github.com/dnote/dnote/web
|
||||
jslibPath="$GOPATH/src/github.com/dnote/dnote/jslib/src"
|
||||
webPath="$dir/web"
|
||||
jslibPath="$dir/jslib/src"
|
||||
agplFiles=$(find "$serverPath" "$webPath" "$jslibPath" -type f \( -name "*.go" -o -name "*.js" -o -name "*.ts" -o -name "*.tsx" -o -name "*.scss" -o -name "*.css" \) ! -path "**/vendor/*" ! -path "**/node_modules/*" ! -path "**/dist/*")
|
||||
|
||||
for file in $agplFiles; do
|
||||
|
|
|
|||
61
scripts/server/build.sh
Executable file
61
scripts/server/build.sh
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eux
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
|
||||
version=$1
|
||||
projectDir="$dir/../.."
|
||||
basedir="$projectDir/pkg/server"
|
||||
outputDir="$projectDir/build/server"
|
||||
|
||||
command_exists () {
|
||||
command -v "$1" >/dev/null 2>&1;
|
||||
}
|
||||
|
||||
if ! command_exists shasum; then
|
||||
echo "please install shasum"
|
||||
exit 1
|
||||
fi
|
||||
if [ $# -eq 0 ]; then
|
||||
echo "no version specified."
|
||||
exit 1
|
||||
fi
|
||||
if [[ $1 == v* ]]; then
|
||||
echo "do not prefix version with v"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
build() {
|
||||
platform=$1
|
||||
arch=$2
|
||||
|
||||
destDir="$outputDir/$platform-$arch"
|
||||
mkdir -p "$destDir"
|
||||
|
||||
# build binary
|
||||
packr2
|
||||
|
||||
GOOS="$platform" \
|
||||
GOARCH="$arch" go build \
|
||||
-o "$destDir/dnote-server" \
|
||||
-ldflags "-X main.versionTag=$version" \
|
||||
"$projectDir"/pkg/server/*.go
|
||||
|
||||
packr2 clean
|
||||
|
||||
# build tarball
|
||||
tarballName="dnote_server_${version}_${platform}_${arch}.tar.gz"
|
||||
tarballPath="$outputDir/$tarballName"
|
||||
|
||||
cp "$projectDir/licenses/AGPLv3.txt" "$destDir"
|
||||
cp "$basedir/README.md" "$destDir"
|
||||
tar -C "$destDir" -zcvf "$tarballPath" "."
|
||||
rm -rf "$destDir"
|
||||
|
||||
# calculate checksum
|
||||
pushd "$outputDir"
|
||||
shasum -a 256 "$tarballName" >> "$outputDir/dnote_${version}_checksums.txt"
|
||||
popd
|
||||
}
|
||||
|
||||
build linux amd64
|
||||
253
scripts/server/makeDemoDigests/main.go
Normal file
253
scripts/server/makeDemoDigests/main.go
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/* Copyright (C) 2019 Monomax Software Pty Ltd
|
||||
*
|
||||
* This file is part of Dnote.
|
||||
*
|
||||
* Dnote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dnote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/dnote/dnote/pkg/server/helpers"
|
||||
"github.com/dnote/dnote/pkg/server/database"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
c := database.Config{
|
||||
Host: os.Getenv("DBHost"),
|
||||
Port: os.Getenv("DBPort"),
|
||||
Name: os.Getenv("DBName"),
|
||||
User: os.Getenv("DBUser"),
|
||||
Password: os.Getenv("DBPassword"),
|
||||
}
|
||||
database.Open(c)
|
||||
|
||||
db := database.DBConn
|
||||
tx := db.Begin()
|
||||
|
||||
userID, err := helpers.GetDemoUserID()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var d1Notes []database.Note
|
||||
var d2Notes []database.Note
|
||||
var d3Notes []database.Note
|
||||
var d4Notes []database.Note
|
||||
var d5Notes []database.Note
|
||||
var d6Notes []database.Note
|
||||
var d7Notes []database.Note
|
||||
var d8Notes []database.Note
|
||||
var d9Notes []database.Note
|
||||
var d10Notes []database.Note
|
||||
var d11Notes []database.Note
|
||||
var d12Notes []database.Note
|
||||
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d1Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d2Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d3Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d4Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d5Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d6Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d7Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d8Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d9Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d10Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d11Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
if err := db.Order("random()").Limit(5).Where("user_id = ?", userID).Find(&d12Notes).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d1Date := time.Date(2019, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
d1 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d1Notes,
|
||||
CreatedAt: d1Date,
|
||||
UpdatedAt: d1Date,
|
||||
}
|
||||
if err := tx.Save(&d1).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d2Date := time.Date(2019, time.February, 4, 0, 0, 0, 0, time.UTC)
|
||||
d2 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d2Notes,
|
||||
CreatedAt: d2Date,
|
||||
UpdatedAt: d2Date,
|
||||
}
|
||||
if err := tx.Save(&d2).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d3Date := time.Date(2019, time.February, 12, 0, 0, 0, 0, time.UTC)
|
||||
d3 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d3Notes,
|
||||
CreatedAt: d3Date,
|
||||
UpdatedAt: d3Date,
|
||||
}
|
||||
if err := tx.Save(&d3).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d4Date := time.Date(2019, time.May, 12, 0, 0, 0, 0, time.UTC)
|
||||
d4 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d4Notes,
|
||||
CreatedAt: d4Date,
|
||||
UpdatedAt: d4Date,
|
||||
}
|
||||
if err := tx.Save(&d4).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d5Date := time.Date(2019, time.March, 10, 0, 0, 0, 0, time.UTC)
|
||||
d5 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d5Notes,
|
||||
CreatedAt: d5Date,
|
||||
UpdatedAt: d5Date,
|
||||
}
|
||||
if err := tx.Save(&d5).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d6Date := time.Date(2019, time.February, 20, 0, 0, 0, 0, time.UTC)
|
||||
d6 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d6Notes,
|
||||
CreatedAt: d6Date,
|
||||
UpdatedAt: d6Date,
|
||||
}
|
||||
if err := tx.Save(&d6).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d7Date := time.Date(2019, time.April, 24, 0, 0, 0, 0, time.UTC)
|
||||
d7 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d7Notes,
|
||||
CreatedAt: d7Date,
|
||||
UpdatedAt: d7Date,
|
||||
}
|
||||
if err := tx.Save(&d7).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d8Date := time.Date(2018, time.December, 6, 0, 0, 0, 0, time.UTC)
|
||||
d8 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d8Notes,
|
||||
CreatedAt: d8Date,
|
||||
UpdatedAt: d8Date,
|
||||
}
|
||||
if err := tx.Save(&d8).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d9Date := time.Date(2018, time.November, 2, 0, 0, 0, 0, time.UTC)
|
||||
d9 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d9Notes,
|
||||
CreatedAt: d9Date,
|
||||
UpdatedAt: d9Date,
|
||||
}
|
||||
if err := tx.Save(&d9).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d10Date := time.Date(2018, time.October, 12, 0, 0, 0, 0, time.UTC)
|
||||
d10 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d10Notes,
|
||||
CreatedAt: d10Date,
|
||||
UpdatedAt: d10Date,
|
||||
}
|
||||
if err := tx.Save(&d10).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d11Date := time.Date(2018, time.October, 1, 0, 0, 0, 0, time.UTC)
|
||||
d11 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d11Notes,
|
||||
CreatedAt: d11Date,
|
||||
UpdatedAt: d11Date,
|
||||
}
|
||||
if err := tx.Save(&d11).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d12Date := time.Date(2018, time.May, 17, 0, 0, 0, 0, time.UTC)
|
||||
d12 := database.Digest{
|
||||
UserID: userID,
|
||||
Notes: d12Notes,
|
||||
CreatedAt: d12Date,
|
||||
UpdatedAt: d12Date,
|
||||
}
|
||||
if err := tx.Save(&d12).Error; err != nil {
|
||||
tx.Rollback()
|
||||
panic(err)
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
}
|
||||
12
scripts/server/test-local.sh
Executable file
12
scripts/server/test-local.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC1090
|
||||
# test-local.sh runs api tests using local setting
|
||||
set -eux
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
|
||||
set -a
|
||||
source "$dir/../../pkg/server/.env.test"
|
||||
set +a
|
||||
|
||||
"$dir/test.sh"
|
||||
19
scripts/server/test.sh
Executable file
19
scripts/server/test.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
# test.sh runs server tests. It is to be invoked by other scripts that set
|
||||
# appropriate env vars.
|
||||
set -eux
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
pushd "$dir/../../pkg/server"
|
||||
|
||||
export DNOTE_TEST_EMAIL_TEMPLATE_DIR="$dir/../../pkg/server/mailer/templates/src"
|
||||
|
||||
if [ "${WATCH-false}" == true ]; then
|
||||
set +e
|
||||
while inotifywait --exclude .swp -e modify -r .; do go test ./... -cover -p 1; done;
|
||||
set -e
|
||||
else
|
||||
go test ./... -cover -p 1
|
||||
fi
|
||||
|
||||
popd
|
||||
21
scripts/web/build-prod.sh
Executable file
21
scripts/web/build-prod.sh
Executable file
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
# build.sh builds a production bundle
|
||||
set -eux
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
|
||||
basePath="$dir/../.."
|
||||
publicPath="$basePath/web/public"
|
||||
compiledPath="$basePath/web/compiled"
|
||||
|
||||
bundleBaseUrl="/static"
|
||||
assetBaseUrl="/static"
|
||||
rootUrl=""
|
||||
|
||||
BUNDLE_BASE_URL="$bundleBaseUrl" \
|
||||
ASSET_BASE_URL="$assetBaseUrl" \
|
||||
ROOT_URL="$rootUrl" \
|
||||
PUBLIC_PATH="$publicPath" \
|
||||
COMPILED_PATH="$compiledPath" \
|
||||
VERSION="$VERSION" \
|
||||
"$dir/build.sh"
|
||||
39
scripts/web/build.sh
Executable file
39
scripts/web/build.sh
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
#!/usr/bin/env bash
|
||||
# build.sh builds a bundle
|
||||
set -ex
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
basePath="$dir/../.."
|
||||
isTest=${IS_TEST:-false}
|
||||
|
||||
set -u
|
||||
rm -rf "$basePath/web/public"
|
||||
mkdir -p "$basePath/web/public/static"
|
||||
|
||||
pushd "$basePath/web"
|
||||
PUBLIC_PATH="$PUBLIC_PATH" \
|
||||
COMPILED_PATH="$COMPILED_PATH" \
|
||||
ASSET_BASE_URL="$ASSET_BASE_URL" \
|
||||
"$dir/setup.sh"
|
||||
|
||||
OUTPUT_PATH="$COMPILED_PATH" \
|
||||
ROOT_URL="$ROOT_URL" \
|
||||
VERSION="$VERSION" \
|
||||
"$basePath"/web/node_modules/.bin/webpack\
|
||||
--colors\
|
||||
--display-error-details\
|
||||
--env.isTest="$isTest"\
|
||||
--config "$basePath"/web/webpack/prod.config.js
|
||||
|
||||
NODE_ENV=PRODUCTION \
|
||||
BUNDLE_BASE_URL=$BUNDLE_BASE_URL \
|
||||
ASSET_BASE_URL=$ASSET_BASE_URL \
|
||||
PUBLIC_PATH=$PUBLIC_PATH \
|
||||
COMPILED_PATH=$COMPILED_PATH \
|
||||
node "$dir/placeholder.js"
|
||||
|
||||
cp "$COMPILED_PATH"/*.js "$COMPILED_PATH"/*.css "$PUBLIC_PATH"/static
|
||||
|
||||
# clean up compiled
|
||||
rm -rf "$basePath"/web/compiled/*
|
||||
popd
|
||||
40
scripts/web/dev.sh
Executable file
40
scripts/web/dev.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env bash
|
||||
# shellcheck disable=SC1090
|
||||
# dev.sh builds and starts development environment
|
||||
set -eux -o pipefail
|
||||
|
||||
# clean up background processes
|
||||
function cleanup {
|
||||
kill "$devServerPID"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
basePath="$dir/../.."
|
||||
appPath="$basePath/web"
|
||||
serverPath="$basePath/pkg/server"
|
||||
serverPort=3000
|
||||
|
||||
# load env
|
||||
set -a
|
||||
dotenvPath="$serverPath/.env.dev"
|
||||
source "$dotenvPath"
|
||||
set +a
|
||||
|
||||
# run webpack-dev-server for js in the background
|
||||
(
|
||||
BUNDLE_BASE_URL=http://localhost:8080 \
|
||||
ASSET_BASE_URL=http://localhost:3000/static \
|
||||
ROOT_URL=http://localhost:$serverPort \
|
||||
COMPILED_PATH="$appPath"/compiled \
|
||||
PUBLIC_PATH="$appPath"/public \
|
||||
COMPILED_PATH="$basePath/web/compiled" \
|
||||
IS_TEST=true \
|
||||
VERSION="$VERSION" \
|
||||
WEBPACK_HOST="0.0.0.0" \
|
||||
"$dir/webpack-dev.sh"
|
||||
) &
|
||||
devServerPID=$!
|
||||
|
||||
# run server
|
||||
(cd "$serverPath/watcher" && go run main.go)
|
||||
102
scripts/web/placeholder.js
Normal file
102
scripts/web/placeholder.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* Copyright (C) 2019 Monomax Software Pty Ltd
|
||||
*
|
||||
* This file is part of Dnote.
|
||||
*
|
||||
* Dnote is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Dnote is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// placeholder.js replaces the placeholders in index.html with real values
|
||||
// It is needed to load assets whose paths are not fixed because they change
|
||||
// every time they are generated.
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// bundleBaseURL is the base URL from which the application javascript bundle
|
||||
// In production, it should be the same as assetBaseURL. It is used for development
|
||||
// environment, in which it is configured to be the webpack development server.
|
||||
const bundleBaseURL = process.env.BUNDLE_BASE_URL;
|
||||
// assetBaseURL is the base URL from which all assets excluding the application
|
||||
// bundle is served.
|
||||
const assetBaseURL = process.env.ASSET_BASE_URL;
|
||||
const publicPath = process.env.PUBLIC_PATH;
|
||||
const compiledPath = process.env.COMPILED_PATH;
|
||||
|
||||
if (bundleBaseURL === undefined) {
|
||||
throw new Error('No BUNDLE_BASE_URL environment variable found');
|
||||
}
|
||||
if (assetBaseURL === undefined) {
|
||||
throw new Error('No ASSET_BASE_URL environment variable found');
|
||||
}
|
||||
if (publicPath === undefined) {
|
||||
throw new Error('No PUBLIC_PATH environment variable found');
|
||||
}
|
||||
if (compiledPath === undefined) {
|
||||
throw new Error('No COMPILED_PATH environment variable found');
|
||||
}
|
||||
|
||||
const isProduction = process.env.NODE_ENV === 'PRODUCTION';
|
||||
const indexHtmlPath = `${publicPath}/index.html`;
|
||||
const assetManifestPath = path.resolve(compiledPath, 'webpack-manifest.json');
|
||||
|
||||
let manifest;
|
||||
try {
|
||||
// eslint-disable-next-line import/no-dynamic-require,global-require
|
||||
manifest = require(assetManifestPath);
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch (e) {
|
||||
if (isProduction) {
|
||||
throw new Error('asset manifest not found');
|
||||
}
|
||||
}
|
||||
|
||||
function getJSBundleTag() {
|
||||
let jsFilename;
|
||||
if (isProduction) {
|
||||
jsFilename = manifest['app.js'];
|
||||
} else {
|
||||
jsFilename = '/app.js';
|
||||
}
|
||||
|
||||
const jsBundleUrl = `${bundleBaseURL}${jsFilename}`;
|
||||
return `<script src="${jsBundleUrl}"></script>`;
|
||||
}
|
||||
|
||||
// Replace the placeholders with real values
|
||||
fs.readFile(indexHtmlPath, 'utf8', (err, data) => {
|
||||
if (err) {
|
||||
console.log('Error while reading index.html');
|
||||
console.log(err);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const jsBundleTag = getJSBundleTag();
|
||||
let result = data.replace(/<!--JS_BUNDLE_PLACEHOLDER-->/g, jsBundleTag);
|
||||
result = result.replace(/<!--ASSET_BASE_PLACEHOLDER-->/g, assetBaseURL);
|
||||
|
||||
if (isProduction) {
|
||||
const cssBundleUrl = `${assetBaseURL}${manifest['app.css']}`;
|
||||
const cssBundleTag = `<link rel="stylesheet" href="${cssBundleUrl}" />`;
|
||||
|
||||
result = result.replace(/<!--CSS_BUNDLE_PLACEHOLDER-->/g, cssBundleTag);
|
||||
}
|
||||
|
||||
fs.writeFile(indexHtmlPath, result, 'utf8', writeErr => {
|
||||
if (writeErr) {
|
||||
console.log('Error while writing index.html');
|
||||
console.log(writeErr);
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
});
|
||||
22
scripts/web/setup.sh
Executable file
22
scripts/web/setup.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
# setup.sh prepares the directory structure and copies static files
|
||||
set -eux -o pipefail
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
basePath="$dir/../.."
|
||||
publicPath=$PUBLIC_PATH
|
||||
compiledPath=$COMPILED_PATH
|
||||
assetBaseUrl=$ASSET_BASE_URL
|
||||
|
||||
# prepare directories
|
||||
rm -rf "$compiledPath"
|
||||
rm -rf "$publicPath"
|
||||
mkdir -p "$compiledPath"
|
||||
mkdir -p "$publicPath"
|
||||
|
||||
# copy the assets and artifacts
|
||||
cp -r "$basePath"/web/assets/* "$publicPath"
|
||||
|
||||
# populate placeholders
|
||||
assetBaseUrlEscaped=$(echo "$assetBaseUrl" | sed -e 's/[\/&]/\\&/g')
|
||||
sed -i -e "s/ASSET_BASE_PLACEHOLDER/$assetBaseUrlEscaped/g" "$publicPath"/static/manifest.json
|
||||
28
scripts/web/webpack-dev.sh
Executable file
28
scripts/web/webpack-dev.sh
Executable file
|
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eux
|
||||
|
||||
dir=$(dirname "${BASH_SOURCE[0]}")
|
||||
basePath="$dir/../.."
|
||||
appPath="$basePath/web"
|
||||
|
||||
(
|
||||
cd "$appPath" &&
|
||||
PUBLIC_PATH=$PUBLIC_PATH \
|
||||
COMPILED_PATH=$COMPILED_PATH \
|
||||
ASSET_BASE_URL=$ASSET_BASE_URL \
|
||||
"$dir/setup.sh" &&
|
||||
|
||||
BUNDLE_BASE_URL=$BUNDLE_BASE_URL
|
||||
ASSET_BASE_URL=$ASSET_BASE_URL \
|
||||
COMPILED_PATH=$COMPILED_PATH \
|
||||
PUBLIC_PATH=$PUBLIC_PATH \
|
||||
IS_TEST=true \
|
||||
node "$dir/placeholder.js" &&
|
||||
|
||||
ROOT_URL=$ROOT_URL \
|
||||
VERSION="$VERSION" \
|
||||
"$appPath"/node_modules/.bin/webpack-dev-server\
|
||||
--env.isTest="$IS_TEST" \
|
||||
--host "$WEBPACK_HOST" \
|
||||
--config "$appPath"/webpack/dev.config.js
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue