Skip to content

Commit

Permalink
lib/os: add function PathFold and PathUnfold
Browse files Browse the repository at this point in the history
The PathFold replace the path "in" with tilde "~" if its prefix match
with user's home directory from [os.UserHomeDir].

The PathUnfold expand the tilde "~/" prefix into user's home directory
using [os.UserHomeDir] and environment variables using [os.ExpandEnv]
inside the string path "in".
  • Loading branch information
shuLhan committed Jul 21, 2023
1 parent e4c61f4 commit 59b4c87
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 0 deletions.
50 changes: 50 additions & 0 deletions lib/os/os.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"log"
"os"
"path/filepath"
"strings"

"github.com/shuLhan/share/lib/ascii"
)
Expand Down Expand Up @@ -200,6 +201,55 @@ func IsFileExist(parent, relpath string) bool {
return true
}

// PathFold replace the path "in" with tilde "~" if its prefix match with
// user's home directory from [os.UserHomeDir].
func PathFold(in string) (out string, err error) {
var (
logp = `PathFold`

userHomeDir string
)

in = filepath.Clean(in)

userHomeDir, err = os.UserHomeDir()
if err != nil {
return ``, fmt.Errorf(`%s: %s: %w`, logp, in, err)
}
if strings.HasPrefix(in, userHomeDir) {
out = filepath.Join(`~`, in[len(userHomeDir):])
} else {
out = in
}
return out, nil
}

// PathUnfold expand the tilde "~/" prefix into user's home directory using
// [os.UserHomeDir] and environment variables using [os.ExpandEnv] inside
// the string path "in".
func PathUnfold(in string) (out string, err error) {
var (
logp = `PathUnfold`

userHomeDir string
)

if strings.HasPrefix(in, `~/`) {
userHomeDir, err = os.UserHomeDir()
if err != nil {
return ``, fmt.Errorf(`%s: %s: %w`, logp, in, err)
}
out = filepath.Join(userHomeDir, in[2:])
} else {
out = in
}

out = os.ExpandEnv(out)
out = filepath.Clean(out)

return out, nil
}

// RmdirEmptyAll remove directory in path if it's empty until one of the
// parent is not empty.
func RmdirEmptyAll(path string) error {
Expand Down
104 changes: 104 additions & 0 deletions lib/os/os_unix_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2023, Shulhan <[email protected]>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package os

import (
"os"
"path/filepath"
"testing"

"github.com/shuLhan/share/lib/test"
)

func TestPathFold(t *testing.T) {
type testCase struct {
path string
expPath string
}

var (
userHomeDir string
err error
)
userHomeDir, err = os.UserHomeDir()
if err != nil {
t.Fatal(err)
}

var listTestCase = []testCase{{
path: filepath.Join(userHomeDir, `tmp`),
expPath: `~/tmp`,
}, {
// Unclean path.
path: `//` + userHomeDir + `///tmp`,
expPath: `~/tmp`,
}}

var (
c testCase
gotPath string
)
for _, c = range listTestCase {
gotPath, err = PathFold(c.path)
if err != nil {
t.Fatal(err)
}
test.Assert(t, c.path, c.expPath, gotPath)
}
}

func TestPathUnfold(t *testing.T) {
type testCase struct {
path string
expPath string
}

var (
username = os.Getenv(`USER`)

workDir string
userHomeDir string
err error
)

userHomeDir, err = os.UserHomeDir()
if err != nil {
t.Fatal(err)
}

workDir, err = os.Getwd()
if err != nil {
t.Fatal(err)
}

var listTestCase = []testCase{{
path: `~/tmp`,
expPath: filepath.Join(userHomeDir, `tmp`),
}, {
path: `/home/user/~/tmp`,
expPath: `/home/user/~/tmp`,
}, {
path: `$HOME/tmp`,
expPath: filepath.Join(userHomeDir, `tmp`),
}, {
path: `/tmp/$USER/adir`,
expPath: filepath.Join(`/`, `tmp`, username, `adir`),
}, {
path: `~/$PWD/adir`,
expPath: filepath.Join(userHomeDir, workDir, `adir`),
}}

var (
c testCase
gotPath string
)
for _, c = range listTestCase {
gotPath, err = PathUnfold(c.path)
if err != nil {
t.Fatal(err)
}
test.Assert(t, c.path, c.expPath, gotPath)
}
}

0 comments on commit 59b4c87

Please sign in to comment.