Skip to content

Commit

Permalink
Introducing manpath support.
Browse files Browse the repository at this point in the history
  • Loading branch information
otaviof committed Sep 27, 2019
1 parent 118e643 commit 0760d7b
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 41 deletions.
80 changes: 48 additions & 32 deletions pkg/path-helper/path_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import (
// PathHelper represents the application path-helper. Takes a configuration as input, and uses local
// attributes to keep list of files and directories to compose PATH.
type PathHelper struct {
config *Config // parsed command-line flags
files []string // slice of files in path.d
directories []string // directories that will compose PATH
config *Config // parsed command-line flags
}

// logger for path-helper instance, skip printing when verbose is off.
Expand All @@ -23,44 +21,46 @@ func (p *PathHelper) logger(format string, v ...interface{}) {
}

// append a directory in global list, making sure it skips duplicates when setting is enabled.
func (p *PathHelper) append(directory string) {
func (p *PathHelper) append(directories []string, directory string) []string {
if p.config.SkipDuplicates {
for _, d := range p.directories {
for _, d := range directories {
if d == directory {
p.logger("[WARN] Skipping entry '%s', is already defined.", directory)
return
return directories
}
}
}
p.directories = append(p.directories, directory)
return append(directories, directory)
}

// globPathFiles load list of files in base directory. Returns errors when base directory does not
// exist or when having issues to execute globing.
func (p *PathHelper) globPathFiles() error {
baseDir := p.config.BaseDir
func (p *PathHelper) globPathFiles(baseDir string) ([]string, error) {
p.logger("Inspecting paths directory: '%s'", baseDir)
if !dirExists(baseDir) {
return fmt.Errorf("can't find base directory at '%s'", baseDir)
return nil, fmt.Errorf("can't find base directory at '%s'", baseDir)
}

var err error
pattern := path.Join(baseDir, "*")
p.files, err = filepath.Glob(pattern)
return err
files, err := filepath.Glob(pattern)
if err != nil {
return nil, err
}
return files, nil
}

// gatherPathDirs based in path files, read and inspect direcotories listed in those. Can return
// errors related to reading files.
func (p *PathHelper) gatherPathDirs() error {
for _, file := range p.files {
// inspectPathDirectories based in path files, read and inspect direcotories listed in those. Can
// return errors related to reading files.
func (p *PathHelper) inspectPathDirectories(files []string) ([]string, error) {
directories := []string{}
for _, file := range files {
p.logger("File '%s'", file)
directories, err := readLines(file)
lines, err := readLines(file)
if err != nil {
return fmt.Errorf("can't read file '%s': '%v'", file, err)
return nil, fmt.Errorf("can't read file '%s': '%v'", file, err)
}

for _, directory := range directories {
for _, directory := range lines {
p.logger("\t- '%s'", directory)
if strings.HasPrefix(directory, "#") {
continue
Expand All @@ -69,35 +69,51 @@ func (p *PathHelper) gatherPathDirs() error {
p.logger("[WARN] Directory '%s' (%s) is not found! Skipping.", directory, file)
continue
}
p.append(directory)
directories = p.append(directories, directory)
}
}
return nil
return directories, nil
}

// collect glob for files and open them to extract contents. File contents are threated as path
// directories, therefore configuration directive applies on them. It can return error when having
// problems to glob directories and on reading files.
func (p *PathHelper) collect(baseDir string) ([]string, error) {
files, err := p.globPathFiles(baseDir)
if err != nil {
return nil, err
}
directories, err := p.inspectPathDirectories(files)
if err != nil {
return nil, err
}
return directories, nil
}

// pathDirsColonJoined return slice of direcotires joined by colon.
func (p *PathHelper) pathDirsColonJoined() string {
return strings.Join(p.directories, ":")
func (p *PathHelper) colonJoin(directories []string) string {
return strings.Join(directories, ":")
}

// RenderExpression print out the shell expression exporting PATH. Will forward errors from methods
// listing and reading path files, and inspecting direcotories present found in those files.
func (p *PathHelper) RenderExpression() (string, error) {
if err := p.globPathFiles(); err != nil {
pathDirectories, err := p.collect(p.config.PathBaseDir)
if err != nil {
return "", err
}
if err := p.gatherPathDirs(); err != nil {

manDirectories, err := p.collect(p.config.ManBaseDir)
if err != nil {
return "", err
}

return fmt.Sprintf("export PATH=\"%s\"", p.pathDirsColonJoined()), nil
expr := fmt.Sprintf(`PATH="%s" ; MANPATH="%s" ; export PATH MANPATH ;`,
p.colonJoin(pathDirectories), p.colonJoin(manDirectories))
return expr, nil
}

// NewPathHelper instantiate a PathHelper type.
func NewPathHelper(config *Config) *PathHelper {
return &PathHelper{
config: config,
files: []string{},
directories: []string{},
}
return &PathHelper{config: config}
}
21 changes: 12 additions & 9 deletions pkg/path-helper/path_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ func TestPathHelper(t *testing.T) {
SkipDuplicates: true,
SkipNotFound: true,
Verbose: true,
BaseDir: "../../test/paths.d",
ManBaseDir: "../../test/paths.d",
PathBaseDir: "../../test/paths.d",
}
expectedJoinedPaths := "/a/a/a:/b/b/b:/c/c/c:/d/d/d"
expectedJoinedPathsDuplicated := "/a/a/a:/b/b/b:/c/c/c:/d/d/d:/d/d/d"
Expand Down Expand Up @@ -72,19 +73,19 @@ func TestPathHelper(t *testing.T) {
// share the test context and expected characteristics.
func assertFilesAndDirectories(t *testing.T, c *Config, expectedLen int, expectedPaths string) {
p := NewPathHelper(c)
err := p.globPathFiles()
files, err := p.globPathFiles(c.PathBaseDir)
t.Logf("Error: '%#v", err)
assert.NoError(t, err)
t.Logf("Files: '%#v'", p.files)
assert.True(t, len(p.files) >= expectedLen)
t.Logf("Files: '%#v'", files)
assert.True(t, len(files) >= expectedLen)

err = p.gatherPathDirs()
directories, err := p.inspectPathDirectories(files)
t.Logf("Error: '%#v", err)
assert.NoError(t, err)
t.Logf("Directories: '%#v'", p.directories)
assert.True(t, len(p.directories) >= expectedLen)
t.Logf("Directories: '%#v'", directories)
assert.True(t, len(directories) >= expectedLen)

assert.Equal(t, expectedPaths, p.pathDirsColonJoined())
assert.Equal(t, expectedPaths, p.colonJoin(directories))
}

// assertExpression assert primary objective of this app, the shell expression to export PATH. Method
Expand All @@ -95,5 +96,7 @@ func assertExpression(t *testing.T, c *Config, expectedExpression string) {
assert.NoError(t, err)
t.Logf("Expression: '%s'", s)
assert.NotEmpty(t, s)
assert.Equal(t, fmt.Sprintf("export PATH=\"%s\"", expectedExpression), s)
expr := fmt.Sprintf(`PATH="%s" ; MANPATH="%s" ; export PATH MANPATH ;`,
expectedExpression, expectedExpression)
assert.Equal(t, expr, s)
}

0 comments on commit 0760d7b

Please sign in to comment.