Skip to content

Commit 22d1709

Browse files
akoclaude
andcommitted
fix: add RENAME WORKFLOW support (#466)
Add WORKFLOW to the renameTarget grammar rule, regenerate the ANTLR4 parser, and wire the "workflow" case through the executor dispatcher and document-exists check. RenameDocumentByName already handles workflows generically so no SDK changes are needed. Also add TestRename_Workflow_Success / _NotFound mock tests, update the pre-existing TestRename_UnsupportedType (which was using "workflow" as its unsupported-type stub), and extend 25-rename-examples.mdl with a create/rename/drop workflow example. Closes #466 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 8af0836 commit 22d1709

10 files changed

Lines changed: 8728 additions & 8631 deletions

File tree

mdl-examples/doctype-tests/25-rename-examples.mdl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@ rename java action RenameTest.OldHelper to NewHelper;
3939
-- Dry run: preview what references would change without modifying anything
4040
rename java action RenameTest.NewHelper to AnotherName dry run;
4141

42+
-- Rename workflow
43+
create workflow RenameTest.OldProcess
44+
begin
45+
end workflow;
46+
47+
rename workflow RenameTest.OldProcess to NewProcess;
48+
4249
-- Clean up
50+
drop workflow RenameTest.NewProcess;
4351
drop java action RenameTest.NewHelper;
4452
drop association RenameTest.Order_Client;
4553
drop entity RenameTest.client;

mdl/ast/ast_rename.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ package ast
77
// RENAME ENTITY Module.OldName TO NewName [DRY RUN];
88
// RENAME MODULE OldName TO NewName [DRY RUN];
99
// RENAME JAVA ACTION Module.OldName TO NewName [DRY RUN];
10-
// ... and microflow, nanoflow, page, enumeration, association, constant
10+
// ... and microflow, nanoflow, page, enumeration, association, constant, workflow
1111
type RenameStmt struct {
1212
ObjectType string // lowercase type key, e.g. "entity", "module", "javaaction"
1313
Name QualifiedName // Current name (Module.Entity or Module for modules)

mdl/executor/cmd_rename.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ func execRename(ctx *ExecContext, s *ast.RenameStmt) error {
3333
return execRenameAssociation(ctx, s)
3434
case "constant":
3535
return execRenameDocument(ctx, s, "constant")
36+
case "workflow":
37+
return execRenameDocument(ctx, s, "workflow")
3638
case "javaaction":
3739
return execRenameJavaAction(ctx, s)
3840
case "module":
@@ -200,6 +202,15 @@ func execRenameDocument(ctx *ExecContext, s *ast.RenameStmt, docType string) err
200202
break
201203
}
202204
}
205+
case "workflow":
206+
wfs, _ := ctx.Backend.ListWorkflows()
207+
for _, wf := range wfs {
208+
modID := h.FindModuleID(wf.ContainerID)
209+
if h.GetModuleName(modID) == s.Name.Module && wf.Name == s.Name.Name {
210+
found = true
211+
break
212+
}
213+
}
203214
}
204215

205216
if !found {

mdl/executor/cmd_rename_mock_test.go

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/mendixlabs/mxcli/sdk/domainmodel"
1414
"github.com/mendixlabs/mxcli/sdk/microflows"
1515
"github.com/mendixlabs/mxcli/sdk/pages"
16+
"github.com/mendixlabs/mxcli/sdk/workflows"
1617
)
1718

