Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
20 changes: 6 additions & 14 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,17 @@ lint:
tidy:
go mod tidy

generate:
openapi-generator-cli generate \
-i ./membership-swagger.yaml \
-g go \
-o ./membershipclient \
--git-user-id=formancehq \
--git-repo-id=fctl \
-p packageVersion=latest \
-p isGoSubmodule=true \
-p packageName=membershipclient \
-p disallowAdditionalPropertiesIfNotPresent=false
rm -rf ./membershipclient/test
rm -rf ./membershipclient/docs
generate: generate-deploy-server-client generate-membership-client
@go generate ./...
g: generate

[group('generate')]
generate-client:
generate-deploy-server-client:
@cd internal/deployserverclient && speakeasy run --skip-versioning

generate-membership-client:
@cd internal/membershipclient && speakeasy run --skip-versioning
Comment on lines +20 to +24
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify the directories exist with proper Speakeasy configuration.

Ensure that internal/deployserverclient and internal/membershipclient directories exist and contain the necessary Speakeasy configuration files (e.g., .speakeasy/workflow.yaml or similar). Also confirm that the --skip-versioning flag is intentional for both targets.

Run the following script to verify the directory structure:


🏁 Script executed:

#!/bin/bash
# Description: Verify that Speakeasy directories exist and contain configuration.

# Check if directories exist
fd -t d '^(deployserverclient|membershipclient)$' internal/

# Look for Speakeasy configuration files
fd -t f '(workflow\.yaml|gen\.yaml|\.speakeasy)' internal/deployserverclient internal/membershipclient

Length of output: 55



---

🏁 Script executed:

```shell
#!/bin/bash
# Description: List contents of Speakeasy directories to verify proper setup

echo "=== Contents of internal/deployserverclient ==="
fd -t f '' internal/deployserverclient/ | head -20

echo ""
echo "=== Contents of internal/membershipclient ==="
fd -t f '' internal/membershipclient/ | head -20

echo ""
echo "=== Check for .speakeasy directory ==="
fd -t d '.speakeasy' internal/

echo ""
echo "=== Look for any YAML/config files in internal/ related to these clients ==="
rg -l 'speakeasy|openapi' internal/deployserverclient internal/membershipclient 2>/dev/null || echo "No config matches found"

Length of output: 563



---

🏁 Script executed:

```shell
#!/bin/bash
# Description: Check repository structure and verify if directories exist at all

echo "=== Current directory ==="
pwd

echo ""
echo "=== Repository exists? Check for .git ==="
ls -la | grep -E '^\.' | head -5

echo ""
echo "=== List top-level directories in repo ==="
ls -d */ 2>/dev/null | head -20

echo ""
echo "=== Check if internal directory exists ==="
[ -d internal ] && echo "internal/ EXISTS" || echo "internal/ DOES NOT EXIST"

echo ""
echo "=== If internal exists, list its contents ==="
if [ -d internal ]; then
  ls -la internal/ | head -20
fi

Length of output: 513



---

🏁 Script executed:

```shell
#!/bin/bash
# Description: Verify Speakeasy configuration in client directories

echo "=== Files in internal/deployserverclient ==="
find internal/deployserverclient -type f -o -type d | head -30

echo ""
echo "=== Files in internal/membershipclient ==="
find internal/membershipclient -type f -o -type d | head -30

echo ""
echo "=== Look for Speakeasy workflow configs ==="
find internal/deployserverclient internal/membershipclient -name "*workflow*" -o -name "*gen.yaml" -o -name "*.speakeasy"

echo ""
echo "=== Check for gen.yaml or speakeasy config at any level ==="
find internal/deployserverclient internal/membershipclient -type f \( -name "*.yaml" -o -name "*.yml" -o -name "*.json" \) | head -20

Length of output: 4028



---

🏁 Script executed:

```shell
#!/bin/bash
# Description: Look for Speakeasy configuration in root and other locations

echo "=== Check root directory for Speakeasy config ==="
find . -maxdepth 2 -type f \( -name "gen.yaml" -o -name "workflow.yaml" \) 2>/dev/null

echo ""
echo "=== Check for .speakeasy directory anywhere ==="
find . -type d -name ".speakeasy" 2>/dev/null

echo ""
echo "=== Look for speakeasy references in repository ==="
rg -l "speakeasy" --type-list 2>/dev/null | head -10

echo ""
echo "=== Check Justfile for other speakeasy references ==="
rg -n "speakeasy" Justfile 2>/dev/null || echo "No speakeasy in Justfile"

echo ""
echo "=== List files in root directory ==="
ls -la | grep -E '(gen\.|workflow|spec|openapi)' || echo "No config files matching pattern"

Length of output: 423


Missing Speakeasy configuration prevents the targets from functioning.

