diff --git a/.golangci.yaml b/.golangci.yaml index a7082e22..616ee205 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,5 +1,6 @@ linters: enable: + - errcheck - goimports - revive - govet @@ -10,17 +11,30 @@ linters: - rowserrcheck - nilerr - godot + - forbidigo + - mirror + - bodyclose issues: + include: + # https://golangci-lint.run/usage/configuration/#command-line-options exclude: - Rollback + - logger.Sync + - pgInstance.Stop - fmt.Printf - - fmt.Print + - Enter(.*)_(.*) + - Exit(.*)_(.*) linters-settings: + goimports: + # Put imports beginning with prefix after 3rd-party packages. + local-prefixes: github.com/usememos/memos 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 rules: + # The following rules are too strict and make coding harder. We do not enable them for now. - name: file-header disabled: true - name: line-length-limit @@ -56,9 +70,14 @@ linters-settings: - ifElseChain govet: settings: - printf: - funcs: + printf: # The name of the analyzer, run `go tool vet help` to see the list of all analyzers + funcs: # Run `go tool vet help printf` to see the full configuration of `printf`. - common.Errorf + enable-all: true + disable: + - fieldalignment + - shadow forbidigo: forbid: - 'fmt\.Errorf(# Please use errors\.Wrap\|Wrapf\|Errorf instead)?' + - 'ioutil\.ReadDir(# Please use os\.ReadDir)?' diff --git a/.vscode/settings.json b/.vscode/settings.json index 7d81ce6f..bf4a44ad 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,8 +2,4 @@ "json.schemaDownload.enable":true, "go.lintOnSave": "workspace", "go.lintTool": "golangci-lint", - "go.inferGopath": false, - "go.toolsEnvVars": { - "GO111MODULE": "on" - } } diff --git a/api/v1/auth.go b/api/v1/auth.go index 8a52edb1..0dae91bc 100644 --- a/api/v1/auth.go +++ b/api/v1/auth.go @@ -10,13 +10,14 @@ import ( "github.com/labstack/echo/v4" "github.com/pkg/errors" + "golang.org/x/crypto/bcrypt" + "github.com/usememos/memos/api/auth" "github.com/usememos/memos/common/util" "github.com/usememos/memos/plugin/idp" "github.com/usememos/memos/plugin/idp/oauth2" storepb "github.com/usememos/memos/proto/gen/store" "github.com/usememos/memos/store" - "golang.org/x/crypto/bcrypt" ) type SignIn struct { diff --git a/api/v1/http_getter.go b/api/v1/http_getter.go index 3eaef4a8..9f6dcfb6 100644 --- a/api/v1/http_getter.go +++ b/api/v1/http_getter.go @@ -6,6 +6,7 @@ import ( "net/url" "github.com/labstack/echo/v4" + getter "github.com/usememos/memos/plugin/http-getter" ) diff --git a/api/v1/idp.go b/api/v1/idp.go index def1f4b1..2bc7e912 100644 --- a/api/v1/idp.go +++ b/api/v1/idp.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/labstack/echo/v4" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" ) diff --git a/api/v1/jwt.go b/api/v1/jwt.go index 29b423d1..6921908c 100644 --- a/api/v1/jwt.go +++ b/api/v1/jwt.go @@ -8,6 +8,7 @@ import ( "github.com/golang-jwt/jwt/v4" "github.com/labstack/echo/v4" "github.com/pkg/errors" + "github.com/usememos/memos/api/auth" "github.com/usememos/memos/common/util" storepb "github.com/usememos/memos/proto/gen/store" diff --git a/api/v1/memo.go b/api/v1/memo.go index 08ecfa24..fe3c37f6 100644 --- a/api/v1/memo.go +++ b/api/v1/memo.go @@ -10,10 +10,11 @@ import ( "github.com/labstack/echo/v4" "github.com/pkg/errors" + "go.uber.org/zap" + "github.com/usememos/memos/common/log" "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" - "go.uber.org/zap" ) // Visibility is the type of a visibility. @@ -336,17 +337,17 @@ func (s *APIV1Service) CreateMemo(c echo.Context) error { } } - memo, err = s.Store.GetMemo(ctx, &store.FindMemo{ + composedMemo, err := s.Store.GetMemo(ctx, &store.FindMemo{ ID: &memo.ID, }) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo").SetInternal(err) } - if memo == nil { + if composedMemo == nil { return echo.NewHTTPError(http.StatusNotFound, fmt.Sprintf("Memo not found: %d", memo.ID)) } - memoResponse, err := s.convertMemoFromStore(ctx, memo) + memoResponse, err := s.convertMemoFromStore(ctx, composedMemo) if err != nil { return echo.NewHTTPError(http.StatusInternalServerError, "Failed to compose memo response").SetInternal(err) } diff --git a/api/v1/memo_organizer.go b/api/v1/memo_organizer.go index a3457743..e55f048a 100644 --- a/api/v1/memo_organizer.go +++ b/api/v1/memo_organizer.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/labstack/echo/v4" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" ) diff --git a/api/v1/memo_relation.go b/api/v1/memo_relation.go index b67ce0b5..d3c6ecad 100644 --- a/api/v1/memo_relation.go +++ b/api/v1/memo_relation.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/labstack/echo/v4" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" ) diff --git a/api/v1/memo_resource.go b/api/v1/memo_resource.go index 7e83cfec..fddc4688 100644 --- a/api/v1/memo_resource.go +++ b/api/v1/memo_resource.go @@ -7,6 +7,7 @@ import ( "time" "github.com/labstack/echo/v4" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" ) diff --git a/api/v1/resource.go b/api/v1/resource.go index f09e2bd8..63f7e610 100644 --- a/api/v1/resource.go +++ b/api/v1/resource.go @@ -20,11 +20,12 @@ import ( "github.com/disintegration/imaging" "github.com/labstack/echo/v4" "github.com/pkg/errors" + "go.uber.org/zap" + "github.com/usememos/memos/common/log" "github.com/usememos/memos/common/util" "github.com/usememos/memos/plugin/storage/s3" "github.com/usememos/memos/store" - "go.uber.org/zap" ) type Resource struct { @@ -606,14 +607,14 @@ func convertResourceFromStore(resource *store.Resource) *Resource { func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resource, r io.Reader) error { systemSettingStorageServiceID, err := s.GetSystemSetting(ctx, &store.FindSystemSetting{Name: SystemSettingStorageServiceIDName.String()}) if err != nil { - return fmt.Errorf("Failed to find SystemSettingStorageServiceIDName: %s", err) + return errors.Errorf("Failed to find SystemSettingStorageServiceIDName: %s", err) } storageServiceID := LocalStorage if systemSettingStorageServiceID != nil { err = json.Unmarshal([]byte(systemSettingStorageServiceID.Value), &storageServiceID) if err != nil { - return fmt.Errorf("Failed to unmarshal storage service id: %s", err) + return errors.Errorf("Failed to unmarshal storage service id: %s", err) } } @@ -621,7 +622,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc if storageServiceID == DatabaseStorage { fileBytes, err := io.ReadAll(r) if err != nil { - return fmt.Errorf("Failed to read file: %s", err) + return errors.Errorf("Failed to read file: %s", err) } create.Blob = fileBytes return nil @@ -629,13 +630,13 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc // `LocalStorage` means save blob into local disk systemSettingLocalStoragePath, err := s.GetSystemSetting(ctx, &store.FindSystemSetting{Name: SystemSettingLocalStoragePathName.String()}) if err != nil { - return fmt.Errorf("Failed to find SystemSettingLocalStoragePathName: %s", err) + return errors.Errorf("Failed to find SystemSettingLocalStoragePathName: %s", err) } localStoragePath := "assets/{timestamp}_{filename}" if systemSettingLocalStoragePath != nil && systemSettingLocalStoragePath.Value != "" { err = json.Unmarshal([]byte(systemSettingLocalStoragePath.Value), &localStoragePath) if err != nil { - return fmt.Errorf("Failed to unmarshal SystemSettingLocalStoragePathName: %s", err) + return errors.Errorf("Failed to unmarshal SystemSettingLocalStoragePathName: %s", err) } } filePath := filepath.FromSlash(localStoragePath) @@ -646,16 +647,16 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc dir := filepath.Dir(filePath) if err = os.MkdirAll(dir, os.ModePerm); err != nil { - return fmt.Errorf("Failed to create directory: %s", err) + return errors.Errorf("Failed to create directory: %s", err) } dst, err := os.Create(filePath) if err != nil { - return fmt.Errorf("Failed to create file: %s", err) + return errors.Errorf("Failed to create file: %s", err) } defer dst.Close() _, err = io.Copy(dst, r) if err != nil { - return fmt.Errorf("Failed to copy file: %s", err) + return errors.Errorf("Failed to copy file: %s", err) } create.InternalPath = filePath @@ -665,18 +666,18 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc // Others: store blob into external service, such as S3 storage, err := s.GetStorage(ctx, &store.FindStorage{ID: &storageServiceID}) if err != nil { - return fmt.Errorf("Failed to find StorageServiceID: %s", err) + return errors.Errorf("Failed to find StorageServiceID: %s", err) } if storage == nil { - return fmt.Errorf("Storage %d not found", storageServiceID) + return errors.Errorf("Storage %d not found", storageServiceID) } storageMessage, err := ConvertStorageFromStore(storage) if err != nil { - return fmt.Errorf("Failed to ConvertStorageFromStore: %s", err) + return errors.Errorf("Failed to ConvertStorageFromStore: %s", err) } if storageMessage.Type != StorageS3 { - return fmt.Errorf("Unsupported storage type: %s", storageMessage.Type) + return errors.Errorf("Unsupported storage type: %s", storageMessage.Type) } s3Config := storageMessage.Config.S3Config @@ -690,7 +691,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc URLSuffix: s3Config.URLSuffix, }) if err != nil { - return fmt.Errorf("Failed to create s3 client: %s", err) + return errors.Errorf("Failed to create s3 client: %s", err) } filePath := s3Config.Path @@ -701,7 +702,7 @@ func SaveResourceBlob(ctx context.Context, s *store.Store, create *store.Resourc link, err := s3Client.UploadFile(ctx, filePath, create.Type, r) if err != nil { - return fmt.Errorf("Failed to upload via s3 client: %s", err) + return errors.Errorf("Failed to upload via s3 client: %s", err) } create.ExternalLink = link diff --git a/api/v1/rss.go b/api/v1/rss.go index f525e22b..6ecd330b 100644 --- a/api/v1/rss.go +++ b/api/v1/rss.go @@ -12,9 +12,11 @@ import ( "github.com/gorilla/feeds" "github.com/labstack/echo/v4" + "github.com/pkg/errors" + "github.com/yuin/goldmark" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" - "github.com/yuin/goldmark" ) const maxRSSItemCount = 100 @@ -129,7 +131,7 @@ func (s *APIV1Service) generateRSSFromMemoList(ctx context.Context, memoList []* return "", err } if resource == nil { - return "", fmt.Errorf("Resource not found: %d", resourceID) + return "", errors.Errorf("Resource not found: %d", resourceID) } enclosure := feeds.Enclosure{} if resource.ExternalLink != "" { diff --git a/api/v1/storage.go b/api/v1/storage.go index e5e6efc5..e3c8180f 100644 --- a/api/v1/storage.go +++ b/api/v1/storage.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/labstack/echo/v4" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" ) diff --git a/api/v1/system.go b/api/v1/system.go index 897ad419..0c0cb7a3 100644 --- a/api/v1/system.go +++ b/api/v1/system.go @@ -5,10 +5,11 @@ import ( "net/http" "github.com/labstack/echo/v4" + "go.uber.org/zap" + "github.com/usememos/memos/common/log" "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" - "go.uber.org/zap" ) type SystemStatus struct { diff --git a/api/v1/system_setting.go b/api/v1/system_setting.go index e7090199..f7151322 100644 --- a/api/v1/system_setting.go +++ b/api/v1/system_setting.go @@ -2,11 +2,12 @@ package v1 import ( "encoding/json" - "fmt" "net/http" "strings" "github.com/labstack/echo/v4" + "github.com/pkg/errors" + "github.com/usememos/memos/store" ) @@ -186,36 +187,36 @@ func (s *APIV1Service) CreateSystemSetting(c echo.Context) error { func (upsert UpsertSystemSettingRequest) Validate() error { switch settingName := upsert.Name; settingName { case SystemSettingServerIDName: - return fmt.Errorf("updating %v is not allowed", settingName) + return errors.Errorf("updating %v is not allowed", settingName) case SystemSettingAllowSignUpName: var value bool if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingDisablePasswordLoginName: var value bool if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingDisablePublicMemosName: var value bool if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingMaxUploadSizeMiBName: var value int if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingAdditionalStyleName: var value string if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingAdditionalScriptName: var value string if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingCustomizedProfileName: customizedProfile := CustomizedProfile{ @@ -227,27 +228,27 @@ func (upsert UpsertSystemSettingRequest) Validate() error { ExternalURL: "", } if err := json.Unmarshal([]byte(upsert.Value), &customizedProfile); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingStorageServiceIDName: // Note: 0 is the default value(database) for storage service ID. value := 0 if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } return nil case SystemSettingLocalStoragePathName: value := "" if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingAutoBackupIntervalName: var value int if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } if value < 0 { - return fmt.Errorf("must be positive") + return errors.Errorf("must be positive") } case SystemSettingTelegramBotTokenName: if upsert.Value == "" { @@ -259,19 +260,19 @@ func (upsert UpsertSystemSettingRequest) Validate() error { if strings.HasPrefix(upsert.Value[slashIndex:], "/bot") { return nil } - return fmt.Errorf("token start with `http` must end with `/bot`") + return errors.Errorf("token start with `http` must end with `/bot`") } fragments := strings.Split(upsert.Value, ":") if len(fragments) != 2 { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } case SystemSettingMemoDisplayWithUpdatedTsName: var value bool if err := json.Unmarshal([]byte(upsert.Value), &value); err != nil { - return fmt.Errorf(systemSettingUnmarshalError, settingName) + return errors.Errorf(systemSettingUnmarshalError, settingName) } default: - return fmt.Errorf("invalid system setting name") + return errors.Errorf("invalid system setting name") } return nil } diff --git a/api/v1/tag.go b/api/v1/tag.go index 8786d350..31163637 100644 --- a/api/v1/tag.go +++ b/api/v1/tag.go @@ -9,8 +9,9 @@ import ( "github.com/labstack/echo/v4" "github.com/pkg/errors" - "github.com/usememos/memos/store" "golang.org/x/exp/slices" + + "github.com/usememos/memos/store" ) type Tag struct { diff --git a/api/v1/user.go b/api/v1/user.go index de33b377..a2f8f870 100644 --- a/api/v1/user.go +++ b/api/v1/user.go @@ -8,9 +8,10 @@ import ( "github.com/labstack/echo/v4" "github.com/pkg/errors" + "golang.org/x/crypto/bcrypt" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" - "golang.org/x/crypto/bcrypt" ) // Role is the type of a role. @@ -404,26 +405,26 @@ func (s *APIV1Service) UpdateUser(c echo.Context) error { func (create CreateUserRequest) Validate() error { if len(create.Username) < 3 { - return fmt.Errorf("username is too short, minimum length is 3") + return errors.Errorf("username is too short, minimum length is 3") } if len(create.Username) > 32 { - return fmt.Errorf("username is too long, maximum length is 32") + return errors.Errorf("username is too long, maximum length is 32") } if len(create.Password) < 3 { - return fmt.Errorf("password is too short, minimum length is 3") + return errors.Errorf("password is too short, minimum length is 3") } if len(create.Password) > 512 { - return fmt.Errorf("password is too long, maximum length is 512") + return errors.Errorf("password is too long, maximum length is 512") } if len(create.Nickname) > 64 { - return fmt.Errorf("nickname is too long, maximum length is 64") + return errors.Errorf("nickname is too long, maximum length is 64") } if create.Email != "" { if len(create.Email) > 256 { - return fmt.Errorf("email is too long, maximum length is 256") + return errors.Errorf("email is too long, maximum length is 256") } if !util.ValidateEmail(create.Email) { - return fmt.Errorf("invalid email format") + return errors.Errorf("invalid email format") } } @@ -432,31 +433,31 @@ func (create CreateUserRequest) Validate() error { func (update UpdateUserRequest) Validate() error { if update.Username != nil && len(*update.Username) < 3 { - return fmt.Errorf("username is too short, minimum length is 3") + return errors.Errorf("username is too short, minimum length is 3") } if update.Username != nil && len(*update.Username) > 32 { - return fmt.Errorf("username is too long, maximum length is 32") + return errors.Errorf("username is too long, maximum length is 32") } if update.Password != nil && len(*update.Password) < 3 { - return fmt.Errorf("password is too short, minimum length is 3") + return errors.Errorf("password is too short, minimum length is 3") } if update.Password != nil && len(*update.Password) > 512 { - return fmt.Errorf("password is too long, maximum length is 512") + return errors.Errorf("password is too long, maximum length is 512") } if update.Nickname != nil && len(*update.Nickname) > 64 { - return fmt.Errorf("nickname is too long, maximum length is 64") + return errors.Errorf("nickname is too long, maximum length is 64") } if update.AvatarURL != nil { if len(*update.AvatarURL) > 2<<20 { - return fmt.Errorf("avatar is too large, maximum is 2MB") + return errors.Errorf("avatar is too large, maximum is 2MB") } } if update.Email != nil && *update.Email != "" { if len(*update.Email) > 256 { - return fmt.Errorf("email is too long, maximum length is 256") + return errors.Errorf("email is too long, maximum length is 256") } if !util.ValidateEmail(*update.Email) { - return fmt.Errorf("invalid email format") + return errors.Errorf("invalid email format") } } diff --git a/api/v1/user_setting.go b/api/v1/user_setting.go index abdd66a9..b808fc32 100644 --- a/api/v1/user_setting.go +++ b/api/v1/user_setting.go @@ -2,12 +2,13 @@ package v1 import ( "encoding/json" - "fmt" "net/http" "github.com/labstack/echo/v4" - "github.com/usememos/memos/store" + "github.com/pkg/errors" "golang.org/x/exp/slices" + + "github.com/usememos/memos/store" ) type UserSettingKey string @@ -127,37 +128,37 @@ func (upsert UpsertUserSettingRequest) Validate() error { localeValue := "en" err := json.Unmarshal([]byte(upsert.Value), &localeValue) if err != nil { - return fmt.Errorf("failed to unmarshal user setting locale value") + return errors.Errorf("failed to unmarshal user setting locale value") } if !slices.Contains(UserSettingLocaleValue, localeValue) { - return fmt.Errorf("invalid user setting locale value") + return errors.Errorf("invalid user setting locale value") } } else if upsert.Key == UserSettingAppearanceKey { appearanceValue := "system" err := json.Unmarshal([]byte(upsert.Value), &appearanceValue) if err != nil { - return fmt.Errorf("failed to unmarshal user setting appearance value") + return errors.Errorf("failed to unmarshal user setting appearance value") } if !slices.Contains(UserSettingAppearanceValue, appearanceValue) { - return fmt.Errorf("invalid user setting appearance value") + return errors.Errorf("invalid user setting appearance value") } } else if upsert.Key == UserSettingMemoVisibilityKey { memoVisibilityValue := Private err := json.Unmarshal([]byte(upsert.Value), &memoVisibilityValue) if err != nil { - return fmt.Errorf("failed to unmarshal user setting memo visibility value") + return errors.Errorf("failed to unmarshal user setting memo visibility value") } if !slices.Contains(UserSettingMemoVisibilityValue, memoVisibilityValue) { - return fmt.Errorf("invalid user setting memo visibility value") + return errors.Errorf("invalid user setting memo visibility value") } } else if upsert.Key == UserSettingTelegramUserIDKey { var key string err := json.Unmarshal([]byte(upsert.Value), &key) if err != nil { - return fmt.Errorf("invalid user setting telegram user id value") + return errors.Errorf("invalid user setting telegram user id value") } } else { - return fmt.Errorf("invalid user setting key") + return errors.Errorf("invalid user setting key") } return nil diff --git a/api/v1/v1.go b/api/v1/v1.go index 79e7b903..862298cd 100644 --- a/api/v1/v1.go +++ b/api/v1/v1.go @@ -2,6 +2,7 @@ package v1 import ( "github.com/labstack/echo/v4" + "github.com/usememos/memos/plugin/telegram" "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" diff --git a/api/v2/acl.go b/api/v2/acl.go index c67f0369..b3512525 100644 --- a/api/v2/acl.go +++ b/api/v2/acl.go @@ -7,13 +7,14 @@ import ( "github.com/golang-jwt/jwt/v4" "github.com/pkg/errors" - "github.com/usememos/memos/api/auth" - storepb "github.com/usememos/memos/proto/gen/store" - "github.com/usememos/memos/store" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" + + "github.com/usememos/memos/api/auth" + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" ) // ContextKey is the key type of context value. diff --git a/api/v2/memo_service.go b/api/v2/memo_service.go index 9b798639..01538161 100644 --- a/api/v2/memo_service.go +++ b/api/v2/memo_service.go @@ -5,11 +5,12 @@ import ( "github.com/google/cel-go/cel" "github.com/pkg/errors" - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - "github.com/usememos/memos/store" v1alpha1 "google.golang.org/genproto/googleapis/api/expr/v1alpha1" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + "github.com/usememos/memos/store" ) type MemoService struct { diff --git a/api/v2/resource_service.go b/api/v2/resource_service.go index 27d0a010..f35afc0b 100644 --- a/api/v2/resource_service.go +++ b/api/v2/resource_service.go @@ -4,11 +4,12 @@ import ( "context" "time" - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - "github.com/usememos/memos/store" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + "github.com/usememos/memos/store" ) type ResourceService struct { diff --git a/api/v2/system_service.go b/api/v2/system_service.go index 38bee07e..6bfe4c29 100644 --- a/api/v2/system_service.go +++ b/api/v2/system_service.go @@ -5,11 +5,12 @@ import ( "os" "strconv" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) type SystemService struct { diff --git a/api/v2/tag_service.go b/api/v2/tag_service.go index abdff9ce..d421987d 100644 --- a/api/v2/tag_service.go +++ b/api/v2/tag_service.go @@ -3,10 +3,11 @@ package v2 import ( "context" - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - "github.com/usememos/memos/store" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + "github.com/usememos/memos/store" ) type TagService struct { diff --git a/api/v2/user_service.go b/api/v2/user_service.go index 0f980c2c..2a57d37a 100644 --- a/api/v2/user_service.go +++ b/api/v2/user_service.go @@ -8,15 +8,16 @@ import ( "github.com/golang-jwt/jwt/v4" "github.com/labstack/echo/v4" "github.com/pkg/errors" - "github.com/usememos/memos/api/auth" - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - storepb "github.com/usememos/memos/proto/gen/store" - "github.com/usememos/memos/store" "golang.org/x/crypto/bcrypt" "golang.org/x/exp/slices" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" + + "github.com/usememos/memos/api/auth" + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + storepb "github.com/usememos/memos/proto/gen/store" + "github.com/usememos/memos/store" ) type UserService struct { diff --git a/api/v2/v2.go b/api/v2/v2.go index 2c72f2f8..e6b41f20 100644 --- a/api/v2/v2.go +++ b/api/v2/v2.go @@ -7,12 +7,13 @@ import ( grpcRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" "github.com/improbable-eng/grpc-web/go/grpcweb" "github.com/labstack/echo/v4" - apiv2pb "github.com/usememos/memos/proto/gen/api/v2" - "github.com/usememos/memos/server/profile" - "github.com/usememos/memos/store" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/reflection" + + apiv2pb "github.com/usememos/memos/proto/gen/api/v2" + "github.com/usememos/memos/server/profile" + "github.com/usememos/memos/store" ) type APIV2Service struct { diff --git a/cmd/memos.go b/cmd/memos.go index 4d62a1d7..fb5df0cf 100644 --- a/cmd/memos.go +++ b/cmd/memos.go @@ -10,12 +10,13 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "go.uber.org/zap" + "github.com/usememos/memos/common/log" "github.com/usememos/memos/server" _profile "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" - "go.uber.org/zap" ) const ( @@ -144,15 +145,15 @@ func initConfig() { } func printGreetings() { - fmt.Print(greetingBanner) + print(greetingBanner) if len(profile.Addr) == 0 { fmt.Printf("Version %s has been started on port %d\n", profile.Version, profile.Port) } else { fmt.Printf("Version %s has been started on address '%s' and port %d\n", profile.Version, profile.Addr, profile.Port) } - fmt.Println("---") - fmt.Println("See more in:") + println("---") + println("See more in:") fmt.Printf("👉Website: %s\n", "https://usememos.com") fmt.Printf("👉GitHub: %s\n", "https://github.com/usememos/memos") - fmt.Println("---") + println("---") } diff --git a/cmd/mvrss.go b/cmd/mvrss.go index 05145c4a..dd64720f 100644 --- a/cmd/mvrss.go +++ b/cmd/mvrss.go @@ -7,6 +7,7 @@ import ( "time" "github.com/spf13/cobra" + "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" ) @@ -85,7 +86,7 @@ var ( fmt.Printf("Resource %5d copy %12d bytes from %s\n", res.ID, len(buf), res.InternalPath) } - fmt.Println("done") + println("done") }, } ) diff --git a/cmd/setup.go b/cmd/setup.go index 8b2705bc..a3bb1bae 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -2,15 +2,16 @@ package cmd import ( "context" - "errors" "fmt" "time" + "github.com/pkg/errors" "github.com/spf13/cobra" + "golang.org/x/crypto/bcrypt" + "github.com/usememos/memos/common/util" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" - "golang.org/x/crypto/bcrypt" ) var ( @@ -76,7 +77,7 @@ func (s setupService) Setup(ctx context.Context, hostUsername, hostPassword stri } if err := s.createUser(ctx, hostUsername, hostPassword); err != nil { - return fmt.Errorf("create user: %w", err) + return errors.Wrap(err, "create user") } return nil } @@ -85,7 +86,7 @@ func (s setupService) makeSureHostUserNotExists(ctx context.Context) error { hostUserType := store.RoleHost existedHostUsers, err := s.store.ListUsers(ctx, &store.FindUser{Role: &hostUserType}) if err != nil { - return fmt.Errorf("find user list: %w", err) + return errors.Wrap(err, "find user list") } if len(existedHostUsers) != 0 { @@ -104,37 +105,37 @@ func (s setupService) createUser(ctx context.Context, hostUsername, hostPassword } if len(userCreate.Username) < 3 { - return fmt.Errorf("username is too short, minimum length is 3") + return errors.New("username is too short, minimum length is 3") } if len(userCreate.Username) > 32 { - return fmt.Errorf("username is too long, maximum length is 32") + return errors.New("username is too long, maximum length is 32") } if len(hostPassword) < 3 { - return fmt.Errorf("password is too short, minimum length is 3") + return errors.New("password is too short, minimum length is 3") } if len(hostPassword) > 512 { - return fmt.Errorf("password is too long, maximum length is 512") + return errors.New("password is too long, maximum length is 512") } if len(userCreate.Nickname) > 64 { - return fmt.Errorf("nickname is too long, maximum length is 64") + return errors.New("nickname is too long, maximum length is 64") } if userCreate.Email != "" { if len(userCreate.Email) > 256 { - return fmt.Errorf("email is too long, maximum length is 256") + return errors.New("email is too long, maximum length is 256") } if !util.ValidateEmail(userCreate.Email) { - return fmt.Errorf("invalid email format") + return errors.New("invalid email format") } } passwordHash, err := bcrypt.GenerateFromPassword([]byte(hostPassword), bcrypt.DefaultCost) if err != nil { - return fmt.Errorf("failed to hash password: %w", err) + return errors.Wrap(err, "failed to hash password") } userCreate.PasswordHash = string(passwordHash) if _, err := s.store.CreateUser(ctx, userCreate); err != nil { - return fmt.Errorf("failed to create user: %w", err) + return errors.Wrap(err, "failed to create user") } return nil diff --git a/internal/cron/cron.go b/internal/cron/cron.go index 4b4f314f..df26c48a 100644 --- a/internal/cron/cron.go +++ b/internal/cron/cron.go @@ -1,18 +1,17 @@ -// Package cron implements a crontab-like service to execute and schedule -// repeative tasks/jobs. -// +// Package cron implements a crontab-like service to execute and schedule repeative tasks/jobs. +package cron + // Example: // // c := cron.New() // c.MustAdd("dailyReport", "0 0 * * *", func() { ... }) // c.Start() -package cron import ( - "errors" - "fmt" "sync" "time" + + "github.com/pkg/errors" ) type job struct { @@ -90,7 +89,7 @@ func (c *Cron) Add(jobID string, cronExpr string, run func()) error { schedule, err := NewSchedule(cronExpr) 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{ diff --git a/internal/cron/schedule.go b/internal/cron/schedule.go index eaef6441..26d74315 100644 --- a/internal/cron/schedule.go +++ b/internal/cron/schedule.go @@ -1,11 +1,11 @@ package cron import ( - "errors" - "fmt" "strconv" "strings" "time" + + "github.com/pkg/errors" ) // 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 } 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.Errorf("invalid segment step boundary - the step must be between 1 and the %d", max) } step = parsedStep default: @@ -167,7 +167,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error return nil, err } if parsedMin < min || parsedMin > max { - return nil, fmt.Errorf("invalid segment range minimum - must be between %d and %d", min, max) + return nil, errors.Errorf("invalid segment range minimum - must be between %d and %d", min, max) } rangeMin = parsedMin @@ -176,7 +176,7 @@ func parseCronSegment(segment string, min int, max int) (map[int]struct{}, error return nil, err } if parsedMax < parsedMin || parsedMax > max { - return nil, fmt.Errorf("invalid segment range maximum - must be between %d and %d", rangeMin, max) + return nil, errors.Errorf("invalid segment range maximum - must be between %d and %d", rangeMin, max) } rangeMax = parsedMax default: diff --git a/plugin/gomark/parser/bold_test.go b/plugin/gomark/parser/bold_test.go index adeabef2..511bb70e 100644 --- a/plugin/gomark/parser/bold_test.go +++ b/plugin/gomark/parser/bold_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/code_block_test.go b/plugin/gomark/parser/code_block_test.go index 246c9704..cbfbf6bd 100644 --- a/plugin/gomark/parser/code_block_test.go +++ b/plugin/gomark/parser/code_block_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/code_test.go b/plugin/gomark/parser/code_test.go index 2a9a0cad..8e4fed41 100644 --- a/plugin/gomark/parser/code_test.go +++ b/plugin/gomark/parser/code_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/heading_test.go b/plugin/gomark/parser/heading_test.go index a5088f01..b9ef4a5e 100644 --- a/plugin/gomark/parser/heading_test.go +++ b/plugin/gomark/parser/heading_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/image_test.go b/plugin/gomark/parser/image_test.go index 4d8ed843..cdcbfa2a 100644 --- a/plugin/gomark/parser/image_test.go +++ b/plugin/gomark/parser/image_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/italic_test.go b/plugin/gomark/parser/italic_test.go index 2c6df3b5..116616bf 100644 --- a/plugin/gomark/parser/italic_test.go +++ b/plugin/gomark/parser/italic_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/link_test.go b/plugin/gomark/parser/link_test.go index 370867e8..ab4f5c7d 100644 --- a/plugin/gomark/parser/link_test.go +++ b/plugin/gomark/parser/link_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/paragraph_test.go b/plugin/gomark/parser/paragraph_test.go index 2afe42ee..d3e0f55b 100644 --- a/plugin/gomark/parser/paragraph_test.go +++ b/plugin/gomark/parser/paragraph_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/gomark/parser/tag_test.go b/plugin/gomark/parser/tag_test.go index ef133fbb..7066027f 100644 --- a/plugin/gomark/parser/tag_test.go +++ b/plugin/gomark/parser/tag_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/gomark/parser/tokenizer" ) diff --git a/plugin/http-getter/html_meta.go b/plugin/http-getter/html_meta.go index ca2d8a61..4105ece0 100644 --- a/plugin/http-getter/html_meta.go +++ b/plugin/http-getter/html_meta.go @@ -1,7 +1,7 @@ package getter import ( - "fmt" + "errors" "io" "net/http" "net/url" @@ -32,7 +32,7 @@ func GetHTMLMeta(urlStr string) (*HTMLMeta, error) { return nil, err } if mediatype != "text/html" { - return nil, fmt.Errorf("Wrong website mediatype") + return nil, errors.New("Wrong website mediatype") } htmlMeta := extractHTMLMeta(response.Body) diff --git a/plugin/http-getter/image.go b/plugin/http-getter/image.go index 1dbd3220..05678306 100644 --- a/plugin/http-getter/image.go +++ b/plugin/http-getter/image.go @@ -1,7 +1,7 @@ package getter import ( - "fmt" + "errors" "io" "net/http" "net/url" @@ -29,7 +29,7 @@ func GetImage(urlStr string) (*Image, error) { return nil, err } if !strings.HasPrefix(mediatype, "image/") { - return nil, fmt.Errorf("Wrong image mediatype") + return nil, errors.New("Wrong image mediatype") } bodyBytes, err := io.ReadAll(response.Body) diff --git a/plugin/idp/oauth2/oauth2.go b/plugin/idp/oauth2/oauth2.go index ac31a7b1..4dd52d68 100644 --- a/plugin/idp/oauth2/oauth2.go +++ b/plugin/idp/oauth2/oauth2.go @@ -9,9 +9,10 @@ import ( "net/http" "github.com/pkg/errors" + "golang.org/x/oauth2" + "github.com/usememos/memos/plugin/idp" "github.com/usememos/memos/store" - "golang.org/x/oauth2" ) // IdentityProvider represents an OAuth2 Identity Provider. @@ -82,6 +83,7 @@ func (p *IdentityProvider) UserInfo(token string) (*idp.IdentityProviderUserInfo if err != nil { return nil, errors.Wrap(err, "failed to read response body") } + defer resp.Body.Close() var claims map[string]any err = json.Unmarshal(body, &claims) diff --git a/plugin/idp/oauth2/oauth2_test.go b/plugin/idp/oauth2/oauth2_test.go index 035333d2..3f02b894 100644 --- a/plugin/idp/oauth2/oauth2_test.go +++ b/plugin/idp/oauth2/oauth2_test.go @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/usememos/memos/plugin/idp" "github.com/usememos/memos/store" ) diff --git a/plugin/storage/s3/s3.go b/plugin/storage/s3/s3.go index 028c563e..10b05392 100644 --- a/plugin/storage/s3/s3.go +++ b/plugin/storage/s3/s3.go @@ -2,6 +2,7 @@ package s3 import ( "context" + "errors" "fmt" "io" "strings" @@ -80,7 +81,7 @@ func (client *Client) UploadFile(ctx context.Context, filename string, fileType link = fmt.Sprintf("%s/%s%s", client.Config.URLPrefix, filename, client.Config.URLSuffix) } if link == "" { - return "", fmt.Errorf("failed to get file link") + return "", errors.New("failed to get file link") } return link, nil } diff --git a/plugin/telegram/api_edit_message.go b/plugin/telegram/api_edit_message.go index 2345d9b7..fcd8e8f3 100644 --- a/plugin/telegram/api_edit_message.go +++ b/plugin/telegram/api_edit_message.go @@ -3,9 +3,10 @@ package telegram import ( "context" "encoding/json" - "fmt" "net/url" "strconv" + + "github.com/pkg/errors" ) // EditMessage make an editMessageText api request. @@ -23,7 +24,7 @@ func (b *Bot) EditMessage(ctx context.Context, chatID, messageID int64, text str markup.InlineKeyboard = inlineKeyboards data, err := json.Marshal(markup) if err != nil { - return nil, fmt.Errorf("fail to encode inlineKeyboard: %s", err) + return nil, errors.Wrap(err, "fail to encode inlineKeyboard") } formData.Set("reply_markup", string(data)) } diff --git a/plugin/telegram/attachment.go b/plugin/telegram/attachment.go index 2afece49..d5ec9c2b 100644 --- a/plugin/telegram/attachment.go +++ b/plugin/telegram/attachment.go @@ -3,8 +3,9 @@ package telegram import ( "path" - "github.com/usememos/memos/common/log" "go.uber.org/zap" + + "github.com/usememos/memos/common/log" ) type Attachment struct { diff --git a/plugin/telegram/bot.go b/plugin/telegram/bot.go index 23454e47..43349b9a 100644 --- a/plugin/telegram/bot.go +++ b/plugin/telegram/bot.go @@ -7,8 +7,9 @@ import ( "strings" "time" - "github.com/usememos/memos/common/log" "go.uber.org/zap" + + "github.com/usememos/memos/common/log" ) type Handler interface { diff --git a/plugin/telegram/download.go b/plugin/telegram/download.go index fd931885..78be3208 100644 --- a/plugin/telegram/download.go +++ b/plugin/telegram/download.go @@ -2,10 +2,11 @@ package telegram import ( "context" - "fmt" "io" "net/http" "strings" + + "github.com/pkg/errors" ) func (b *Bot) downloadAttachment(ctx context.Context, message *Message) (*Attachment, error) { @@ -92,13 +93,13 @@ func (b *Bot) downloadFilepath(ctx context.Context, filePath string) ([]byte, er resp, err := http.Get(fileURL + "/" + filePath) if err != nil { - return nil, fmt.Errorf("fail to http.Get: %s", err) + return nil, errors.Wrap(err, "fail to http.Get") } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("fail to io.ReadAll: %s", err) + return nil, errors.Wrap(err, "fail to io.ReadAll") } return body, nil diff --git a/plugin/telegram/request.go b/plugin/telegram/request.go index b2783973..58e4f4ba 100644 --- a/plugin/telegram/request.go +++ b/plugin/telegram/request.go @@ -3,10 +3,11 @@ package telegram import ( "context" "encoding/json" - "fmt" "io" "net/http" "net/url" + + "github.com/pkg/errors" ) func (b *Bot) postForm(ctx context.Context, apiPath string, formData url.Values, result any) error { @@ -17,13 +18,13 @@ func (b *Bot) postForm(ctx context.Context, apiPath string, formData url.Values, resp, err := http.PostForm(apiURL+apiPath, formData) if err != nil { - return fmt.Errorf("fail to http.PostForm: %s", err) + return errors.Wrap(err, "fail to http.PostForm") } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { - return fmt.Errorf("fail to ioutil.ReadAll: %s", err) + return errors.Wrap(err, "fail to ioutil.ReadAll") } var respInfo struct { @@ -37,11 +38,11 @@ func (b *Bot) postForm(ctx context.Context, apiPath string, formData url.Values, err = json.Unmarshal(body, &respInfo) if err != nil { - return fmt.Errorf("fail to json.Unmarshal: %s", err) + return errors.Wrap(err, "fail to json.Unmarshal") } if !respInfo.Ok { - return fmt.Errorf("api error: [%d]%s", respInfo.ErrorCode, respInfo.Description) + return errors.Errorf("api error: [%d]%s", respInfo.ErrorCode, respInfo.Description) } return nil diff --git a/server/embed_frontend.go b/server/embed_frontend.go index a1b3aa2b..73e45536 100644 --- a/server/embed_frontend.go +++ b/server/embed_frontend.go @@ -7,6 +7,7 @@ import ( "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" + "github.com/usememos/memos/common/util" ) diff --git a/server/profile/profile.go b/server/profile/profile.go index a785c59e..5da57c3d 100644 --- a/server/profile/profile.go +++ b/server/profile/profile.go @@ -7,7 +7,9 @@ import ( "runtime" "strings" + "github.com/pkg/errors" "github.com/spf13/viper" + "github.com/usememos/memos/server/version" ) @@ -46,7 +48,7 @@ func checkDSN(dataDir string) (string, error) { dataDir = strings.TrimRight(dataDir, "\\/") 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 diff --git a/server/server.go b/server/server.go index 29251da7..2cbf5490 100644 --- a/server/server.go +++ b/server/server.go @@ -14,6 +14,8 @@ import ( "github.com/labstack/echo/v4/middleware" "github.com/pkg/errors" echoSwagger "github.com/swaggo/echo-swagger" + "go.uber.org/zap" + apiv1 "github.com/usememos/memos/api/v1" apiv2 "github.com/usememos/memos/api/v2" "github.com/usememos/memos/common/log" @@ -21,7 +23,6 @@ import ( "github.com/usememos/memos/server/profile" "github.com/usememos/memos/server/service" "github.com/usememos/memos/store" - "go.uber.org/zap" ) type Server struct { @@ -89,7 +90,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store serverID, err := s.getSystemServerID(ctx) if err != nil { - return nil, fmt.Errorf("failed to retrieve system server ID: %w", err) + return nil, errors.Wrap(err, "failed to retrieve system server ID") } s.ID = serverID @@ -105,7 +106,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store if profile.Mode == "prod" { secret, err = s.getSystemSecretSessionName(ctx) if err != nil { - return nil, fmt.Errorf("failed to retrieve system secret session name: %w", err) + return nil, errors.Wrap(err, "failed to retrieve system secret session name") } } s.Secret = secret @@ -117,7 +118,7 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store s.apiV2Service = apiv2.NewAPIV2Service(s.Secret, profile, store, s.Profile.Port+1) // Register gRPC gateway as api v2. 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") } return s, nil diff --git a/server/service/backup.go b/server/service/backup.go index b9e6f41e..ade63e86 100644 --- a/server/service/backup.go +++ b/server/service/backup.go @@ -6,10 +6,11 @@ import ( "strconv" "time" + "go.uber.org/zap" + apiv1 "github.com/usememos/memos/api/v1" "github.com/usememos/memos/common/log" "github.com/usememos/memos/store" - "go.uber.org/zap" ) type BackupRunner struct { diff --git a/server/telegram.go b/server/telegram.go index 302243f2..aadd8ab7 100644 --- a/server/telegram.go +++ b/server/telegram.go @@ -9,6 +9,7 @@ import ( "unicode/utf16" "github.com/pkg/errors" + apiv1 "github.com/usememos/memos/api/v1" "github.com/usememos/memos/plugin/telegram" "github.com/usememos/memos/store" @@ -34,7 +35,7 @@ const ( func (t *telegramHandler) MessageHandle(ctx context.Context, bot *telegram.Bot, message telegram.Message, attachments []telegram.Attachment) error { reply, err := bot.SendReplyMessage(ctx, message.Chat.ID, message.MessageID, workingMessage) if err != nil { - return fmt.Errorf("Failed to SendReplyMessage: %s", err) + return errors.Wrap(err, "Failed to SendReplyMessage") } var creatorID int32 diff --git a/store/db/db.go b/store/db/db.go index 5ac902fa..1bacbc0f 100644 --- a/store/db/db.go +++ b/store/db/db.go @@ -4,7 +4,6 @@ import ( "context" "database/sql" "embed" - "errors" "fmt" "io/fs" "os" @@ -12,6 +11,8 @@ import ( "sort" "time" + "github.com/pkg/errors" + "github.com/usememos/memos/server/profile" "github.com/usememos/memos/server/version" ) @@ -42,7 +43,7 @@ func NewDB(profile *profile.Profile) *DB { func (db *DB) Open() error { // Ensure a DSN is set before attempting to open the database. if db.profile.DSN == "" { - return fmt.Errorf("dsn required") + return errors.New("dsn required") } // Connect to the database with some sane settings: @@ -61,7 +62,7 @@ func (db *DB) Open() error { // - 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)") 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 return nil @@ -75,24 +76,24 @@ func (db *DB) Migrate(ctx context.Context) error { // If db file not exists, we should create a new one with latest schema. if errors.Is(err, os.ErrNotExist) { 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 { - return fmt.Errorf("failed to get db file stat, err: %w", err) + return errors.Wrap(err, "failed to get db file stat") } } else { // If db file exists, we should check if we need to migrate the database. currentVersion := version.GetCurrentVersion(db.profile.Mode) migrationHistoryList, err := db.FindMigrationHistoryList(ctx, &MigrationHistoryFind{}) 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 { _, err := db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{ Version: currentVersion, }) 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 } @@ -110,11 +111,11 @@ func (db *DB) Migrate(ctx context.Context) error { // backup the raw database file before migration rawBytes, err := os.ReadFile(db.profile.DSN) 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/memos_%s_%d_backup.db", db.profile.Data, db.profile.Version, time.Now().Unix()) 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") @@ -124,7 +125,7 @@ func (db *DB) Migrate(ctx context.Context) error { if version.IsVersionGreaterThan(normalizedVersion, latestMigrationHistoryVersion) && version.IsVersionGreaterOrEqualThan(currentVersion, normalizedVersion) { println("applying migration for", normalizedVersion) 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") } } } @@ -140,12 +141,12 @@ func (db *DB) Migrate(ctx context.Context) error { // In non-prod mode, we should always migrate the database. if _, err := os.Stat(db.profile.DSN); errors.Is(err, os.ErrNotExist) { 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. if db.profile.Mode == "demo" { if err := db.seed(ctx); err != nil { - return fmt.Errorf("failed to seed: %w", err) + return errors.Wrap(err, "failed to seed") } } } @@ -166,11 +167,11 @@ func (db *DB) applyLatestSchema(ctx context.Context) error { latestSchemaPath := fmt.Sprintf("%s/%s/%s", "migration", schemaMode, latestSchemaFileName) buf, err := migrationFS.ReadFile(latestSchemaPath) 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) 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: %s", stmt) } return nil } @@ -178,7 +179,7 @@ func (db *DB) applyLatestSchema(ctx context.Context) error { func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion string) error { filenames, err := fs.Glob(migrationFS, fmt.Sprintf("%s/%s/*.sql", "migration/prod", minorVersion)) 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) @@ -188,12 +189,12 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st for _, filename := range filenames { buf, err := migrationFS.ReadFile(filename) 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) migrationStmt += stmt 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: %s", stmt) } } @@ -202,7 +203,7 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st if _, err = db.UpsertMigrationHistory(ctx, &MigrationHistoryUpsert{ Version: version, }); 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 @@ -211,7 +212,7 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st func (db *DB) seed(ctx context.Context) error { filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed")) 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) @@ -220,11 +221,11 @@ func (db *DB) seed(ctx context.Context) error { for _, filename := range filenames { buf, err := seedFS.ReadFile(filename) 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) 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: %s", stmt) } } return nil @@ -239,7 +240,7 @@ func (db *DB) execute(ctx context.Context, stmt string) error { defer tx.Rollback() if _, err := tx.ExecContext(ctx, stmt); err != nil { - return fmt.Errorf("failed to execute statement, err: %w", err) + return errors.Wrap(err, "failed to execute statement") } return tx.Commit() diff --git a/store/idp.go b/store/idp.go index 61a1df8a..a0e31f0f 100644 --- a/store/idp.go +++ b/store/idp.go @@ -5,6 +5,8 @@ import ( "encoding/json" "fmt" "strings" + + "github.com/pkg/errors" ) type IdentityProviderType string @@ -70,7 +72,7 @@ func (s *Store) CreateIdentityProvider(ctx context.Context, create *IdentityProv } configBytes = bytes } else { - return nil, fmt.Errorf("unsupported idp type %s", string(create.Type)) + return nil, errors.Errorf("unsupported idp type %s", string(create.Type)) } stmt := ` @@ -146,7 +148,7 @@ func (s *Store) ListIdentityProviders(ctx context.Context, find *FindIdentityPro OAuth2Config: oauth2Config, } } else { - return nil, fmt.Errorf("unsupported idp type %s", string(identityProvider.Type)) + return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type)) } identityProviders = append(identityProviders, &identityProvider) } @@ -198,7 +200,7 @@ func (s *Store) UpdateIdentityProvider(ctx context.Context, update *UpdateIdenti } configBytes = bytes } else { - return nil, fmt.Errorf("unsupported idp type %s", string(update.Type)) + return nil, errors.Errorf("unsupported idp type %s", string(update.Type)) } set, args = append(set, "config = ?"), append(args, string(configBytes)) } @@ -231,7 +233,7 @@ func (s *Store) UpdateIdentityProvider(ctx context.Context, update *UpdateIdenti OAuth2Config: oauth2Config, } } else { - return nil, fmt.Errorf("unsupported idp type %s", string(identityProvider.Type)) + return nil, errors.Errorf("unsupported idp type %s", string(identityProvider.Type)) } s.idpCache.Store(identityProvider.ID, identityProvider) diff --git a/store/memo.go b/store/memo.go index 6fd39c3e..42bc4129 100644 --- a/store/memo.go +++ b/store/memo.go @@ -7,6 +7,8 @@ import ( "strings" "time" + "github.com/pkg/errors" + "github.com/usememos/memos/common/util" ) @@ -244,7 +246,7 @@ func (s *Store) ListMemos(ctx context.Context, find *FindMemo) ([]*Memo, error) for _, relatedMemoType := range relatedMemoTypeList { relatedMemoTypeList := strings.Split(relatedMemoType, ":") if len(relatedMemoTypeList) != 2 { - return nil, fmt.Errorf("invalid relation format") + return nil, errors.Errorf("invalid relation format") } relatedMemoID, err := util.ConvertStringToInt32(relatedMemoTypeList[0]) if err != nil { diff --git a/store/store.go b/store/store.go index ca0fad8c..ed3fe8c8 100644 --- a/store/store.go +++ b/store/store.go @@ -3,11 +3,13 @@ package store import ( "context" "database/sql" - "fmt" "sync" - "github.com/usememos/memos/server/profile" "modernc.org/sqlite" + + "github.com/pkg/errors" + + "github.com/usememos/memos/server/profile" ) // Store provides database access to all raw objects. @@ -35,7 +37,7 @@ func (s *Store) GetDB() *sql.DB { func (s *Store) BackupTo(ctx context.Context, filename string) error { conn, err := s.db.Conn(ctx) if err != nil { - return fmt.Errorf("fail to get conn %s", err) + return errors.Errorf("fail to get conn %s", err) } defer conn.Close() @@ -45,25 +47,25 @@ func (s *Store) BackupTo(ctx context.Context, filename string) error { } backupConn, ok := driverConn.(backuper) if !ok { - return fmt.Errorf("db connection is not a sqlite backuper") + return errors.Errorf("db connection is not a sqlite backuper") } bck, err := backupConn.NewBackup(filename) if err != nil { - return fmt.Errorf("fail to create sqlite backup %s", err) + return errors.Errorf("fail to create sqlite backup %s", err) } for more := true; more; { more, err = bck.Step(-1) if err != nil { - return fmt.Errorf("fail to execute sqlite backup %s", err) + return errors.Errorf("fail to execute sqlite backup %s", err) } } return bck.Finish() }) if err != nil { - return fmt.Errorf("fail to backup %s", err) + return errors.Errorf("fail to backup %s", err) } return nil diff --git a/store/user_setting.go b/store/user_setting.go index 014f450f..3b395efe 100644 --- a/store/user_setting.go +++ b/store/user_setting.go @@ -6,8 +6,9 @@ import ( "errors" "strings" - storepb "github.com/usememos/memos/proto/gen/store" "google.golang.org/protobuf/encoding/protojson" + + storepb "github.com/usememos/memos/proto/gen/store" ) type UserSetting struct { diff --git a/test/server/auth_test.go b/test/server/auth_test.go index 98dba514..372a4207 100644 --- a/test/server/auth_test.go +++ b/test/server/auth_test.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" + apiv1 "github.com/usememos/memos/api/v1" ) diff --git a/test/server/memo_relation_test.go b/test/server/memo_relation_test.go index 66103541..53179934 100644 --- a/test/server/memo_relation_test.go +++ b/test/server/memo_relation_test.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" + apiv1 "github.com/usememos/memos/api/v1" ) diff --git a/test/server/memo_test.go b/test/server/memo_test.go index fee153b9..0c0fb37c 100644 --- a/test/server/memo_test.go +++ b/test/server/memo_test.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" + apiv1 "github.com/usememos/memos/api/v1" ) diff --git a/test/server/server.go b/test/server/server.go index 852eae59..88631821 100644 --- a/test/server/server.go +++ b/test/server/server.go @@ -11,15 +11,15 @@ import ( "time" "github.com/pkg/errors" + // sqlite driver. + _ "modernc.org/sqlite" + "github.com/usememos/memos/api/auth" "github.com/usememos/memos/server" "github.com/usememos/memos/server/profile" "github.com/usememos/memos/store" "github.com/usememos/memos/store/db" "github.com/usememos/memos/test" - - // sqlite driver. - _ "modernc.org/sqlite" ) type TestingServer struct { diff --git a/test/server/system_test.go b/test/server/system_test.go index 7e0a8ce4..03ac3ebd 100644 --- a/test/server/system_test.go +++ b/test/server/system_test.go @@ -8,6 +8,7 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" + apiv1 "github.com/usememos/memos/api/v1" ) diff --git a/test/server/user_test.go b/test/server/user_test.go index 425364d3..da9c6301 100644 --- a/test/server/user_test.go +++ b/test/server/user_test.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" "github.com/stretchr/testify/require" + apiv1 "github.com/usememos/memos/api/v1" ) diff --git a/test/store/memo_relation_test.go b/test/store/memo_relation_test.go index c6918671..6c5ed77b 100644 --- a/test/store/memo_relation_test.go +++ b/test/store/memo_relation_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/store" ) diff --git a/test/store/memo_test.go b/test/store/memo_test.go index 16e9393d..dd6454e9 100644 --- a/test/store/memo_test.go +++ b/test/store/memo_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/store" ) diff --git a/test/store/resource_test.go b/test/store/resource_test.go index 86e1f138..10dde079 100644 --- a/test/store/resource_test.go +++ b/test/store/resource_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/store" ) diff --git a/test/store/storage_test.go b/test/store/storage_test.go index 23670bec..bb7901c5 100644 --- a/test/store/storage_test.go +++ b/test/store/storage_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/store" ) diff --git a/test/store/user_setting_test.go b/test/store/user_setting_test.go index da27242b..59eb192b 100644 --- a/test/store/user_setting_test.go +++ b/test/store/user_setting_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/usememos/memos/store" ) diff --git a/test/store/user_test.go b/test/store/user_test.go index 29aed53d..560eea2f 100644 --- a/test/store/user_test.go +++ b/test/store/user_test.go @@ -5,8 +5,9 @@ import ( "testing" "github.com/stretchr/testify/require" - "github.com/usememos/memos/store" "golang.org/x/crypto/bcrypt" + + "github.com/usememos/memos/store" ) func TestUserStore(t *testing.T) {