Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: de-duplicate message IDs #1973

Merged
merged 5 commits into from
Nov 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ $(foreach dep, $(GO_DEPENDENCIES), $(eval $(call make-go-dependency, $(dep))))
$(call make-lint-dependency)

.bin/clidoc:
echo "deprecated usage, use docs/cli instead"
go build -o .bin/clidoc ./cmd/clidoc/.

docs/cli: .bin/clidoc
clidoc .
.PHONY: docs/cli
docs/cli:
go run ./cmd/clidoc/. .
Copy link
Member Author

@zepatrik zepatrik Nov 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is way easier to manage rebuilding when needed.


.bin/ory: Makefile
bash <(curl https://raw.githubusercontent.com/ory/meta/master/install.sh) -d -b .bin ory v0.1.0
Expand Down
77 changes: 68 additions & 9 deletions cmd/clidoc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import (
"encoding/json"
"fmt"
"go/ast"
"go/importer"
"go/parser"
"go/token"
"go/types"
"os"
"path/filepath"
"regexp"
Expand Down Expand Up @@ -123,12 +125,12 @@ func main() {
}

if err := validateAllMessages(filepath.Join(os.Args[1], "text")); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Unable to validate messages: %+v", err)
_, _ = fmt.Fprintf(os.Stderr, "Unable to validate messages: %+v\n", err)
os.Exit(1)
}

if err := writeMessages(filepath.Join(os.Args[1], "docs/docs/concepts/ui-user-interface.mdx")); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Unable to generate message table: %+v", err)
_, _ = fmt.Fprintf(os.Stderr, "Unable to generate message table: %+v\n", err)
os.Exit(1)
}

Expand Down Expand Up @@ -192,25 +194,82 @@ func writeMessages(path string) error {
}