The Justfile targets attempt to run speakeasy run --skip-versioning in internal/deployserverclient and internal/membershipclient, but these directories contain only generated client code (models, documentation) with no Speakeasy configuration files. The repository also lacks any root-level Speakeasy configuration (gen.yaml, .speakeasy/workflow.yaml, or .speakeasy/ directory).

Add the necessary Speakeasy configuration files to enable these targets to execute successfully. Either:

  • Place gen.yaml or .speakeasy/workflow.yaml in each client directory, or
  • Configure the targets to run from a directory containing the proper Speakeasy configuration files.
🤖 Prompt for AI Agents
In Justfile around lines 20 to 24, the generate-deploy-server-client and
generate-membership-client targets run speakeasy in directories that only
contain generated client code and lack Speakeasy config; add Speakeasy
configuration or change the target directories: either add a gen.yaml or
.speakeasy/workflow.yaml (or .speakeasy/ directory) into
internal/deployserverclient and internal/membershipclient so speakeasy run can
execute there, or modify the Justfile targets to cd into a directory that
already contains the repository-level Speakeasy config (or pass the appropriate
--config / --workflow flags) so speakeasy finds its configuration before
running.



tests:
echo "not implemented"
Expand Down
15 changes: 12 additions & 3 deletions cmd/auth/clients/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,18 @@ func (c *CreateController) GetStore() *CreateStore {
}