1819
// ---------------------------------------------------------------------------
@@ -39,7 +40,7 @@ func TestRename_UnsupportedType(t *testing.T) {
3940
mb := &mock.MockBackend{IsConnectedFunc: func() bool { return true }}
4041
ctx, _ := newMockCtx(t, withBackend(mb))
4142
err := execRename(ctx, &ast.RenameStmt{
42-
ObjectType: "workflow",
43+
ObjectType: "snippet",
4344
Name: ast.QualifiedName{Module: "M", Name: "N"},
4445
NewName: "X",
4546
})
@@ -382,3 +383,63 @@ func TestRename_JavaAction_NotFound(t *testing.T) {
382383
assertError(t, err)
383384
assertContainsStr(t, err.Error(), "not found")
384385
}
386+
387+
// ---------------------------------------------------------------------------
388+
// Rename workflow — happy path
389+
// ---------------------------------------------------------------------------
390+
391+
func TestRename_Workflow_Success(t *testing.T) {
392+
mod := mkModule("BPModule")
393+
wf := mkWorkflow(mod.ID, "OldProcess")
394+
renameCalled := false
395+
mb := &mock.MockBackend{
396+
IsConnectedFunc: func() bool { return true },
397+
ListModulesFunc: func() ([]*model.Module, error) { return []*model.Module{mod}, nil },
398+
ListFoldersFunc: func() ([]*types.FolderInfo, error) { return nil, nil },
399+
ListWorkflowsFunc: func() ([]*workflows.Workflow, error) { return []*workflows.Workflow{wf}, nil },
400+
RenameReferencesFunc: func(old, new string, dryRun bool) ([]types.RenameHit, error) {
401+
return nil, nil
402+
},
403+
RenameDocumentByNameFunc: func(module, old, newName string) error {
404+
renameCalled = true
405+
return nil
406+
},
407+
}
408+
h := mkHierarchy(mod)
409+
withContainer(h, wf.ContainerID, mod.ID)
410+
ctx, buf := newMockCtx(t, withBackend(mb), withHierarchy(h))
411+
assertNoError(t, execRename(ctx, &ast.RenameStmt{
412+
ObjectType: "workflow",
413+
Name: ast.QualifiedName{Module: "BPModule", Name: "OldProcess"},
414+
NewName: "NewProcess",
415+
}))
416+
if !renameCalled {
417+
t.Error("Expected RenameDocumentByName to be called")
418+
}
419+
assertContainsStr(t, buf.String(), "Renamed workflow")
420+
assertContainsStr(t, buf.String(), "BPModule.OldProcess")
421+
assertContainsStr(t, buf.String(), "BPModule.NewProcess")
422+
}
423+
424+
// ---------------------------------------------------------------------------
425+
// Rename workflow — not found
426+
// ---------------------------------------------------------------------------
427+
428+
func TestRename_Workflow_NotFound(t *testing.T) {
429+
mod := mkModule("BPModule")
430+
mb := &mock.MockBackend{
431+
IsConnectedFunc: func() bool { return true },
432+
ListModulesFunc: func() ([]*model.Module, error) { return []*model.Module{mod}, nil },
433+
ListFoldersFunc: func() ([]*types.FolderInfo, error) { return nil, nil },
434+
ListWorkflowsFunc: func() ([]*workflows.Workflow, error) { return nil, nil },
435+
}
436+
h := mkHierarchy(mod)
437+
ctx, _ := newMockCtx(t, withBackend(mb), withHierarchy(h))
438+
err := execRename(ctx, &ast.RenameStmt{
439+
ObjectType: "workflow",
440+
Name: ast.QualifiedName{Module: "BPModule", Name: "Missing"},
441+
NewName: "New",
442+
})
443+
assertError(t, err)
444+
assertContainsStr(t, err.Error(), "not found")
445+
}

mdl/grammar/MDLParser.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ renameStatement
306306
;
307307

308308
renameTarget
309-
: ENTITY | MICROFLOW | NANOFLOW | PAGE | ENUMERATION | ASSOCIATION | CONSTANT | JAVA ACTION
309+
: ENTITY | MICROFLOW | NANOFLOW | PAGE | ENUMERATION | ASSOCIATION | CONSTANT | JAVA ACTION | WORKFLOW
310310
;
311311

312312
/**

mdl/grammar/parser/MDLParser.interp

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

mdl/grammar/parser/mdl_lexer.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)