Implement server binary (#223)

This commit is contained in:
Sung Won Cho 2019-07-22 13:41:09 +10:00 committed by GitHub
commit 357a587653
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 756 additions and 589 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
/vendor
/build

View file

@ -2,51 +2,61 @@
This repository contains the server side and the client side code for Dnote.
## Set up
* [Setting up](#setting-up)
* [Command Linux Interface](#command-line-interface)
* [Server](#server)
1. Download and setup the [Go programming language](https://golang.org/dl/).
2. Download the project
## Setting up
1. Install the following prerequisites if necessary:
* [Go programming language](https://golang.org/dl/) 1.12+
* [Node.js](https://nodejs.org/) 10.16+
* Postgres 10.9+
2. Get the Dnote code:
```sh
go get github.com/dnote/dnote
```
## CLI
3. Run `make` to install dependencies
### Set up
## Command Line Interface
Download dependencies using [dep](https://github.com/golang/dep).
### Build
```sh
dep ensure
You can build either a development version or a production version:
```
# Build a development version for your platform and place it in your `PATH`.
make debug=true build-cli
# Build a production version
make version=v0.1.0 build-cli
```
### Test
Run:
* Run all tests for the command line interface:
```sh
./cli/scripts/test.sh
```
make test-cli
```
### Debug
Run Dnote with `DNOTE_DEBUG=1` to print debugging statements.
Run Dnote with `DNOTE_DEBUG=1` to print debugging statements. For instance:
```
DNOTE_DEBUG=1 dnote sync
```
### Release
* Build for all target platforms, tag, push tags
* Release on GitHub and [Dnote Homebrew tap](https://github.com/dnote/homebrew-dnote).
```sh
VERSION=0.4.8 make release
```
* Build, without releasing, for all target platforms
```sh
VERSION=0.4.8 make
```
* Run `make version=v0.1.0 release-cli` to achieve the following:
* Build for all target platforms, create a git tag, push all tags to the repository
* Create a release on GitHub and [Dnote Homebrew tap](https://github.com/dnote/homebrew-dnote).
**Note**
@ -54,39 +64,24 @@ VERSION=0.4.8 make
- disable the homebrew release by commenting out relevant code in the release script.
- mark release as pre-release on GitHub release
## Web
### Set up
Download dependencies using [dep](https://github.com/golang/dep) and npm.
```sh
dep ensure
npm install
```
### Test
Run:
```
npm run test
```
## Server
### Set up
The server consists of the frontend web application and a web server.
Download dependencies using [dep](https://github.com/golang/dep).
### Development
```sh
dep ensure
```
* Create a postgres database by running `createdb -O postgres dnote`
* If the role does not exist, you can create it by running `sudo -u postgres createuser postgres`
* Run `make dev-server` to start a local server
### Test
Run:
```bash
# Run tests for the frontend web application
make test-web
# Run tests for API
make test-api
```
./server/api/scripts/test-local.sh
```

91
Gopkg.lock generated
View file

@ -45,6 +45,51 @@
revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4"
version = "v1.7.0"
[[projects]]
digest = "1:d29ee5ef14a7e0253facd0bcebe6a69a7a4e02a67eb24d2aacd8ccb4a7cea6fc"
name = "github.com/gobuffalo/envy"
packages = ["."]
pruneopts = "UT"
revision = "043cb4b8af871b49563291e32c66bb84378a60ac"
version = "v1.7.0"
[[projects]]
digest = "1:6c9088827dcc7a807c97592a55f190e35e0fdaf237c5a074256c260925c59428"
name = "github.com/gobuffalo/logger"
packages = ["."]
pruneopts = "UT"
revision = "7c291b53e05b81d77bd43109b4a3c6f84e45c8e1"
version = "v1.0.1"
[[projects]]
digest = "1:40849e8495ef81a84ff335ef65e23d33671b61e60e9db464fbab55f19f43f120"
name = "github.com/gobuffalo/packd"
packages = [
".",
"internal/takeon/github.com/markbates/errx",
]
pruneopts = "UT"
revision = "54ea459691466cfb630ccc276723fe3963f3e9d5"
version = "v0.3.0"
[[projects]]
digest = "1:d5be00af71142774ee6738480e580ae975e8e97158f9334b13af41a77f2f6b0c"
name = "github.com/gobuffalo/packr"
packages = [
"v2",
"v2/file",
"v2/file/resolver",
"v2/file/resolver/encoding/hex",
"v2/internal/takeon/github.com/markbates/errx",
"v2/internal/takeon/github.com/markbates/oncer",
"v2/internal/takeon/github.com/markbates/safe",
"v2/jam/parser",
"v2/plog",
]
pruneopts = "UT"
revision = "9eb7a3d310e89e471c2cdf1ea3ec8d7fc1ab969c"
version = "v2.5.2"
[[projects]]
digest = "1:318f1c959a8a740366fce4b1e1eb2fd914036b4af58fbd0a003349b305f118ad"
name = "github.com/golang/protobuf"
@ -141,6 +186,22 @@
revision = "23d116af351c84513e1946b527c88823e476be13"
version = "v1.3.0"
[[projects]]
digest = "1:77857b3205f936bdc6928ef347b682ab549cf99454d6c0ca04a49f8df9e418f3"
name = "github.com/karrick/godirwalk"
packages = ["."]
pruneopts = "UT"
revision = "73c17a9b9528eb3ce857b782a2816c0cda581e62"
version = "v1.10.12"
[[projects]]
digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de"
name = "github.com/konsorten/go-windows-terminal-sequences"
packages = ["."]
pruneopts = "UT"
revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e"
version = "v1.0.2"
[[projects]]
digest = "1:bdd53b87de8185da386bae179c84d4848854c6870bacacf6a154fe63e2e750f7"
name = "github.com/lib/pq"
@ -154,13 +215,11 @@
version = "v1.1.1"
[[projects]]
digest = "1:639aaff480d288c3dbc99ae68f00d58ae43c283a85725ae3afaada7b5810c6be"
digest = "1:1241b137a50b99f7f395e6d3d917cafa4330bd17c55dacef18bfa8d87707533a"
name = "github.com/markbates/goth"
packages = [
".",
"gothic",
"providers/github",
"providers/gplus",
]
pruneopts = "UT"
revision = "3b8012093d951beedd026d120be1792db01a08f6"
@ -207,7 +266,18 @@
version = "v1.2.0"
[[projects]]
branch = "master"
digest = "1:e09ada96a5a41deda4748b1659cc8953961799e798aea557257b56baee4ecaf3"
name = "github.com/rogpeppe/go-internal"
packages = [
"modfile",
"module",
"semver",
]
pruneopts = "UT"
revision = "438578804ca6f31be148c27683afc419ce47c06e"
version = "v1.3.0"
[[projects]]
digest = "1:83eb06141fc25c7fd89f8b39717962ac930a7480796aab3d46c7e88507a69173"
name = "github.com/rubenv/sql-migrate"
packages = [
@ -233,6 +303,14 @@
revision = "1744e2970ca51c86172c8190fadad617561ed6e7"
version = "v1.0.0"
[[projects]]
digest = "1:04457f9f6f3ffc5fea48e71d62f2ca256637dee0a04d710288e27e05c8b41976"
name = "github.com/sirupsen/logrus"
packages = ["."]
pruneopts = "UT"
revision = "839c75faf7f98a33d445d181f3018b5c3409a45e"
version = "v1.4.2"
[[projects]]
digest = "1:e096613fb7cf34743d49af87d197663cfccd61876e2219853005a57baedfa562"
name = "github.com/spf13/cobra"
@ -385,17 +463,14 @@
"github.com/aymerick/douceur/inliner",
"github.com/dnote/actions",
"github.com/dnote/color",
"github.com/gobuffalo/packr/v2",
"github.com/google/go-github/github",
"github.com/gorilla/mux",
"github.com/gorilla/securecookie",
"github.com/gorilla/sessions",
"github.com/jinzhu/gorm",
"github.com/joho/godotenv",
"github.com/lib/pq",
"github.com/markbates/goth",
"github.com/markbates/goth/gothic",
"github.com/markbates/goth/providers/github",
"github.com/markbates/goth/providers/gplus",
"github.com/mattn/go-sqlite3",
"github.com/pkg/errors",
"github.com/robfig/cron",

View file

@ -45,14 +45,6 @@
name = "github.com/gorilla/mux"
version = "1.7.2"
[[constraint]]
name = "github.com/gorilla/securecookie"
version = "1.1.1"
[[constraint]]
name = "github.com/gorilla/sessions"
version = "1.1.3"
[[constraint]]
name = "github.com/jinzhu/gorm"
version = "1.9.9"
@ -120,3 +112,7 @@
[[constraint]]
revision = "f4d34eae5a5cf210693e81c604e6bac5f6727927"
name = "github.com/rubenv/sql-migrate"
[[constraint]]
name = "github.com/gobuffalo/packr"
version = "2.5.2"

View file

@ -1,5 +1,7 @@
DEP := $(shell command -v dep 2> /dev/null)
PACKR2 := $(shell command -v packr2 2> /dev/null)
NPM := $(shell command -v npm 2> /dev/null)
HUB := $(shell command -v hub 2> /dev/null)
## installation
install: install-go install-js
@ -11,6 +13,11 @@ ifndef DEP
@curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
endif
ifndef PACKR2
@echo "==> installing packr2"
@go get -u github.com/gobuffalo/packr/v2/packr2
endif
@echo "==> installing go dependencies"
@dep ensure
.PHONY: install-go
@ -30,6 +37,9 @@ endif
.PHONY: install-js
## test
test: test-cli test-api test-web
.PHONY: test
test-cli:
@echo "==> running CLI test"
@${GOPATH}/src/github.com/dnote/dnote/pkg/cli/scripts/test.sh
@ -45,26 +55,81 @@ test-web:
@(cd ${GOPATH}/src/github.com/dnote/dnote/web && npm run test)
.PHONY: test-web
test: test-cli test-api test-web
.PHONY: test
# development
dev-server:
@echo "==> running dev environment"
@(cd ${GOPATH}/src/github.com/dnote/dnote/web && ./scripts/dev.sh)
.PHONY: dev-server
## build
build-web:
@echo "==> building web"
@${GOPATH}/src/github.com/dnote/dnote/web/scripts/build-prod.sh
@(cd ${GOPATH}/src/github.com/dnote/dnote/web && ./scripts/build-prod.sh)
.PHONY: build-web
build-dev-cli:
@echo "==> building dev cli"
@${GOPATH}/src/github.com/dnote/dnote/pkg/cli/scripts/dev.sh
.PHONY: build-dev-cli
## migrate
migrate:
ifndef GO_ENV
$(error "environment variable GO_ENV is required.")
build-server: build-web
ifndef version
$(error version is required. Usage: make version=v0.1.0 build-server)
endif
@echo "==> running migrations"
@(cd ${GOPATH}/src/github.com/dnote/dnote/pkg/server/database/migrate && go run *.go --migrationDir ../migrations)
.PHONY: migrate
@echo "==> building server"
@(cd ${GOPATH}/src/github.com/dnote/dnote/pkg/server && ./scripts/build.sh $(version))
.PHONY: build-server
build-cli:
ifeq ($(debug), true)
@echo "==> building cli in dev mode"
@${GOPATH}/src/github.com/dnote/dnote/pkg/cli/scripts/dev.sh
else
ifndef version
$(error version is required. Usage: make version=v0.1.0 build-cli)
endif
@echo "==> building cli"
@${GOPATH}/src/github.com/dnote/dnote/pkg/cli/scripts/build.sh $(version)
endif
.PHONY: build-cli
## release
release-cli: build-cli
ifndef version
$(error version is required. Usage: make version=v0.1.0 release-cli)
endif
ifndef HUB
$(error please install hub)
endif
@homebrewRepoDir=${GOPATH}/src/github.com/dnote/homebrew-dnote
if [ ! -d ${homebrewRepoDir} ]; then
@echo "homebrew-dnote not found locally. did you clone it?"
@exit 1
fi
@echo "==> releasing cli"
@outputDir=${GOPATH}/src/github.com/dnote/dnote/build/cli
@${GOPATH}/src/github.com/dnote/dnote/pkg/cli/scripts/release.sh cli $(version) ${outputDir}
@echo "===> releading on Homebrew"
@homebrew_sha256=$(shasum -a 256 "${outputDir}/dnote_$(version)_darwin_amd64.tar.gz" | cut -d ' ' -f 1)
@(cd "${homebrewRepoDir}" && ./release.sh "$(version)" "${homebrew_sha256}")
.PHONY: release-cli
release-server: build-server
ifndef version
$(error version is required. Usage: make version=v0.1.0 release-server)
endif
ifndef HUB
$(error please install hub)
endif
@echo "==> releasing server"
@outputDir=${GOPATH}/src/github.com/dnote/dnote/build/server
@${GOPATH}/src/github.com/dnote/dnote/pkg/server/scripts/release.sh server $(version) ${outputDir}
.PHONY: release-server
clean:
@git clean -f
@rm -rf build
@rm -rf web/public
.PHONY: clean

101
SELF_HOSTING.md Normal file
View file

@ -0,0 +1,101 @@
# Hosting Dnote On Your Machine
This guide documents the steps for installing the Dnote server on your own machine.
**Please note that self hosted version of Dnote server is currently in beta.**
## Installation
1. Install Postgres 10+.
2. Create a `dnote` database by running `createdb dnote`
2. Download the official Dnote server release.
3. Extract the archive and move the `dnote-server` executable to `/usr/local/bin`.
```bash
tar -xzf dnote-server-$version-$os.tar.gz
chmod +x ./dnote-server/dnote-server
mv ./dnote-server/dnote-server /usr/local/bin
```
4. Run Dnote
```bash
GO_ENV=PRODUCTION \
DBHost=localhost \
DBPort=5432 \
DBName=dnote \
DBUser=$user \
DBPassword=$password \
dnote-server start
```
Replace $user and $password with the credentials of the Postgres user that owns the `dnote` database.
By default, dnote server will run on the port 8080.
## Configuration
By now, Dnote is fully functional in your machine. The API, frontend app, and the background tasks are all in the single binary. Let's take a few more steps to configure Dnote.
### Configure Nginx
To make it accessible from the Internet, you need to configure Nginx.
1. Create a new file in `/etc/nginx/sites-enabled/dnote` with the following contents:
```
server {
server_name my-dnote-server.com;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}
```
2. Reload the nginx configuration by running the following:
```
sudo service nginx reload
```
Now you can access the Dnote frontend application on `http://my-dnote-server.com`, and the API on `http://my-dnote-server.com/api`.
### Configure TLS by using LetsEncrypt
TODO
### Run Dnote As a Daemon
We can use `systemctl` to run Dnote in the background as a Daemon, and automatically start it on system reboot.
1. Create a new file at `/etc/systemd/system/dnote.service` with the following content:
```
[Unit]
Description=Starts the dnote server
Requires=network.target
After=network.target
[Service]
Type=simple
User=$user
Restart=always
RestartSec=3
WorkingDirectory=/home/$user
ExecStart=/home/$user/dnote-server start
Environment=GO_ENV=PRODUCTION DBHost=localhost DBPort=5432 DBName=dnote DBUser=$DBUser
Environment=DBPassword=$DBPassword
[Install]
WantedBy=multi-user.target
```
Replace `$user`, `$DBUser`, and `$DBPassword` with the actual values.
2. Reload the change by running `sudo systemctl daemon-reload`.
3. Enable the Daemon by running `sudo systemctl enable dnote`.`
4. Start the Daemon by running `sudo systemctl start dnote`

View file

@ -1,12 +0,0 @@
all:
./scripts/build.sh $(VERSION)
.PHONY: all
release:
./scripts/build.sh $(VERSION)
./scripts/release.sh $(VERSION)
.PHONY: release
clean:
@git clean -f
.PHONY: clean

View file

@ -113,18 +113,19 @@ hash_sha256() {
}
verify_checksum() {
binary_path=$1
filename=$2
checksums=$3
filepath=$1
checksums=$2
filename=$(basename "$filepath")
want=$(grep "${filename}" "${checksums}" 2>/dev/null | cut -d ' ' -f 1)
if [ -z "$want" ]; then
print_error "unable to find checksum for '${filename}' in '${checksums}'"
exit 1
fi
got=$(hash_sha256 "$binary_path")
got=$(hash_sha256 "$filepath")
if [ "$want" != "$got" ]; then
print_error "checksum for '$binary_path' did not verify ${want} vs $got"
print_error "checksum for '$filepath' did not verify ${want} vs $got"
exit 1
fi
}
@ -173,13 +174,13 @@ install_dnote() {
print_step "Downloading the checksum file for v$version"
http_download "$tmpdir/$checksum" "$checksum_url"
print_step "Comparing checksums for binaries."
verify_checksum "$tmpdir/$tarball" "$tmpdir/$checksum"
# unzip tar
print_step "Inflating the binary."
(cd "${tmpdir}" && tar -xzf "${tarball}")
print_step "Comparing checksums for binaries."
verify_checksum "${tmpdir}/${binary}" "$filename" "$tmpdir/$checksum"
install -d "${bindir}"
install "${tmpdir}/${binary}" "${bindir}/"

View file

@ -1,16 +1,15 @@
#!/bin/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
# 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.
# use: ./scripts/build.sh 0.4.8
set -eu
set -eux
version="$1"
version=$1
projectDir="$GOPATH/src/github.com/dnote/dnote"
basedir="$GOPATH/src/github.com/dnote/dnote/pkg/cli"
TMP="$basedir/build"
outputDir="$projectDir/build/cli"
command_exists () {
command -v "$1" >/dev/null 2>&1;
@ -29,78 +28,55 @@ if [[ $1 == v* ]]; then
exit 1
fi
goVersion=1.12.x
get_binary_name() {
platform=$1
if [ "$platform" == "windows" ]; then
echo "dnote.exe"
else
echo "dnote"
fi
}
build() {
# init build dir
rm -rf "$TMP"
mkdir "$TMP"
platform=$1
arch=$2
# fetch tool
go get -u github.com/karalabe/xgo
# build binary
destDir="$outputDir/$platform-$arch"
pushd "$basedir"
mkdir -p "$destDir"
xgo \
-go "$goVersion" \
-ldflags "-X main.apiEndpoint=https://api.dnote.io -X main.versionTag=$version" \
--targets="$platform/$arch" \
--tags "fts5" \
--dest="$destDir" \
"$basedir"
# build linux
xgo --targets="linux/amd64"\
--tags "linux fts5"\
-ldflags "-X main.apiEndpoint=https://api.dnote.io -X main.versionTag=$version" .
mkdir "$TMP/linux"
mv cli-linux-amd64 "$TMP/linux/dnote"
binaryName=$(get_binary_name "$platform")
mv "$destDir/cli-${platform}-"* "$destDir/$binaryName"
# build darwin
xgo --targets="darwin/amd64"\
--tags "darwin fts5"\
-ldflags "-X main.apiEndpoint=https://api.dnote.io -X main.versionTag=$version" .
mkdir "$TMP/darwin"
mv cli-darwin-10.6-amd64 "$TMP/darwin/dnote"
# build tarball
tarballName="dnote_${version}_${platform}_${arch}.tar.gz"
tarballPath="$outputDir/$tarballName"
# build windows
xgo --targets="windows/amd64"\
--tags "fts5"\
-ldflags "-X main.apiEndpoint=https://api.dnote.io -X main.versionTag=$version" .
mkdir "$TMP/windows"
mv cli-windows-4.0-amd64.exe "$TMP/windows/dnote.exe"
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
}
get_buildname() {
os=$1
echo "dnote_${version}_${os}_amd64"
}
calc_checksum() {
os=$1
pushd "$TMP/$os"
buildname=$(get_buildname "$os")
mv dnote "$buildname"
shasum -a 256 "$buildname" >> "$TMP/dnote_${version}_checksums.txt"
mv "$buildname" dnote
popd
}
build_tarball() {
os=$1
buildname=$(get_buildname "$os")
pushd "$TMP/$os"
cp "$projectDir/licenses/GPLv3.txt" .
cp "$basedir/README.md" .
tar -zcvf "../${buildname}.tar.gz" ./*
popd
}
build
calc_checksum darwin
calc_checksum linux
build_tarball windows
build_tarball darwin
build_tarball linux
# fetch tool
go get -u github.com/karalabe/xgo
build linux amd64
build darwin amd64
build windows amd64

View file

@ -1,58 +0,0 @@
#!/bin/bash
#
# release.sh releases the tarballs and checksum in the build directory
# to GitHub and brew. It is important to build those files using build.sh
# use: ./scripts/release.sh v0.4.8
set -eu
homebrewRepoDir="$GOPATH"/src/github.com/dnote/homebrew-dnote
command_exists () {
command -v "$1" >/dev/null 2>&1;
}
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
if ! command_exists hub; then
echo "please install hub"
exit 1
fi
if [ ! -d "$homebrewRepoDir" ]; then
echo "homebrew-dnote not found locally. did you clone it?"
exit 1
fi
# 1. push tag
version=$1
version_tag="cli-v$version"
echo "* tagging and pushing the tag"
git tag -a "$version_tag" -m "Release $version_tag"
git push --tags
# 2. release on GitHub
files=(./build/*.tar.gz ./build/*.txt)
file_args=()
for file in "${files[@]}"; do
file_args+=("--attach=$file")
done
echo "* creating release"
set -x
hub release create \
"${file_args[@]}" \
--message="$version_tag"\
"$version_tag"
# 3. Release on Homebrew
homebrew_sha256=$(shasum -a 256 "./build/dnote_${version}_darwin_amd64.tar.gz" | cut -d ' ' -f 1)
(cd "$homebrewRepoDir" && ./release.sh "$version" "$homebrew_sha256")

View file

@ -1,6 +1,6 @@
DB_HOST=localhost
POSTGRES_USER=sung
POSTGRES_DB=dnote
POSTGRES_USER=postgres
SmtpUsername=mock-SmtpUsername
SmtpPassword=mock-SmtpPassword

View file

@ -1,3 +1,3 @@
# Dnote Server
The server side infrastructure for Dnote.
The Dnote server containing the web interface, the web API, and the background jobs.

View file

@ -4,3 +4,4 @@ application.zip
test-api
/dump
api
/build

View file

@ -24,4 +24,5 @@ import (
func (a *App) checkHealth(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("ok"))
}

View file

@ -1,103 +0,0 @@
/* 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 (
"flag"
"fmt"
"log"
"net/http"
"os"
"github.com/dnote/dnote/pkg/server/api/clock"
"github.com/dnote/dnote/pkg/server/api/handlers"
"github.com/dnote/dnote/pkg/server/api/logger"
"github.com/dnote/dnote/pkg/server/database"
"github.com/dnote/dnote/pkg/server/mailer"
"github.com/gorilla/mux"
"github.com/gorilla/securecookie"
"github.com/gorilla/sessions"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
"github.com/markbates/goth/providers/github"
"github.com/markbates/goth/providers/gplus"
"github.com/pkg/errors"
)
var (
emailTemplateDir = flag.String("emailTemplateDir", "../mailer/templates/src", "the path to the template directory")
)
func getOauthCallbackURL(provider string) string {
if os.Getenv("GO_ENV") == "PRODUCTION" {
return fmt.Sprintf("%s/api/auth/%s/callback", os.Getenv("WebHost"), provider)
}
return fmt.Sprintf("%s:%s/api/auth/%s/callback", os.Getenv("Host"), os.Getenv("WebPort"), provider)
}
func init() {
// Set up Oauth
gothic.Store = sessions.NewCookieStore(securecookie.GenerateRandomKey(32), securecookie.GenerateRandomKey(32))
goth.UseProviders(
github.New(
os.Getenv("GithubClientID"),
os.Getenv("GithubClientSecret"),
getOauthCallbackURL("github"),
),
gplus.New(
os.Getenv("GoogleClientID"),
os.Getenv("GoogleClientSecret"),
getOauthCallbackURL("gplus"),
"https://www.googleapis.com/auth/plus.me",
),
)
gothic.GetProviderName = func(r *http.Request) (name string, err error) {
vars := mux.Vars(r)
name = vars["provider"]
return
}
}
func main() {
flag.Parse()
mailer.InitTemplates(*emailTemplateDir)
database.InitDB()
database.InitSchema()
defer database.CloseDB()
if err := logger.Init(); err != nil {
log.Println(errors.Wrap(err, "initializing logger"))
}
app := handlers.App{
Clock: clock.New(),
StripeAPIBackend: nil,
}
r := handlers.NewRouter(&app)
port := os.Getenv("PORT")
logger.Notice("API listening on port %s", port)
log.Println(http.ListenAndServe(":"+port, r))
}

View file

@ -0,0 +1,7 @@
#!/bin/bash
set -eux
basePath="$GOPATH/src/github.com/dnote/dnote/pkg/server/api"
cd "$basePath"
GOOS=linux GOARCH=amd64 go build -o "$basePath/build/api" main.go

View file

@ -1,13 +0,0 @@
#!/bin/bash
# dev.sh starts a development environment for the api.
# usage: DOTENV_PATH=path_to_dotenv_file EMAIL_TEMPLATE_DIR=path_to_email_templates ./dev.sh
set -eux
basePath="$GOPATH/src/github.com/dnote/dnote/pkg/server"
# load env
export $(cat "$DOTENV_PATH" | xargs)
PORT=5000 CompileDaemon \
-directory="$basePath"/api \
-command="$basePath/api/api --emailTemplateDir $basePath/mailer/templates/src"

View file

@ -28,6 +28,11 @@ import (
_ "github.com/lib/pq"
)
var (
// MigrationTableName is the name of the table that keeps track of migrations
MigrationTableName = "migrations"
)
func getPGConnectionString() string {
if os.Getenv("GO_ENV") == "PRODUCTION" {
return fmt.Sprintf(

View file

@ -0,0 +1,28 @@
package database
import (
"log"
"github.com/gobuffalo/packr/v2"
"github.com/pkg/errors"
"github.com/rubenv/sql-migrate"
)
// Migrate runs the migrations
func Migrate() error {
migrations := &migrate.PackrMigrationSource{
Box: packr.New("migrations", "../database/migrations/"),
}
migrate.SetTable(MigrationTableName)
db := DBConn.DB()
n, err := migrate.Exec(db, "postgres", migrations, migrate.Up)
if err != nil {
return errors.Wrap(err, "running migrations")
}
log.Printf("Performed %d migrations", n)
return nil
}

View file

@ -1,8 +0,0 @@
# a configuration for sql-migrate tool. We don't need to configure production,
# because we programmatically connect to the database and run migrations.
# Its main purpose is to generate migrations using `sql-migrate new`
development:
dialect: postgres
datasource: dbname=dnote sslmode=disable
dir: ./migrations

View file

@ -55,6 +55,8 @@ func main() {
Dir: *migrationDir,
}
migrate.SetTable("migrations")
n, err := migrate.Exec(db.DB(), "postgres", migrations, migrate.Up)
if err != nil {
panic(errors.Wrap(err, "executing migrations"))

View file

@ -18,4 +18,4 @@ if [ "$#" == 0 ]; then
fi
filename=$1
sql-migrate new -config=migrate.yml "$filename"
sql-migrate new -config=./sql-migrate.yml "$filename"

View file

@ -0,0 +1,8 @@
# A configuration for sql-migrate tool for generating migrations
# using `sql-migrate new`. This file is not actually used for running
# migrations because we run them programmatically.
development:
dialect: postgres
datasource: dbname=dnote sslmode=disable
dir: ./migrations

View file

@ -1,3 +0,0 @@
/tmp
/dnote-job.tar.gz
job

View file

@ -16,7 +16,7 @@
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
*/
package digest
package job
import (
"log"
@ -27,8 +27,8 @@ import (
"github.com/pkg/errors"
)
// Make builds a weekly digest email
func Make(user database.User, emailAddr string) (*mailer.Email, error) {
// makeDigest builds a weekly digest email
func makeDigest(user database.User, emailAddr string) (*mailer.Email, error) {
log.Printf("Sending for %s", emailAddr)
db := database.DBConn
@ -92,8 +92,8 @@ func Make(user database.User, emailAddr string) (*mailer.Email, error) {
return email, nil
}
// Send sends the weekly digests to users
func Send() error {
// sendDigest sends the weekly digests to users
func sendDigest() error {
db := database.DBConn
var users []database.User
@ -111,7 +111,7 @@ func Send() error {
continue
}
email, err := Make(user, account.Email.String)
email, err := makeDigest(user, account.Email.String)
if err != nil {
log.Printf("Error occurred while sending to %s: %s", account.Email.String, err.Error())
continue

View file

@ -16,42 +16,15 @@
* along with Dnote. If not, see <https://www.gnu.org/licenses/>.
*/
package main
package job
import (
"flag"
"log"
"os"
"github.com/dnote/dnote/pkg/server/database"
"github.com/dnote/dnote/pkg/server/job/digest"
"github.com/dnote/dnote/pkg/server/mailer"
"github.com/joho/godotenv"
_ "github.com/lib/pq"
"github.com/pkg/errors"
"github.com/robfig/cron"
)
var (
emailTemplateDir = flag.String("emailTemplateDir", "../mailer/templates/src", "the path to the template directory")
)
func init() {
// Load env
if os.Getenv("GO_ENV") == "PRODUCTION" {
err := godotenv.Load(".env")
if err != nil {
panic(err)
}
} else {
err := godotenv.Load(".env.dev")
if err != nil {
panic(err)
}
}
}
func scheduleJob(c *cron.Cron, spec string, cmd func()) {
s, err := cron.ParseStandard(spec)
if err != nil {
@ -61,22 +34,13 @@ func scheduleJob(c *cron.Cron, spec string, cmd func()) {
c.Schedule(s, cron.FuncJob(cmd))
}
func main() {
flag.Parse()
mailer.InitTemplates(*emailTemplateDir)
database.InitDB()
defer database.CloseDB()
// Run jobs on initial start
log.Println("Job is running")
// Run starts the background tasks and blocks forever.
func Run() {
log.Println("Started background tasks")
// Schedule jobs
c := cron.New()
scheduleJob(c, "0 20 * * 5", func() { digest.Send() })
scheduleJob(c, "0 20 * * 5", func() { sendDigest() })
c.Start()
// Block forever

View file

@ -1 +0,0 @@
CompileDaemon -directory=. -command="./job"

View file

@ -27,6 +27,7 @@ import (
"path"
"github.com/aymerick/douceur/inliner"
"github.com/gobuffalo/packr/v2"
"github.com/pkg/errors"
"gopkg.in/gomail.v2"
)
@ -54,26 +55,45 @@ func getTemplatePath(templateDirPath, filename string) string {
// initTemplate returns a template instance by parsing the template with the
// given name along with partials
func initTemplate(templateDirPath, templateFileName string) (*template.Template, error) {
templatePath := getTemplatePath(templateDirPath, templateFileName)
headerPath := getTemplatePath(templateDirPath, "header")
footerPath := getTemplatePath(templateDirPath, "footer")
func initTemplate(box *packr.Box, templateName string) (*template.Template, error) {
filename := fmt.Sprintf("%s.html", templateName)
t, err := template.ParseFiles(templatePath, headerPath, footerPath)
content, err := box.FindString(filename)
if err != nil {
return nil, errors.Wrap(err, "parseing template")
return nil, errors.Wrap(err, "reading template")
}
headerContent, err := box.FindString("header.html")
if err != nil {
return nil, errors.Wrap(err, "reading header template")
}
footerContent, err := box.FindString("footer.html")
if err != nil {
return nil, errors.Wrap(err, "reading footer template")
}
t := template.New(templateName)
if _, err = t.Parse(content); err != nil {
return nil, errors.Wrap(err, "parsing template")
}
if _, err = t.Parse(headerContent); err != nil {
return nil, errors.Wrap(err, "parsing template")
}
if _, err = t.Parse(footerContent); err != nil {
return nil, errors.Wrap(err, "parsing template")
}
return t, nil
}
// InitTemplates initializes templates
func InitTemplates(templateDirPath string) {
weeklyDigestTmpl, err := initTemplate(templateDirPath, EmailTypeWeeklyDigest)
func InitTemplates() {
box := packr.New("emailTemplates", "../mailer/templates/src")
weeklyDigestTmpl, err := initTemplate(box, EmailTypeWeeklyDigest)
if err != nil {
panic(errors.Wrap(err, "initializing template"))
}
emailVerificationTmpl, err := initTemplate(templateDirPath, EmailTypeEmailVerification)
emailVerificationTmpl, err := initTemplate(box, EmailTypeEmailVerification)
if err != nil {
panic(errors.Wrap(err, "initializing template"))
}

127
pkg/server/main.go Normal file
View file

@ -0,0 +1,127 @@
/* 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 (
"flag"
"fmt"
"log"
"net/http"
"strings"
"github.com/dnote/dnote/pkg/server/api/clock"
"github.com/dnote/dnote/pkg/server/api/handlers"
"github.com/dnote/dnote/pkg/server/database"
"github.com/dnote/dnote/pkg/server/job"
"github.com/dnote/dnote/pkg/server/mailer"
"github.com/gobuffalo/packr/v2"
"github.com/gorilla/mux"
"github.com/pkg/errors"
)
var versionTag = "master"
var port = flag.String("port", "8080", "port to connect to")
func init() {
}
func getAppHandler() http.HandlerFunc {
box := packr.New("web", "../../web/public")
fs := http.FileServer(box)
appShell, err := box.Find("index.html")
if err != nil {
panic(errors.Wrap(err, "getting index.html content"))
}
return func(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) >= 2 && parts[1] == "dist" {
fs.ServeHTTP(w, r)
return
}
// All other requests should serve the index.html file
w.Write(appShell)
}
}
func initServer() *mux.Router {
srv := mux.NewRouter()
apiRouter := handlers.NewRouter(&handlers.App{
Clock: clock.New(),
StripeAPIBackend: nil,
})
srv.PathPrefix("/api").Handler(http.StripPrefix("/api", apiRouter))
srv.PathPrefix("/").HandlerFunc(getAppHandler())
return srv
}
func startCmd() {
mailer.InitTemplates()
database.InitDB()
database.InitSchema()
defer database.CloseDB()
// Perform database migration
if err := database.Migrate(); err != nil {
panic(errors.Wrap(err, "running migrations"))
}
// Run job in the background
go job.Run()
srv := initServer()
log.Printf("Dnote version %s is running on port %s", versionTag, *port)
addr := fmt.Sprintf(":%s", *port)
log.Println(http.ListenAndServe(addr, srv))
}
func versionCmd() {
fmt.Printf("dnote-server-%s\n", versionTag)
}
func main() {
flag.Parse()
cmd := flag.Arg(0)
switch cmd {
case "":
fmt.Printf(`Dnote Server - A simple notebook for developers
Usage:
dnote-server [command]
Available commands:
start: Start the server
version: Print the version
`)
case "start":
startCmd()
case "version":
versionCmd()
default:
fmt.Printf("Unknown command %s", cmd)
}
}

60
pkg/server/scripts/build.sh Executable file
View file

@ -0,0 +1,60 @@
#!/bin/bash
set -eux
version=$1
basePath="$GOPATH/src/github.com/dnote/dnote"
projectDir="$GOPATH/src/github.com/dnote/dnote"
basedir="$GOPATH/src/github.com/dnote/dnote/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" \
"$basePath"/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

54
scripts/release.sh Executable file
View file

@ -0,0 +1,54 @@
#!/bin/bash
#
# release.sh releases the tarballs and checksum in the build directory
# to GitHub and brew. A prerequisite is to build those files using build.sh.
# use: ./scripts/release.sh cli v0.4.8 path/to/assets
set -euxo pipefail
project=$1
version=$2
assetPath=$3
if [ "$project" != "cli" ] || [ "$project" != "server" ]; then
echo "unrecognized project '$project'"
exit 1
fi
if [ -z "$version" ]; then
echo "no version specified."
exit 1
fi
if [[ $version == v* ]]; then
echo "do not prefix version with v"
exit 1
fi
# 1. push tag
version=$1
version_tag="$project-v$version"
echo "* tagging and pushing the tag"
git tag -a "$version_tag" -m "Release $version_tag"
git push --tags
# 2. release on GitHub
files=("$assetPath"/*)
file_flags=()
for file in "${files[@]}"; do
file_flags+=("--attach=$file")
done
# mark as prerelease if version is not in a form of major.minor.patch
# e.g. 1.0.1-beta.1
flags=()
if [[ ! "$version" =~ ^[0-9]+.[0-9]+.[0-9]+$ ]]; then
flags+=("--prerelease")
fi
echo "* creating release"
set -x
hub release create \
"${file_flags[@]}" \
"${flags[@]}" \
--message="$version_tag"\
"$version_tag"

View file

@ -1 +0,0 @@
API_HOST=http://localhost:5000/

View file

@ -1,72 +0,0 @@
/* 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 (
"log"
"net/http"
"net/http/httputil"
"net/url"
"os"
"strings"
"github.com/joho/godotenv"
"github.com/pkg/errors"
)
var apiProxy *httputil.ReverseProxy
func appHandler(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) >= 2 && parts[1] == "dist" {
fs := http.StripPrefix("/dist/", http.FileServer(http.Dir("./public/dist")))
fs.ServeHTTP(w, r)
return
}
// All other requests should go to index.html
http.ServeFile(w, r, "./public/index.html")
}
func init() {
if os.Getenv("GO_ENV") != "PRODUCTION" {
err := godotenv.Load(".env.dev")
if err != nil {
panic(errors.Wrap(err, "loading env vars"))
}
}
apiHostURL, err := url.Parse(os.Getenv("API_HOST"))
if err != nil {
panic(errors.Wrap(err, "parsing api host url"))
}
apiProxy = httputil.NewSingleHostReverseProxy(apiHostURL)
}
func main() {
http.HandleFunc("/", appHandler)
http.Handle("/api/", http.StripPrefix("/api/", apiProxy))
port := os.Getenv("PORT")
log.Printf("Web listening on port %s", port)
log.Println(http.ListenAndServe(":"+port, nil))
}

41
web/package-lock.json generated
View file

@ -5084,8 +5084,7 @@
},
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
"optional": true
"bundled": true
},
"aproba": {
"version": "1.2.0",
@ -5103,13 +5102,11 @@
},
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"optional": true
"bundled": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@ -5122,18 +5119,15 @@
},
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"optional": true
"bundled": true
},
"core-util-is": {
"version": "1.0.2",
@ -5236,8 +5230,7 @@
},
"inherits": {
"version": "2.0.3",
"bundled": true,
"optional": true
"bundled": true
},
"ini": {
"version": "1.3.5",
@ -5247,7 +5240,6 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@ -5260,20 +5252,17 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
"bundled": true,
"optional": true
"bundled": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@ -5290,7 +5279,6 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
@ -5363,8 +5351,7 @@
},
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"optional": true
"bundled": true
},
"object-assign": {
"version": "4.1.1",
@ -5374,7 +5361,6 @@
"once": {
"version": "1.4.0",
"bundled": true,
"optional": true,
"requires": {
"wrappy": "1"
}
@ -5450,8 +5436,7 @@
},
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
"optional": true
"bundled": true
},
"safer-buffer": {
"version": "2.1.2",
@ -5481,7 +5466,6 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@ -5499,7 +5483,6 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@ -5538,13 +5521,11 @@
},
"wrappy": {
"version": "1.0.2",
"bundled": true,
"optional": true
"bundled": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
"optional": true
"bundled": true
}
}
},

View file

@ -6,12 +6,8 @@ basePath="$GOPATH/src/github.com/dnote/dnote"
publicPath="$basePath/web/public"
compiledPath="$basePath/web/compiled"
baseUrl=https://dnote.io
assetBaseUrl=https://dnote.io
# baseUrl=http://localhost:3000
# assetBaseUrl=http://localhost:3000
baseUrl=""
assetBaseUrl=""
STANDALONE=true \
BASE_URL=$baseUrl \
@ -19,4 +15,3 @@ ASSET_BASE_URL=$assetBaseUrl \
PUBLIC_PATH=$publicPath \
COMPILED_PATH=$compiledPath \
"$basePath"/web/scripts/build.sh

View file

@ -1,11 +1,15 @@
#!/bin/bash
# build.sh builds a production bundle
set -eux
# build.sh builds a bundle
set -ex
basePath="$GOPATH/src/github.com/dnote/dnote"
standalone=${STANDALONE:-false}
isTest=${IS_TEST:-false}
baseUrl=$BASE_URL
assetBaseUrl=$ASSET_BASE_URL
set -u
rm -rf "$basePath/web/public"
mkdir -p "$basePath/web/public/dist"
@ -23,11 +27,11 @@ pushd "$basePath/web"
--config "$basePath"/web/webpack/prod.config.js
NODE_ENV=PRODUCTION \
BASE_URL=$BASE_URL \
ASSET_BASE_URL=$ASSET_BASE_URL \
BASE_URL=$baseUrl \
ASSET_BASE_URL=$assetBaseUrl \
PUBLIC_PATH=$PUBLIC_PATH \
COMPILED_PATH=$COMPILED_PATH \
"$basePath"/web/scripts/placeholder.sh
node "$basePath"/web/scripts/placeholder.js
cp "$COMPILED_PATH"/*.js "$COMPILED_PATH"/*.css "$PUBLIC_PATH"/dist

View file

@ -1,11 +1,25 @@
#!/bin/bash
# shellcheck disable=SC1090
# dev.sh builds and starts development environment for standalone app
set -eux -o pipefail
basePath="$GOPATH/src/github.com/dnote/dnote"
appPath="$basePath"/web
# clean up background processes
function cleanup {
kill "$devServerPID"
}
trap cleanup EXIT
# run webpack-dev-server for js
basePath="$GOPATH/src/github.com/dnote/dnote"
appPath="$basePath/web"
serverPath="$basePath/pkg/server"
# load env
set -a
dotenvPath="$serverPath/.env.dev"
source "$dotenvPath"
set +a
# run webpack-dev-server for js in the background
(
cd "$appPath" &&
@ -18,6 +32,7 @@ appPath="$basePath"/web
IS_TEST=true \
"$appPath"/scripts/webpack-dev.sh
) &
devServerPID=$!
# run server
(cd "$appPath" && PORT=3000 go run main.go)
(cd "$serverPath" && go run main.go)

29
web/scripts/placeholder.js Normal file → Executable file
View file

@ -1,20 +1,4 @@
/* 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/>.
*/
#!/usr/bin/env node
// 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
@ -23,8 +7,16 @@
const fs = require('fs');
const path = require('path');
const baseURL = process.env.BASE_URL;
const assetBaseURL = process.env.ASSET_BASE_URL;
const publicPath = process.env.PUBLIC_PATH;
const compiledPath = process.env.COMPILED_PATH;
if (!publicPath) {
throw new Error('No PUBLIC_PATH environment variable found');
}
if (!compiledPath) {
throw new Error('No COMPILED_PATH environment variable found');
}
const indexHtmlPath = `${publicPath}/index.html`;
@ -39,9 +31,6 @@ try {
const isProduction = process.env.NODE_ENV === 'PRODUCTION';
const baseURL = process.env.BASE_URL;
const assetBaseURL = process.env.ASSET_BASE_URL;
function getJSBundleTag() {
let jsBundleUrl;
if (isProduction) {

View file

@ -1,27 +0,0 @@
#!/bin/bash
set -eux
basePath="$GOPATH/src/github.com/dnote/dnote"
if [ -z "$BASE_URL" ]; then
echo "BASE_URL environment variable is not set"
exit 1
fi
if [ -z "$ASSET_BASE_URL" ]; then
echo "ASSET_BASE_URL environment variable is not set"
exit 1
fi
if [ -z "$PUBLIC_PATH" ]; then
echo "PUBLIC_PATH environment variable is not set"
exit 1
fi
if [ -z "$COMPILED_PATH" ]; then
echo "COMPILED_PATH environment variable is not set"
exit 1
fi
BASE_URL=$BASE_URL \
ASSET_BASE_URL=$ASSET_BASE_URL \
PUBLIC_PATH=$PUBLIC_PATH \
COMPILED_PATH=$COMPILED_PATH \
node "$basePath/web/scripts/placeholder.js"

View file

@ -1,6 +0,0 @@
#!/bin/bash
# start.sh starts the server
export PORT=3000
go run main.go

View file

@ -15,7 +15,7 @@ appPath="$basePath"/web
COMPILED_PATH=$COMPILED_PATH \
PUBLIC_PATH=$PUBLIC_PATH \
IS_TEST=true \
"$appPath"/scripts/placeholder.sh &&
node "$appPath"/scripts/placeholder.js &&
"$appPath"/node_modules/.bin/webpack-dev-server\
--env.standalone="$STANDALONE"\