From b366d0e1c3fd227a69a6e107e40b83d0dbb9e686 Mon Sep 17 00:00:00 2001 From: Tom Payne Date: Sat, 30 Mar 2024 18:36:11 +0000 Subject: [PATCH] fix: Fix panic when adding children in exact_ dirs --- internal/chezmoi/sourcestate.go | 4 ++-- internal/cmd/addcmd_test.go | 19 +++++++++++++++++++ internal/cmd/testdata/scripts/issue3666.txtar | 7 +++++++ 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 internal/cmd/testdata/scripts/issue3666.txtar diff --git a/internal/chezmoi/sourcestate.go b/internal/chezmoi/sourcestate.go index 15538651a09..65aa01f0926 100644 --- a/internal/chezmoi/sourcestate.go +++ b/internal/chezmoi/sourcestate.go @@ -417,7 +417,7 @@ DEST_ABS_PATH: switch sourceStateDir, ok := node.sourceStateEntry.(*SourceStateDir); { case i != len(nodes)-1 && !ok: panic(fmt.Errorf("nodes[%d]: unexpected non-terminal source state entry, got %T", i, node.sourceStateEntry)) - case sourceStateDir.Attr.External: + case ok && sourceStateDir.Attr.External: return fmt.Errorf("%s: cannot add entry in external_ directory", destAbsPath) } } @@ -639,7 +639,7 @@ func (s *SourceState) AddDestAbsPathInfos( return nil } parentRelPath := parentAbsPath.MustTrimDirPrefix(s.destDirAbsPath) - if s.root.get(parentRelPath) != nil { + if _, ok := s.root.get(parentRelPath).(*SourceStateDir); ok { return nil } diff --git a/internal/cmd/addcmd_test.go b/internal/cmd/addcmd_test.go index 91ffd89791b..fbc7a2c61de 100644 --- a/internal/cmd/addcmd_test.go +++ b/internal/cmd/addcmd_test.go @@ -237,6 +237,25 @@ func TestAddCmd(t *testing.T) { ), }, }, + { + name: "issue_3666", + root: map[string]any{ + "/home/user": map[string]any{ + ".config/helix/themes/ayu_custom.toml": "# contents of ayu_custom.toml\n", + ".local/share/chezmoi": map[string]any{ + "dot_config/exact_helix": &vfst.Dir{Perm: 0o777 &^ chezmoitest.Umask}, + }, + }, + }, + args: []string{"~/.config/helix/themes/ayu_custom.toml"}, + tests: []any{ + vfst.TestPath("/home/user/.local/share/chezmoi/dot_config/exact_helix/themes/ayu_custom.toml", + vfst.TestModeIsRegular(), + vfst.TestModePerm(0o666&^chezmoitest.Umask), + vfst.TestContentsString("# contents of ayu_custom.toml\n"), + ), + }, + }, } { t.Run(tc.name, func(t *testing.T) { chezmoitest.SkipUnlessGOOS(t, tc.name) diff --git a/internal/cmd/testdata/scripts/issue3666.txtar b/internal/cmd/testdata/scripts/issue3666.txtar new file mode 100644 index 00000000000..deeae377d6d --- /dev/null +++ b/internal/cmd/testdata/scripts/issue3666.txtar @@ -0,0 +1,7 @@ +# test that chezmoi add creates parent directories +exec chezmoi add $HOME${/}.config/helix/themes/ayu_custom.toml +exists $CHEZMOISOURCEDIR/dot_config/exact_helix/themes/ayu_custom.toml + +-- home/user/.config/helix/themes/ayu_custom.toml -- +# contents of ayu_custom.toml +-- home/user/.local/share/chezmoi/dot_config/exact_helix/.keep --