mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-20 14:01:24 +00:00
chore: update golangci-lint config
This commit is contained in:
parent
a58ebd27ca
commit
07e0bb2d4c
@ -1,5 +1,6 @@
|
|||||||
linters:
|
linters:
|
||||||
enable:
|
enable:
|
||||||
|
- errcheck
|
||||||
- goimports
|
- goimports
|
||||||
- revive
|
- revive
|
||||||
- govet
|
- govet
|
||||||
@ -10,17 +11,30 @@ linters:
|
|||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- nilerr
|
- nilerr
|
||||||
- godot
|
- godot
|
||||||
|
- forbidigo
|
||||||
|
- mirror
|
||||||
|
- bodyclose
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
|
include:
|
||||||
|
# https://golangci-lint.run/usage/configuration/#command-line-options
|
||||||
exclude:
|
exclude:
|
||||||
- Rollback
|
- Rollback
|
||||||
|
- logger.Sync
|
||||||
|
- pgInstance.Stop
|
||||||
- fmt.Printf
|
- fmt.Printf
|
||||||
- fmt.Print
|
- Enter(.*)_(.*)
|
||||||
|
- Exit(.*)_(.*)
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
|
goimports:
|
||||||
|
# Put imports beginning with prefix after 3rd-party packages.
|
||||||
|
local-prefixes: github.com/boojack/slash
|
||||||
revive:
|
revive:
|
||||||
|
# Default to run all linters so that new rules in the future could automatically be added to the static check.
|
||||||
enable-all-rules: true
|
enable-all-rules: true
|
||||||
rules:
|
rules:
|
||||||
|
# The following rules are too strict and make coding harder. We do not enable them for now.
|
||||||
- name: file-header
|
- name: file-header
|
||||||
disabled: true
|
disabled: true
|
||||||
- name: line-length-limit
|
- name: line-length-limit
|
||||||
@ -59,9 +73,14 @@ linters-settings:
|
|||||||
- ifElseChain
|
- ifElseChain
|
||||||
govet:
|
govet:
|
||||||
settings:
|
settings:
|
||||||
printf:
|
printf: # The name of the analyzer, run `go tool vet help` to see the list of all analyzers
|
||||||
funcs:
|
funcs: # Run `go tool vet help printf` to see the full configuration of `printf`.
|
||||||
- common.Errorf
|
- common.Errorf
|
||||||
|
enable-all: true
|
||||||
|
disable:
|
||||||
|
- fieldalignment
|
||||||
|
- shadow
|
||||||
forbidigo:
|
forbidigo:
|
||||||
forbid:
|
forbid:
|
||||||
- 'fmt\.Errorf(# Please use errors\.Wrap\|Wrapf\|Errorf instead)?'
|
- 'fmt\.Errorf(# Please use errors\.Wrap\|Wrapf\|Errorf instead)?'
|
||||||
|
- 'ioutil\.ReadDir(# Please use os\.ReadDir)?'
|
||||||
|
@ -6,10 +6,11 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/mssola/useragent"
|
"github.com/mssola/useragent"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ReferenceInfo struct {
|
type ReferenceInfo struct {
|
||||||
|
@ -7,12 +7,13 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/boojack/slash/api/auth"
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/api/auth"
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SignInRequest struct {
|
type SignInRequest struct {
|
||||||
|
@ -5,13 +5,14 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/boojack/slash/api/auth"
|
"github.com/boojack/slash/api/auth"
|
||||||
"github.com/boojack/slash/internal/util"
|
"github.com/boojack/slash/internal/util"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/golang-jwt/jwt/v4"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -8,10 +8,11 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *APIV1Service) registerRedirectorRoutes(g *echo.Group) {
|
func (s *APIV1Service) registerRedirectorRoutes(g *echo.Group) {
|
||||||
|
@ -7,11 +7,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/boojack/slash/internal/util"
|
"github.com/boojack/slash/internal/util"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Visibility is the type of a shortcut visibility.
|
// Visibility is the type of a shortcut visibility.
|
||||||
|
@ -6,10 +6,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/mail"
|
"net/mail"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
"github.com/boojack/slash/internal/util"
|
"github.com/boojack/slash/internal/util"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -60,13 +62,13 @@ type CreateUserRequest struct {
|
|||||||
|
|
||||||
func (create CreateUserRequest) Validate() error {
|
func (create CreateUserRequest) Validate() error {
|
||||||
if create.Email != "" && !validateEmail(create.Email) {
|
if create.Email != "" && !validateEmail(create.Email) {
|
||||||
return fmt.Errorf("invalid email format")
|
return errors.New("invalid email format")
|
||||||
}
|
}
|
||||||
if create.Nickname != "" && len(create.Nickname) < 3 {
|
if create.Nickname != "" && len(create.Nickname) < 3 {
|
||||||
return fmt.Errorf("nickname is too short, minimum length is 3")
|
return errors.New("nickname is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
if len(create.Password) < 3 {
|
if len(create.Password) < 3 {
|
||||||
return fmt.Errorf("password is too short, minimum length is 3")
|
return errors.New("password is too short, minimum length is 3")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -2,7 +2,8 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserSettingKey string
|
type UserSettingKey string
|
||||||
@ -39,7 +40,7 @@ func (upsert UserSettingUpsert) Validate() error {
|
|||||||
localeValue := "en"
|
localeValue := "en"
|
||||||
err := json.Unmarshal([]byte(upsert.Value), &localeValue)
|
err := json.Unmarshal([]byte(upsert.Value), &localeValue)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to unmarshal user setting locale value")
|
return errors.New("failed to unmarshal user setting locale value")
|
||||||
}
|
}
|
||||||
|
|
||||||
invalid := true
|
invalid := true
|
||||||
@ -50,10 +51,10 @@ func (upsert UserSettingUpsert) Validate() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if invalid {
|
if invalid {
|
||||||
return fmt.Errorf("invalid user setting locale value")
|
return errors.New("invalid user setting locale value")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("invalid user setting key")
|
return errors.New("invalid user setting key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/server/service/license"
|
"github.com/boojack/slash/server/service/license"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type APIV1Service struct {
|
type APIV1Service struct {
|
||||||
|
@ -4,10 +4,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type WorkspaceProfile struct {
|
type WorkspaceProfile struct {
|
||||||
|
@ -5,16 +5,17 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/boojack/slash/api/auth"
|
|
||||||
"github.com/boojack/slash/internal/util"
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/api/auth"
|
||||||
|
"github.com/boojack/slash/internal/util"
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContextKey is the key type of context value.
|
// ContextKey is the key type of context value.
|
||||||
|
@ -3,13 +3,14 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
|
||||||
|
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ShortcutService struct {
|
type ShortcutService struct {
|
||||||
|
@ -3,12 +3,13 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/server/service/license"
|
"github.com/boojack/slash/server/service/license"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type SubscriptionService struct {
|
type SubscriptionService struct {
|
||||||
|
@ -4,10 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/boojack/slash/api/auth"
|
|
||||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/golang-jwt/jwt/v4"
|
"github.com/golang-jwt/jwt/v4"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
@ -15,6 +11,11 @@ import (
|
|||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/api/auth"
|
||||||
|
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserService struct {
|
type UserService struct {
|
||||||
|
@ -3,12 +3,13 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
|
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type UserSettingService struct {
|
type UserSettingService struct {
|
||||||
|
@ -4,16 +4,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
|
||||||
"github.com/boojack/slash/server/profile"
|
|
||||||
"github.com/boojack/slash/server/service/license"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||||
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
"github.com/improbable-eng/grpc-web/go/grpcweb"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/credentials/insecure"
|
"google.golang.org/grpc/credentials/insecure"
|
||||||
"google.golang.org/grpc/reflection"
|
"google.golang.org/grpc/reflection"
|
||||||
|
|
||||||
|
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||||
|
"github.com/boojack/slash/server/profile"
|
||||||
|
"github.com/boojack/slash/server/service/license"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type APIV2Service struct {
|
type APIV2Service struct {
|
||||||
|
@ -3,13 +3,14 @@ package v2
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/server/service/license"
|
"github.com/boojack/slash/server/service/license"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/status"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type WorkspaceService struct {
|
type WorkspaceService struct {
|
||||||
|
@ -8,15 +8,16 @@ import (
|
|||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/boojack/slash/internal/log"
|
|
||||||
"github.com/boojack/slash/server"
|
|
||||||
_profile "github.com/boojack/slash/server/profile"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/boojack/slash/store/db"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
_ "modernc.org/sqlite"
|
_ "modernc.org/sqlite"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/internal/log"
|
||||||
|
"github.com/boojack/slash/server"
|
||||||
|
"github.com/boojack/slash/server/profile"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
|
"github.com/boojack/slash/store/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -24,25 +25,25 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
profile *_profile.Profile
|
serverProfile *profile.Profile
|
||||||
mode string
|
mode string
|
||||||
port int
|
port int
|
||||||
data string
|
data string
|
||||||
|
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
Use: "slash",
|
Use: "slash",
|
||||||
Short: `An open source, self-hosted bookmarks and link sharing platform.`,
|
Short: `An open source, self-hosted bookmarks and link sharing platform.`,
|
||||||
Run: func(_cmd *cobra.Command, _args []string) {
|
Run: func(_cmd *cobra.Command, _args []string) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
db := db.NewDB(profile)
|
db := db.NewDB(serverProfile)
|
||||||
if err := db.Open(ctx); err != nil {
|
if err := db.Open(ctx); err != nil {
|
||||||
cancel()
|
cancel()
|
||||||
log.Error("failed to open database", zap.Error(err))
|
log.Error("failed to open database", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
storeInstance := store.New(db.DBInstance, profile)
|
storeInstance := store.New(db.DBInstance, serverProfile)
|
||||||
s, err := server.NewServer(ctx, profile, storeInstance)
|
s, err := server.NewServer(ctx, serverProfile, storeInstance)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cancel()
|
cancel()
|
||||||
log.Error("failed to create server", zap.Error(err))
|
log.Error("failed to create server", zap.Error(err))
|
||||||
@ -109,7 +110,7 @@ func init() {
|
|||||||
func initConfig() {
|
func initConfig() {
|
||||||
viper.AutomaticEnv()
|
viper.AutomaticEnv()
|
||||||
var err error
|
var err error
|
||||||
profile, err = _profile.GetProfile()
|
serverProfile, err = profile.GetProfile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("failed to get profile", zap.Error(err))
|
log.Error("failed to get profile", zap.Error(err))
|
||||||
return
|
return
|
||||||
@ -117,20 +118,20 @@ func initConfig() {
|
|||||||
|
|
||||||
println("---")
|
println("---")
|
||||||
println("Server profile")
|
println("Server profile")
|
||||||
println("dsn:", profile.DSN)
|
println("dsn:", serverProfile.DSN)
|
||||||
println("port:", profile.Port)
|
println("port:", serverProfile.Port)
|
||||||
println("mode:", profile.Mode)
|
println("mode:", serverProfile.Mode)
|
||||||
println("version:", profile.Version)
|
println("version:", serverProfile.Version)
|
||||||
println("---")
|
println("---")
|
||||||
}
|
}
|
||||||
|
|
||||||
func printGreetings() {
|
func printGreetings() {
|
||||||
fmt.Println(greetingBanner)
|
println(greetingBanner)
|
||||||
fmt.Printf("Version %s has been started on port %d\n", profile.Version, profile.Port)
|
fmt.Printf("Version %s has been started on port %d\n", serverProfile.Version, serverProfile.Port)
|
||||||
fmt.Println("---")
|
println("---")
|
||||||
fmt.Println("See more in:")
|
println("See more in:")
|
||||||
fmt.Printf("👉GitHub: %s\n", "https://github.com/boojack/slash")
|
fmt.Printf("👉GitHub: %s\n", "https://github.com/boojack/slash")
|
||||||
fmt.Println("---")
|
println("---")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
@ -28,7 +28,7 @@ const SignIn: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mode === "demo") {
|
if (mode === "demo") {
|
||||||
setEmail("steven@usememos.com");
|
setEmail("steven@yourselfhosted.com");
|
||||||
setPassword("secret");
|
setPassword("secret");
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
package cron
|
||||||
|
|
||||||
// Package cron implements a crontab-like service to execute and schedule
|
// Package cron implements a crontab-like service to execute and schedule
|
||||||
// repeative tasks/jobs.
|
// repeative tasks/jobs.
|
||||||
//
|
//
|
||||||
@ -6,13 +8,12 @@
|
|||||||
// c := cron.New()
|
// c := cron.New()
|
||||||
// c.MustAdd("dailyReport", "0 0 * * *", func() { ... })
|
// c.MustAdd("dailyReport", "0 0 * * *", func() { ... })
|
||||||
// c.Start()
|
// c.Start()
|
||||||
package cron
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type job struct {
|
type job struct {
|
||||||
@ -90,7 +91,7 @@ func (c *Cron) Add(jobID string, cronExpr string, run func()) error {
|
|||||||
|
|
||||||
schedule, err := NewSchedule(cronExpr)
|
schedule, err := NewSchedule(cronExpr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to add new cron job: %w", err)
|
return errors.Wrap(err, "failed to add new cron job")
|
||||||
}
|
}
|
||||||
|
|
||||||
c.jobs[jobID] = &job{
|
c.jobs[jobID] = &job{
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package cron
|
package cron
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Moment represents a parsed single time moment.
|
// Moment represents a parsed single time moment.
|
||||||
@ -132,7 +132,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if parsedStep < 1 || parsedStep > max {
|
if parsedStep < 1 || parsedStep > max {
|
||||||
return nil, fmt.Errorf("invalid segment step boundary - the step must be between 1 and the %d", max)
|
return nil, errors.New("invalid segment step boundary")
|
||||||
}
|
}
|
||||||
step = parsedStep
|
step = parsedStep
|
||||||
default:
|
default:
|
||||||
@ -167,7 +167,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if parsedMin < min || parsedMin > max {
|
if parsedMin < min || parsedMin > max {
|
||||||
return nil, fmt.Errorf("invalid segment range minimum - must be between %d and %d", min, max)
|
return nil, errors.New("invalid segment range minimum")
|
||||||
}
|
}
|
||||||
rangeMin = parsedMin
|
rangeMin = parsedMin
|
||||||
|
|
||||||
@ -176,7 +176,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if parsedMax < parsedMin || parsedMax > max {
|
if parsedMax < parsedMin || parsedMax > max {
|
||||||
return nil, fmt.Errorf("invalid segment range maximum - must be between %d and %d", rangeMin, max)
|
return nil, errors.New("invalid segment range maximum")
|
||||||
}
|
}
|
||||||
rangeMax = parsedMax
|
rangeMax = parsedMax
|
||||||
default:
|
default:
|
||||||
|
@ -5,9 +5,10 @@ import (
|
|||||||
"io/fs"
|
"io/fs"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/boojack/slash/internal/util"
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed dist
|
//go:embed dist
|
||||||
|
@ -7,8 +7,10 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/boojack/slash/server/version"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/server/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Profile is the configuration to start main server.
|
// Profile is the configuration to start main server.
|
||||||
@ -44,7 +46,7 @@ func checkDSN(dataDir string) (string, error) {
|
|||||||
dataDir = strings.TrimRight(dataDir, "\\/")
|
dataDir = strings.TrimRight(dataDir, "\\/")
|
||||||
|
|
||||||
if _, err := os.Stat(dataDir); err != nil {
|
if _, err := os.Stat(dataDir); err != nil {
|
||||||
return "", fmt.Errorf("unable to access data folder %s, err %w", dataDir, err)
|
return "", errors.Wrapf(err, "unable to access data folder %s", dataDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
return dataDir, nil
|
return dataDir, nil
|
||||||
|
@ -6,11 +6,12 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/h2non/filetype"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/h2non/filetype"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ResourceService struct {
|
type ResourceService struct {
|
||||||
|
@ -8,15 +8,17 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
apiv1 "github.com/boojack/slash/api/v1"
|
apiv1 "github.com/boojack/slash/api/v1"
|
||||||
apiv2 "github.com/boojack/slash/api/v2"
|
apiv2 "github.com/boojack/slash/api/v2"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/server/service/license"
|
"github.com/boojack/slash/server/service/license"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/labstack/echo/v4/middleware"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
@ -102,7 +104,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
|
|||||||
s.apiV2Service = apiv2.NewAPIV2Service(secret, profile, store, licenseService, s.Profile.Port+1)
|
s.apiV2Service = apiv2.NewAPIV2Service(secret, profile, store, licenseService, s.Profile.Port+1)
|
||||||
// Register gRPC gateway as api v2.
|
// Register gRPC gateway as api v2.
|
||||||
if err := s.apiV2Service.RegisterGateway(ctx, e); err != nil {
|
if err := s.apiV2Service.RegisterGateway(ctx, e); err != nil {
|
||||||
return nil, fmt.Errorf("failed to register gRPC gateway: %w", err)
|
return nil, errors.Wrap(err, "failed to register gRPC gateway")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register resource service.
|
// Register resource service.
|
||||||
|
@ -4,12 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"google.golang.org/protobuf/types/known/timestamppb"
|
||||||
|
|
||||||
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
apiv2pb "github.com/boojack/slash/proto/gen/api/v2"
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type LicenseService struct {
|
type LicenseService struct {
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"embed"
|
"embed"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
@ -12,6 +11,8 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/server/version"
|
"github.com/boojack/slash/server/version"
|
||||||
)
|
)
|
||||||
@ -39,7 +40,7 @@ func NewDB(profile *profile.Profile) *DB {
|
|||||||
func (db *DB) Open(ctx context.Context) (err error) {
|
func (db *DB) Open(ctx context.Context) (err error) {
|
||||||
// Ensure a DSN is set before attempting to open the database.
|
// Ensure a DSN is set before attempting to open the database.
|
||||||
if db.profile.DSN == "" {
|
if db.profile.DSN == "" {
|
||||||
return fmt.Errorf("dsn required")
|
return errors.New("dsn required")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect to the database with some sane settings:
|
// Connect to the database with some sane settings:
|
||||||
@ -58,7 +59,7 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
|||||||
// - https://www.sqlite.org/pragma.html
|
// - https://www.sqlite.org/pragma.html
|
||||||
sqliteDB, err := sql.Open("sqlite", db.profile.DSN+"?_pragma=foreign_keys(0)&_pragma=busy_timeout(10000)&_pragma=journal_mode(WAL)")
|
sqliteDB, err := sql.Open("sqlite", db.profile.DSN+"?_pragma=foreign_keys(0)&_pragma=busy_timeout(10000)&_pragma=journal_mode(WAL)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open db with dsn: %s, err: %w", db.profile.DSN, err)
|
return errors.Wrapf(err, "failed to open db with dsn: %s", db.profile.DSN)
|
||||||
}
|
}
|
||||||
db.DBInstance = sqliteDB
|
db.DBInstance = sqliteDB
|
||||||
|
|
||||||
@ -68,24 +69,24 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
|||||||
// If db file not exists, we should create a new one with latest schema.
|
// If db file not exists, we should create a new one with latest schema.
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
if err := db.applyLatestSchema(ctx); err != nil {
|
if err := db.applyLatestSchema(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to apply latest schema, err: %w", err)
|
return errors.Wrap(err, "failed to apply latest schema")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("failed to get db file stat, err: %w", err)
|
return errors.Wrap(err, "failed to get db file stat")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If db file exists, we should check if we need to migrate the database.
|
// If db file exists, we should check if we need to migrate the database.
|
||||||
currentVersion := version.GetCurrentVersion(db.profile.Mode)
|
currentVersion := version.GetCurrentVersion(db.profile.Mode)
|
||||||
migrationHistoryList, err := db.FindMigrationHistoryList(ctx, &MigrationHistoryFind{})
|
migrationHistoryList, err := db.FindMigrationHistoryList(ctx, &MigrationHistoryFind{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to find migration history, err: %w", err)
|
return errors.Wrap(err, "failed to find migration history")
|
||||||
}
|
}
|
||||||
if len(migrationHistoryList) == 0 {
|
if len(migrationHistoryList) == 0 {
|
||||||
_, err := db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
_, err := db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
||||||
Version: currentVersion,
|
Version: currentVersion,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to upsert migration history, err: %w", err)
|
return errors.Wrap(err, "failed to upsert migration history")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -103,11 +104,11 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
|||||||
// backup the raw database file before migration
|
// backup the raw database file before migration
|
||||||
rawBytes, err := os.ReadFile(db.profile.DSN)
|
rawBytes, err := os.ReadFile(db.profile.DSN)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read raw database file, err: %w", err)
|
return errors.Wrap(err, "failed to read raw database file")
|
||||||
}
|
}
|
||||||
backupDBFilePath := fmt.Sprintf("%s/slash_%s_%d_backup.db", db.profile.Data, db.profile.Version, time.Now().Unix())
|
backupDBFilePath := fmt.Sprintf("%s/slash_%s_%d_backup.db", db.profile.Data, db.profile.Version, time.Now().Unix())
|
||||||
if err := os.WriteFile(backupDBFilePath, rawBytes, 0644); err != nil {
|
if err := os.WriteFile(backupDBFilePath, rawBytes, 0644); err != nil {
|
||||||
return fmt.Errorf("failed to write raw database file, err: %w", err)
|
return errors.Wrap(err, "failed to write raw database file")
|
||||||
}
|
}
|
||||||
println("succeed to copy a backup database file")
|
println("succeed to copy a backup database file")
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
|||||||
if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) {
|
if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) {
|
||||||
println("applying migration for", normalizedVersion)
|
println("applying migration for", normalizedVersion)
|
||||||
if err := db.applyMigrationForMinorVersion(ctx, minorVersion); err != nil {
|
if err := db.applyMigrationForMinorVersion(ctx, minorVersion); err != nil {
|
||||||
return fmt.Errorf("failed to apply minor version migration: %w", err)
|
return errors.Wrap(err, "failed to apply minor version migration")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,12 +134,12 @@ func (db *DB) Open(ctx context.Context) (err error) {
|
|||||||
// In non-prod mode, we should always migrate the database.
|
// In non-prod mode, we should always migrate the database.
|
||||||
if _, err := os.Stat(db.profile.DSN); errors.Is(err, os.ErrNotExist) {
|
if _, err := os.Stat(db.profile.DSN); errors.Is(err, os.ErrNotExist) {
|
||||||
if err := db.applyLatestSchema(ctx); err != nil {
|
if err := db.applyLatestSchema(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to apply latest schema: %w", err)
|
return errors.Wrap(err, "failed to apply latest schema")
|
||||||
}
|
}
|
||||||
// In demo mode, we should seed the database.
|
// In demo mode, we should seed the database.
|
||||||
if db.profile.Mode == "demo" {
|
if db.profile.Mode == "demo" {
|
||||||
if err := db.seed(ctx); err != nil {
|
if err := db.seed(ctx); err != nil {
|
||||||
return fmt.Errorf("failed to seed: %w", err)
|
return errors.Wrap(err, "failed to seed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -159,11 +160,11 @@ func (db *DB) applyLatestSchema(ctx context.Context) error {
|
|||||||
latestSchemaPath := fmt.Sprintf("%s/%s/%s", "migration", schemaMode, latestSchemaFileName)
|
latestSchemaPath := fmt.Sprintf("%s/%s/%s", "migration", schemaMode, latestSchemaFileName)
|
||||||
buf, err := migrationFS.ReadFile(latestSchemaPath)
|
buf, err := migrationFS.ReadFile(latestSchemaPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read latest schema %q, error %w", latestSchemaPath, err)
|
return errors.Wrapf(err, "failed to read latest schema %q", latestSchemaPath)
|
||||||
}
|
}
|
||||||
stmt := string(buf)
|
stmt := string(buf)
|
||||||
if err := db.execute(ctx, stmt); err != nil {
|
if err := db.execute(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("migrate error: statement:%s err=%w", stmt, err)
|
return errors.Wrapf(err, "migrate error: statement %s", stmt)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -171,7 +172,7 @@ func (db *DB) applyLatestSchema(ctx context.Context) error {
|
|||||||
func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error {
|
func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error {
|
||||||
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("%s/%s/*.sql", "migration/prod", minorVersion))
|
filenames, err := fs.Glob(migrationFS, fmt.Sprintf("%s/%s/*.sql", "migration/prod", minorVersion))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read ddl files, err: %w", err)
|
return errors.Wrap(err, "failed to read ddl files")
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
@ -181,12 +182,12 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
|
|||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
buf, err := migrationFS.ReadFile(filename)
|
buf, err := migrationFS.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read minor version migration file, filename=%s err=%w", filename, err)
|
return errors.Wrapf(err, "failed to read minor version migration file, filename %s", filename)
|
||||||
}
|
}
|
||||||
stmt := string(buf)
|
stmt := string(buf)
|
||||||
migrationStmt += stmt
|
migrationStmt += stmt
|
||||||
if err := db.execute(ctx, stmt); err != nil {
|
if err := db.execute(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("migrate error: statement:%s err=%w", stmt, err)
|
return errors.Wrapf(err, "migrate error: statement %s", stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +196,7 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
|
|||||||
if _, err = db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
if _, err = db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{
|
||||||
Version: version,
|
Version: version,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("failed to upsert migration history with version: %s, err: %w", version, err)
|
return errors.Wrapf(err, "failed to upsert migration history with version %s", version)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -204,7 +205,7 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
|
|||||||
func (db *DB) seed(ctx context.Context) error {
|
func (db *DB) seed(ctx context.Context) error {
|
||||||
filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed"))
|
filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read seed files, err: %w", err)
|
return errors.Wrap(err, "failed to read seed files")
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Strings(filenames)
|
sort.Strings(filenames)
|
||||||
@ -213,11 +214,11 @@ func (db *DB) seed(ctx context.Context) error {
|
|||||||
for _, filename := range filenames {
|
for _, filename := range filenames {
|
||||||
buf, err := seedFS.ReadFile(filename)
|
buf, err := seedFS.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to read seed file, filename=%s err=%w", filename, err)
|
return errors.Wrapf(err, "failed to read seed file, filename %s", filename)
|
||||||
}
|
}
|
||||||
stmt := string(buf)
|
stmt := string(buf)
|
||||||
if err := db.execute(ctx, stmt); err != nil {
|
if err := db.execute(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("seed error: statement:%s err=%w", stmt, err)
|
return errors.Wrapf(err, "seed error: statement %s", stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -226,7 +227,7 @@ func (db *DB) seed(ctx context.Context) error {
|
|||||||
// execute runs a single SQL statement within a transaction.
|
// execute runs a single SQL statement within a transaction.
|
||||||
func (db *DB) execute(ctx context.Context, stmt string) error {
|
func (db *DB) execute(ctx context.Context, stmt string) error {
|
||||||
if _, err := db.DBInstance.ExecContext(ctx, stmt); err != nil {
|
if _, err := db.DBInstance.ExecContext(ctx, stmt); err != nil {
|
||||||
return fmt.Errorf("failed to execute statement, err: %w", err)
|
return errors.Wrap(err, "failed to execute statement")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -27,7 +27,7 @@ VALUES
|
|||||||
(
|
(
|
||||||
102,
|
102,
|
||||||
'USER',
|
'USER',
|
||||||
'steven@usememos.com',
|
'steven@yourselfhosted.com',
|
||||||
'Steven',
|
'Steven',
|
||||||
-- raw password: secret
|
-- raw password: secret
|
||||||
'$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK'
|
'$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK'
|
||||||
|
@ -4,11 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Visibility is the type of a visibility.
|
// Visibility is the type of a visibility.
|
||||||
@ -134,7 +136,7 @@ func (s *Store) UpdateShortcut(ctx context.Context, update *UpdateShortcut) (*st
|
|||||||
set, args = append(set, "og_metadata = ?"), append(args, string(openGraphMetadataBytes))
|
set, args = append(set, "og_metadata = ?"), append(args, string(openGraphMetadataBytes))
|
||||||
}
|
}
|
||||||
if len(set) == 0 {
|
if len(set) == 0 {
|
||||||
return nil, fmt.Errorf("no update specified")
|
return nil, errors.New("no update specified")
|
||||||
}
|
}
|
||||||
args = append(args, update.ID)
|
args = append(args, update.ID)
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ package store
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ func (s *Store) UpdateUser(ctx context.Context, update *UpdateUser) (*User, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(set) == 0 {
|
if len(set) == 0 {
|
||||||
return nil, fmt.Errorf("no fields to update")
|
return nil, errors.New("no fields to update")
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt := `
|
stmt := `
|
||||||
|
@ -6,8 +6,9 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FindUserSetting struct {
|
type FindUserSetting struct {
|
||||||
|
@ -6,8 +6,9 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FindWorkspaceSetting struct {
|
type FindWorkspaceSetting struct {
|
||||||
|
@ -6,9 +6,10 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
apiv1 "github.com/boojack/slash/api/v1"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
apiv1 "github.com/boojack/slash/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAuthServer(t *testing.T) {
|
func TestAuthServer(t *testing.T) {
|
||||||
|
@ -10,16 +10,16 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
// sqlite driver.
|
||||||
|
_ "modernc.org/sqlite"
|
||||||
|
|
||||||
"github.com/boojack/slash/api/auth"
|
"github.com/boojack/slash/api/auth"
|
||||||
"github.com/boojack/slash/server"
|
"github.com/boojack/slash/server"
|
||||||
"github.com/boojack/slash/server/profile"
|
"github.com/boojack/slash/server/profile"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/boojack/slash/store/db"
|
"github.com/boojack/slash/store/db"
|
||||||
"github.com/boojack/slash/test"
|
"github.com/boojack/slash/test"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
// sqlite driver.
|
|
||||||
_ "modernc.org/sqlite"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TestingServer struct {
|
type TestingServer struct {
|
||||||
|
@ -7,9 +7,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
apiv1 "github.com/boojack/slash/api/v1"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
apiv1 "github.com/boojack/slash/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShortcutServer(t *testing.T) {
|
func TestShortcutServer(t *testing.T) {
|
||||||
|
@ -7,9 +7,10 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
apiv1 "github.com/boojack/slash/api/v1"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
apiv1 "github.com/boojack/slash/api/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUserServer(t *testing.T) {
|
func TestUserServer(t *testing.T) {
|
||||||
@ -31,7 +32,7 @@ func TestUserServer(t *testing.T) {
|
|||||||
user, err = s.getUserByID(user.ID)
|
user, err = s.getUserByID(user.ID)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, signup.Email, user.Email)
|
require.Equal(t, signup.Email, user.Email)
|
||||||
newEmail := "test@usermemos.com"
|
newEmail := "test@yourselfhosted.com"
|
||||||
userPatch := &apiv1.PatchUserRequest{
|
userPatch := &apiv1.PatchUserRequest{
|
||||||
Email: &newEmail,
|
Email: &newEmail,
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestActivityStore(t *testing.T) {
|
func TestActivityStore(t *testing.T) {
|
||||||
|
@ -4,9 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestShortcutStore(t *testing.T) {
|
func TestShortcutStore(t *testing.T) {
|
||||||
|
@ -5,12 +5,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
// sqlite driver.
|
||||||
|
_ "modernc.org/sqlite"
|
||||||
|
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/boojack/slash/store/db"
|
"github.com/boojack/slash/store/db"
|
||||||
test "github.com/boojack/slash/test"
|
test "github.com/boojack/slash/test"
|
||||||
|
|
||||||
// sqlite driver.
|
|
||||||
_ "modernc.org/sqlite"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTestingStore(ctx context.Context, t *testing.T) *store.Store {
|
func NewTestingStore(ctx context.Context, t *testing.T) *store.Store {
|
||||||
|
@ -4,9 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
"github.com/boojack/slash/store"
|
"github.com/boojack/slash/store"
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUserSettingStore(t *testing.T) {
|
func TestUserSettingStore(t *testing.T) {
|
||||||
|
@ -4,10 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestUserStore(t *testing.T) {
|
func TestUserStore(t *testing.T) {
|
||||||
|
@ -4,10 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
storepb "github.com/boojack/slash/proto/gen/store"
|
|
||||||
"github.com/boojack/slash/store"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
storepb "github.com/boojack/slash/proto/gen/store"
|
||||||
|
"github.com/boojack/slash/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWorkspaceSettingStore(t *testing.T) {
|
func TestWorkspaceSettingStore(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user