Skip to content

Commit

Permalink
feat(link): create parent folder with mkdir: true
Browse files Browse the repository at this point in the history
resolves #227
  • Loading branch information
JanDeDobbeleer committed Dec 29, 2024
1 parent 818be5e commit 2639f29
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 16 deletions.
43 changes: 39 additions & 4 deletions src/shell/link.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
package shell

import (
"os"
"path/filepath"

"github.com/jandedobbeleer/aliae/src/context"
)

type Links []*Link

type Link struct {
Name Template `yaml:"name"`
Target Template `yaml:"target"`
If If `yaml:"if"`

Name Template `yaml:"name"`
Target Template `yaml:"target"`
If If `yaml:"if"`
template string
MkDir bool `yaml:"mkdir"`
force bool
}

func (l *Link) string() string {
// avoid parsing multiple times
l.Name = l.Name.Parse()
l.Target = l.Target.Parse()

// do not process if the link already exists or the target does not exist
if l.exists(string(l.Name)) || (!l.force && !l.exists(string(l.Target))) {
return ""
}

if l.MkDir {
l.buildPath()
}

switch context.Current.Shell {
case ZSH, BASH, FISH, XONSH:
return l.zsh().render()
Expand All @@ -31,6 +48,24 @@ func (l *Link) string() string {
}
}

func (l *Link) exists(path string) bool {
_, err := os.Stat(path)
return err == nil
}

func (l *Link) buildPath() {
parent := filepath.Dir(string(l.Name))

_, err := os.Stat(parent)
if err == nil {
return
}

if os.IsNotExist(err) {
_ = os.MkdirAll(parent, 0644)
}
}

func (l *Link) render() string {
script, err := parse(l.template, l)
if err != nil {
Expand Down
12 changes: 6 additions & 6 deletions src/shell/link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

func TestLinkCommand(t *testing.T) {
link := &Link{Name: "foo", Target: "bar"}
link := &Link{Name: "foo", Target: "bar", force: true}
cases := []struct {
Case string
Shell string
Expand Down Expand Up @@ -80,23 +80,23 @@ func TestLinkRender(t *testing.T) {
{
Case: "Single link",
Links: Links{
&Link{Name: "FOO", Target: "bar"},
&Link{Name: "FOO", Target: "bar", force: true},
},
Expected: "ln -sf bar FOO",
},
{
Case: "Double link",
Links: Links{
&Link{Name: "FOO", Target: "bar"},
&Link{Name: "BAR", Target: "foo"},
&Link{Name: "FOO", Target: "bar", force: true},
&Link{Name: "BAR", Target: "foo", force: true},
},
Expected: `ln -sf bar FOO
ln -sf foo BAR`,
},
{
Case: "Filtered out",
Links: Links{
&Link{Name: "FOO", Target: "bar", If: `eq .Shell "fish"`},
&Link{Name: "FOO", Target: "bar", If: `eq .Shell "fish"`, force: true},
},
},
}
Expand Down Expand Up @@ -133,7 +133,7 @@ func TestLinkWithTemplate(t *testing.T) {
}

for _, tc := range cases {
link := &Link{Name: "/tmp/l", Target: tc.Target}
link := &Link{Name: "/tmp/l", Target: tc.Target, force: true}
context.Current = &context.Runtime{Shell: BASH, Home: "/Users/jan", OS: context.WINDOWS}
assert.Equal(t, tc.Expected, link.string(), tc.Case)
}
Expand Down
13 changes: 7 additions & 6 deletions website/docs/setup/link.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Symbolic Link
sidebar_label: 🔗 Symbolic Link
---

Create symlinks to files and directories. Useful for dotfiles.
Create symlinks to files and directories. Will validate the targets exist before creating the link.

### Syntax

Expand All @@ -21,11 +21,12 @@ link:
### Link
| Name | Type | Description |
| -------- | -------- | ------------------------------------------------------------------------------ |
| `name` | `string` | the link name, supports [templating][templates] |
| `target` | `string` | the name of the file or directory to link to, supports [templating][templates] |
| `if` | `string` | golang [template][go-text-template] conditional statement, see [if][if] |
| Name | Type | Description |
| -------- | --------- | ------------------------------------------------------------------------------ |
| `name` | `string` | the link name, supports [templating][templates] |
| `target` | `string` | the name of the file or directory to link to, supports [templating][templates] |
| `if` | `string` | golang [template][go-text-template] conditional statement, see [if][if] |
| `mkdir` | `boolean` | create `name`'s parent folder when it does not exist |

[go-text-template]: https://golang.org/pkg/text/template/
[if]: if.mdx
Expand Down

0 comments on commit 2639f29

Please sign in to comment.