func (c *CreateController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

if !fctl.CheckStackApprobation(cmd, store.Stack(), "You are about to create a new OAuth2 client") {
_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

if !fctl.CheckStackApprobation(cmd, "You are about to create a new OAuth2 client") {
return nil, fctl.ErrMissingApproval
}

Expand All @@ -95,7 +104,7 @@ func (c *CreateController) Run(cmd *cobra.Command, args []string) (fctl.Renderab
PostLogoutRedirectUris: fctl.GetStringSlice(cmd, c.postLogoutRedirectUriFlag),
Scopes: fctl.GetStringSlice(cmd, c.scopes),
}
response, err := store.Client().Auth.V1.CreateClient(cmd.Context(), &request)
response, err := stackClient.Auth.V1.CreateClient(cmd.Context(), &request)
if err != nil {
return nil, err
}
Expand Down
15 changes: 12 additions & 3 deletions cmd/auth/clients/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,25 @@ func (c *DeleteController) GetStore() *DeleteStore {
}

func (c *DeleteController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

if !fctl.CheckStackApprobation(cmd, store.Stack(), "You are about to delete an OAuth2 client") {
_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

if !fctl.CheckStackApprobation(cmd, "You are about to delete an OAuth2 client") {
return nil, fctl.ErrMissingApproval
}

request := operations.DeleteClientRequest{
ClientID: args[0],
}
response, err := store.Client().Auth.V1.DeleteClient(cmd.Context(), request)
response, err := stackClient.Auth.V1.DeleteClient(cmd.Context(), request)
if err != nil {
return nil, err
}
Expand Down
13 changes: 11 additions & 2 deletions cmd/auth/clients/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,18 @@ func (c *ListController) GetStore() *ListStore {
}

func (c *ListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

clients, err := store.Client().Auth.V1.ListClients(cmd.Context())
_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

clients, err := stackClient.Auth.V1.ListClients(cmd.Context())
if err != nil {
return nil, err
}
Expand Down
14 changes: 11 additions & 3 deletions cmd/auth/clients/secrets/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,17 @@ func (c *CreateController) GetStore() *CreateStore {

func (c *CreateController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {

store := fctl.GetStackStore(cmd.Context())
_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

if !fctl.CheckStackApprobation(cmd, store.Stack(), "You are about to create a new client secret") {
if !fctl.CheckStackApprobation(cmd, "You are about to create a new client secret") {
return nil, fctl.ErrMissingApproval
}

Expand All @@ -62,7 +70,7 @@ func (c *CreateController) Run(cmd *cobra.Command, args []string) (fctl.Renderab
Metadata: nil,
},
}
response, err := store.Client().Auth.V1.CreateSecret(cmd.Context(), request)
response, err := stackClient.Auth.V1.CreateSecret(cmd.Context(), request)
if err != nil {
return nil, err
}
Expand Down
14 changes: 11 additions & 3 deletions cmd/auth/clients/secrets/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,25 @@ func (c *DeleteController) GetStore() *DeleteStore {

func (c *DeleteController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {

store := fctl.GetStackStore(cmd.Context())
_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

if !fctl.CheckStackApprobation(cmd, store.Stack(), "You are about to delete a client secret") {
if !fctl.CheckStackApprobation(cmd, "You are about to delete a client secret") {
return nil, fctl.ErrMissingApproval
}

request := operations.DeleteSecretRequest{
ClientID: args[0],
SecretID: args[1],
}
response, err := store.Client().Auth.V1.DeleteSecret(cmd.Context(), request)
response, err := stackClient.Auth.V1.DeleteSecret(cmd.Context(), request)
if err != nil {
return nil, err
}
Expand Down
13 changes: 11 additions & 2 deletions cmd/auth/clients/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,21 @@ func (c *ShowController) GetStore() *ShowStore {
}

func (c *ShowController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

request := operations.ReadClientRequest{
ClientID: args[0],
}
response, err := store.Client().Auth.V1.ReadClient(cmd.Context(), request)
response, err := stackClient.Auth.V1.ReadClient(cmd.Context(), request)
if err != nil {
return nil, err
}
Expand Down
14 changes: 11 additions & 3 deletions cmd/auth/clients/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,17 @@ func (c *UpdateController) GetStore() *UpdateStore {

func (c *UpdateController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {

store := fctl.GetStackStore(cmd.Context())
_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

if !fctl.CheckStackApprobation(cmd, store.Stack(), "You are about to delete an OAuth2 client") {
if !fctl.CheckStackApprobation(cmd, "You are about to update an OAuth2 client") {
return nil, fctl.ErrMissingApproval
}

Expand All @@ -106,7 +114,7 @@ func (c *UpdateController) Run(cmd *cobra.Command, args []string) (fctl.Renderab
Scopes: fctl.GetStringSlice(cmd, c.scopes),
},
}
response, err := store.Client().Auth.V1.UpdateClient(cmd.Context(), request)
response, err := stackClient.Auth.V1.UpdateClient(cmd.Context(), request)
if err != nil {
return nil, err
}
Expand Down
3 changes: 0 additions & 3 deletions cmd/auth/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,5 @@ func NewCommand() *cobra.Command {
clients.NewCommand(),
users.NewCommand(),
),
fctl.WithPersistentPreRunE(func(cmd *cobra.Command, args []string) error {
return fctl.NewStackStore(cmd)
}),
)
}
14 changes: 12 additions & 2 deletions cmd/auth/users/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,18 @@ func (c *ListController) GetStore() *ListStore {
}

func (c *ListController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())
listUsersResponse, err := store.Client().Auth.V1.ListUsers(cmd.Context())

_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

listUsersResponse, err := stackClient.Auth.V1.ListUsers(cmd.Context())
if err != nil {
return nil, err
}
Expand Down
13 changes: 11 additions & 2 deletions cmd/auth/users/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,21 @@ func (c *ShowController) GetStore() *ShowStore {
}

func (c *ShowController) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetStackStore(cmd.Context())

_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

stackClient, err := fctl.NewStackClientFromFlags(cmd, relyingParty, fctl.NewPTermDialog(), profileName, *profile)
if err != nil {
return nil, err
}

request := operations.ReadUserRequest{
UserID: args[0],
}
readUserResponse, err := store.Client().Auth.V1.ReadUser(cmd.Context(), request)
readUserResponse, err := stackClient.Auth.V1.ReadUser(cmd.Context(), request)
if err != nil {
return nil, err
}
Expand Down
18 changes: 12 additions & 6 deletions cmd/cloud/apps/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,24 @@ func (c *CreateCtrl) GetStore() *Create {
return c.store
}

func (c *CreateCtrl) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
cfg, err := fctl.GetConfig(cmd)
func (c *CreateCtrl) Run(cmd *cobra.Command, _ []string) (fctl.Renderable, error) {

_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}
membershipStore := fctl.GetMembershipStore(cmd.Context())
organizationID, err := fctl.ResolveOrganizationID(cmd, cfg, membershipStore.Client())

organizationID, apiClient, err := fctl.NewAppDeployClientFromFlags(
cmd,
relyingParty,
fctl.NewPTermDialog(),
profileName,
*profile,
)
if err != nil {
return nil, err
}
store := fctl.GetDeployServerStore(cmd.Context())
apps, err := store.Cli.CreateApp(cmd.Context(), components.CreateAppRequest{
apps, err := apiClient.CreateApp(cmd.Context(), components.CreateAppRequest{
OrganizationID: organizationID,
})
if err != nil {
Expand Down
18 changes: 16 additions & 2 deletions cmd/cloud/apps/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,26 @@ func (c *DeleteCtrl) GetStore() *Delete {
}

func (c *DeleteCtrl) Run(cmd *cobra.Command, args []string) (fctl.Renderable, error) {
store := fctl.GetDeployServerStore(cmd.Context())
_, profile, profileName, relyingParty, err := fctl.LoadAndAuthenticateCurrentProfile(cmd)
if err != nil {
return nil, err
}

_, apiClient, err := fctl.NewAppDeployClientFromFlags(
cmd,
relyingParty,
fctl.NewPTermDialog(),
profileName,
*profile,
)
if err != nil {
return nil, err
}
id := fctl.GetString(cmd, "id")
if id == "" {
return nil, fmt.Errorf("id is required")
}
_, err := store.Cli.DeleteApp(cmd.Context(), id)
_, err = apiClient.DeleteApp(cmd.Context(), id)
if err != nil {
return nil, err
}
Expand Down
Loading