func validateAllMessages(path string) error {
type message struct {
ID, Name string
}

usedIDs := make([]message, 0, len(messages))
set := token.NewFileSet()
packs, err := parser.ParseDir(set, path, nil, 0)
if err != nil {
return errors.Wrapf(err, "unable to parse text directory")
}
info := &types.Info{
Defs: make(map[*ast.Ident]types.Object),
}
var pack *ast.Package
for _, p := range packs {
if p.Name == "text" {
pack = p
break
}
}
allFiles := make([]*ast.File, 0)
for fn, f := range pack.Files {
if strings.HasSuffix(fn, "/id.go") {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and hence we only load that file (hard-coded).

allFiles = append(allFiles, f)
}
}
_, err = (&types.Config{Importer: importer.Default()}).Check("text", set, allFiles, info)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gave me a bit of a hard time, as I could not get it to properly resolve imports from modules. Therefore, the warning in the id.go file.

if err != nil {
return err // type error
}

for _, pack := range packs {
for _, f := range pack.Files {
for _, d := range f.Decls {
if fn, isFn := d.(*ast.FuncDecl); isFn {
if name := fn.Name.String(); fn.Name.IsExported() && strings.HasPrefix(name, "New") {
if _, ok := messages[name]; !ok {
return errors.Errorf("expected to find message %s in the list for the documentation generation but could not", name)
for _, f := range pack.Files {
for _, d := range f.Decls {
switch decl := d.(type) {
case *ast.FuncDecl:
if name := decl.Name.String(); decl.Name.IsExported() && strings.HasPrefix(name, "New") {
if _, ok := messages[name]; !ok {
return errors.Errorf("expected to find message %s in the list for the documentation generation but could not", name)
}
}
case *ast.GenDecl:
if decl.Tok == token.CONST {
for _, spec := range decl.Specs {
value := spec.(*ast.ValueSpec) // safe because decl.Tok is token.CONST
if t, ok := value.Type.(*ast.Ident); ok {
if t.Name == "ID" {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This filters to use const's only of type ID (i.e. hard-coded).

for _, name := range value.Names {
c := info.ObjectOf(name)
if c == nil {
return errors.Errorf("expected to find const %s in text/id.go", name.Name)
}
usedIDs = append(usedIDs, message{
ID: c.(*types.Const).Val().ExactString(),
Name: name.Name,
})
}
}
}
}
}
}
}
}

sort.Slice(usedIDs, func(i, j int) bool {
return usedIDs[i].ID < usedIDs[j].ID
})
for i := 1; i < len(usedIDs); i++ {
if usedIDs[i].ID == usedIDs[i-1].ID {
return errors.Errorf("message ID %s is used more than once: %s %s", usedIDs[i].ID, usedIDs[i].Name, usedIDs[i-1].Name)
}
}

return nil
}

type importerFunc func(path string) (*types.Package, error)

func (f importerFunc) Import(path string) (*types.Package, error) { return f(path) }
46 changes: 23 additions & 23 deletions docs/docs/concepts/ui-user-interface.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1423,17 +1423,6 @@ will be overwritten!
}
```

###### An email containing a verification link has been sent to the email address you provided. (1070001)

```json
{
"id": 1070001,
"text": "An email containing a verification link has been sent to the email address you provided.",
"type": "info",
"context": {}
}
```

###### Password (1070001)

```json
Expand All @@ -1444,16 +1433,6 @@ will be overwritten!
}
```

###### You successfully verified your email address. (1070002)

```json
{
"id": 1070002,
"text": "You successfully verified your email address.",
"type": "info"
}
```

###### {title} (1070002)

```json
Expand Down Expand Up @@ -1514,6 +1493,27 @@ will be overwritten!
}
```

###### An email containing a verification link has been sent to the email address you provided. (1080001)

```json
{
"id": 1080001,
"text": "An email containing a verification link has been sent to the email address you provided.",
"type": "info",
"context": {}
}
```

###### You successfully verified your email address. (1080002)

```json
{
"id": 1080002,
"text": "You successfully verified your email address.",
"type": "info"
}
```

###### {reason} (4000001)

```json
Expand Down Expand Up @@ -1545,8 +1545,8 @@ will be overwritten!
"text": "Length must be \u003e= 1, but got 2.",
"type": "error",
"context": {
"expected_length": 1,
"actual_length": 2
"actual_length": 2,
"expected_length": 1
}
}
```
Expand Down
124 changes: 124 additions & 0 deletions text/id.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
package text

// This file MUST not have any imports to modules that are not in the standard library.
// Otherwise, `make docs/cli` will fail.
Comment on lines +3 to +4
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this warning


type ID int

const (
InfoSelfServiceLoginRoot ID = 1010000 + iota // 1010000
InfoSelfServiceLogin // 1010001
InfoSelfServiceLoginWith // 1010002
InfoSelfServiceLoginReAuth // 1010003
InfoSelfServiceLoginMFA // 1010004
InfoSelfServiceLoginVerify // 1010005
InfoSelfServiceLoginTOTPLabel // 1010006
InfoLoginLookupLabel // 1010007
InfoSelfServiceLoginWebAuthn // 1010008
InfoLoginTOTP // 1010009
InfoLoginLookup // 1010010
)

const (
InfoSelfServiceLogout ID = 1020000 + iota
)
Expand All @@ -10,6 +27,113 @@ const (
InfoSelfServiceMFA ID = 1030000 + iota
)

const (
InfoSelfServiceRegistrationRoot ID = 1040000 + iota // 1040000
InfoSelfServiceRegistration // 1040001
InfoSelfServiceRegistrationWith // 1040002
InfoRegistrationContinue // 1040003
)

const (
InfoSelfServiceSettings ID = 1050000 + iota
InfoSelfServiceSettingsUpdateSuccess
InfoSelfServiceSettingsUpdateLinkOidc
InfoSelfServiceSettingsUpdateUnlinkOidc
InfoSelfServiceSettingsUpdateUnlinkTOTP
InfoSelfServiceSettingsTOTPQRCode
InfoSelfServiceSettingsTOTPSecret
InfoSelfServiceSettingsRevealLookup
InfoSelfServiceSettingsRegenerateLookup
InfoSelfServiceSettingsLookupSecret
InfoSelfServiceSettingsLookupSecretLabel
InfoSelfServiceSettingsLookupConfirm
InfoSelfServiceSettingsRegisterWebAuthn
InfoSelfServiceSettingsRegisterWebAuthnDisplayName
InfoSelfServiceSettingsLookupSecretUsed
InfoSelfServiceSettingsLookupSecretList
InfoSelfServiceSettingsDisableLookup
InfoSelfServiceSettingsTOTPSecretLabel
)

const (
InfoSelfServiceRecovery ID = 1060000 + iota // 1060000
InfoSelfServiceRecoverySuccessful // 1060001
InfoSelfServiceRecoveryEmailSent // 1060002
)

const (
InfoNodeLabel ID = 1070000 + iota // 1070000
InfoNodeLabelInputPassword // 1070001
InfoNodeLabelGenerated // 1070002
InfoNodeLabelSave // 1070003
InfoNodeLabelID // 1070004
InfoNodeLabelSubmit // 1070005
InfoNodeLabelVerifyOTP // 1070006
InfoNodeLabelEmail // 1070007
)

const (
InfoSelfServiceVerification ID = 1080000 + iota // 1070000
InfoSelfServiceVerificationEmailSent // 1070001
InfoSelfServiceVerificationSuccessful // 1070002
)

const (
ErrorValidation ID = 4000000 + iota
ErrorValidationGeneric
ErrorValidationRequired
ErrorValidationMinLength
ErrorValidationInvalidFormat
ErrorValidationPasswordPolicyViolation
ErrorValidationInvalidCredentials
ErrorValidationDuplicateCredentials
ErrorValidationTOTPVerifierWrong
ErrorValidationIdentifierMissing
ErrorValidationAddressNotVerified
ErrorValidationNoTOTPDevice
ErrorValidationLookupAlreadyUsed
ErrorValidationNoWebAuthnDevice
ErrorValidationNoLookup
)

const (
ErrorValidationLogin ID = 4010000 + iota // 4010000
ErrorValidationLoginFlowExpired // 4010001
ErrorValidationLoginNoStrategyFound // 4010002
ErrorValidationRegistrationNoStrategyFound // 4010003
ErrorValidationSettingsNoStrategyFound // 4010004
ErrorValidationRecoveryNoStrategyFound // 4010005
ErrorValidationVerificationNoStrategyFound // 4010006
)

const (
ErrorValidationRegistration ID = 4040000 + iota
ErrorValidationRegistrationFlowExpired
)

const (
ErrorValidationSettings ID = 4050000 + iota
ErrorValidationSettingsFlowExpired
)

const (
ErrorValidationRecovery ID = 4060000 + iota // 4060000
ErrorValidationRecoveryRetrySuccess // 4060001
ErrorValidationRecoveryStateFailure // 4060002
ErrorValidationRecoveryMissingRecoveryToken // 4060003
ErrorValidationRecoveryTokenInvalidOrAlreadyUsed // 4060004
ErrorValidationRecoveryFlowExpired // 4060005
)

const (
ErrorValidationVerification ID = 4070000 + iota // 4070000
ErrorValidationVerificationTokenInvalidOrAlreadyUsed // 4070001
ErrorValidationVerificationRetrySuccess // 4070002
ErrorValidationVerificationStateFailure // 4070003
ErrorValidationVerificationMissingVerificationToken // 4070004
ErrorValidationVerificationFlowExpired // 4070005
)

const (
ErrorSystem ID = 5000000 + iota
ErrorSystemGeneric
Expand Down
24 changes: 0 additions & 24 deletions text/message_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,6 @@ import (
"time"
)

const (
InfoSelfServiceLoginRoot ID = 1010000 + iota // 1010000
InfoSelfServiceLogin // 1010001
InfoSelfServiceLoginWith // 1010002
InfoSelfServiceLoginReAuth // 1010003
InfoSelfServiceLoginMFA // 1010004
InfoSelfServiceLoginVerify // 1010005
InfoSelfServiceLoginTOTPLabel // 1010006
InfoLoginLookupLabel // 1010007
InfoSelfServiceLoginWebAuthn // 1010008
InfoLoginTOTP // 1010009
InfoLoginLookup // 1010010
)

const (
ErrorValidationLogin ID = 4010000 + iota // 4010000
ErrorValidationLoginFlowExpired // 4010001
ErrorValidationLoginNoStrategyFound // 4010002
ErrorValidationRegistrationNoStrategyFound // 4010003
ErrorValidationSettingsNoStrategyFound // 4010004
ErrorValidationRecoveryNoStrategyFound // 4010005
ErrorValidationVerificationNoStrategyFound // 4010006
)

func NewInfoLoginReAuth() *Message {
return &Message{
ID: InfoSelfServiceLoginReAuth,
Expand Down
11 changes: 0 additions & 11 deletions text/message_node.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
package text

const (
InfoNodeLabel ID = 1070000 + iota // 1070000
InfoNodeLabelInputPassword // 1070001
InfoNodeLabelGenerated // 1070002
InfoNodeLabelSave // 1070003
InfoNodeLabelID // 1070004
InfoNodeLabelSubmit // 1070005
InfoNodeLabelVerifyOTP // 1070006
InfoNodeLabelEmail // 1070007
)

func NewInfoNodeLabelVerifyOTP() *Message {
return &Message{
ID: InfoNodeLabelVerifyOTP,
Expand Down
Loading