From e793321e1ea891cadf794e8f6208a4cad3fdc940 Mon Sep 17 00:00:00 2001 From: Virgil Date: Wed, 1 Apr 2026 22:56:14 +0000 Subject: [PATCH] Add lineinfile create support --- modules.go | 7 +++++++ modules_file_test.go | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/modules.go b/modules.go index f7fb0be..c1bb5c1 100644 --- a/modules.go +++ b/modules.go @@ -592,6 +592,7 @@ func (e *Executor) moduleLineinfile(ctx context.Context, client sshExecutorClien regexp := getStringArg(args, "regexp", "") state := getStringArg(args, "state", "present") backrefs := getBoolArg(args, "backrefs", false) + create := getBoolArg(args, "create", false) if state == "absent" { if regexp != "" { @@ -602,6 +603,12 @@ func (e *Executor) moduleLineinfile(ctx context.Context, client sshExecutorClien } } } else { + // Create the file first when requested so regexp-based updates have a + // target to operate on. + if create { + _, _, _, _ = client.Run(ctx, sprintf("touch %q", path)) + } + // state == present if regexp != "" { // Replace line matching regexp. diff --git a/modules_file_test.go b/modules_file_test.go index a57fd96..28d1b30 100644 --- a/modules_file_test.go +++ b/modules_file_test.go @@ -1,6 +1,7 @@ package ansible import ( + "context" "io/fs" "testing" @@ -403,6 +404,22 @@ func TestModulesFile_ModuleLineinfile_Good_RegexpFallsBackToAppend(t *testing.T) assert.True(t, mock.hasExecuted(`echo`)) } +func TestModulesFile_ModuleLineinfile_Good_CreateFile(t *testing.T) { + e, mock := newTestExecutorWithMock("host1") + + result, err := e.moduleLineinfile(context.Background(), mock, map[string]any{ + "path": "/etc/example.conf", + "regexp": "^setting=", + "line": "setting=value", + "create": true, + }) + + require.NoError(t, err) + assert.True(t, result.Changed) + assert.True(t, mock.hasExecuted(`touch "/etc/example\.conf"`)) + assert.True(t, mock.hasExecuted(`sed -i`)) +} + func TestModulesFile_ModuleLineinfile_Good_BackrefsReplaceMatchOnly(t *testing.T) { e, mock := newTestExecutorWithMock("host1")