ln implemented.

This commit is contained in:
Andrey Parhomenko 2023-03-08 16:39:50 +03:00
parent 5140f3591b
commit afa0e736bd
6 changed files with 120 additions and 67 deletions

View file

@ -7,6 +7,7 @@ install-sh:VQ: build
fi fi
if test -d app ; then if test -d app ; then
echo Installing application files... echo Installing application files...
echo "'$APPDIR'"
mkdir -p $APPDIR/$PKG_NAME && cp -rf app/* $APPDIR/$PKG_NAME/ mkdir -p $APPDIR/$PKG_NAME && cp -rf app/* $APPDIR/$PKG_NAME/
echo Done installing application files echo Done installing application files
fi fi

View file

@ -1,66 +1,67 @@
package main package main
import( import (
mtool "github.com/surdeus/gomtool/src/multitool" "github.com/surdeus/goblin/src/tool/awk"
"github.com/surdeus/goblin/src/tool/basename"
"github.com/surdeus/goblin/src/tool/cat" "github.com/surdeus/goblin/src/tool/cat"
"github.com/surdeus/goblin/src/tool/date"
"github.com/surdeus/goblin/src/tool/ec"
"github.com/surdeus/goblin/src/tool/echo" "github.com/surdeus/goblin/src/tool/echo"
"github.com/surdeus/goblin/src/tool/mkdir" "github.com/surdeus/goblin/src/tool/ftest"
"github.com/surdeus/goblin/src/tool/gtrue"
"github.com/surdeus/goblin/src/tool/gfalse" "github.com/surdeus/goblin/src/tool/gfalse"
"github.com/surdeus/goblin/src/tool/grange"
"github.com/surdeus/goblin/src/tool/gtrue"
"github.com/surdeus/goblin/src/tool/in"
"github.com/surdeus/goblin/src/tool/ln"
"github.com/surdeus/goblin/src/tool/ls"
"github.com/surdeus/goblin/src/tool/mergelbl"
"github.com/surdeus/goblin/src/tool/mk"
"github.com/surdeus/goblin/src/tool/mkdir"
"github.com/surdeus/goblin/src/tool/noext"
"github.com/surdeus/goblin/src/tool/path"
"github.com/surdeus/goblin/src/tool/paths"
"github.com/surdeus/goblin/src/tool/quote"
"github.com/surdeus/goblin/src/tool/read"
"github.com/surdeus/goblin/src/tool/sort" "github.com/surdeus/goblin/src/tool/sort"
"github.com/surdeus/goblin/src/tool/tac" "github.com/surdeus/goblin/src/tool/tac"
"github.com/surdeus/goblin/src/tool/ls"
"github.com/surdeus/goblin/src/tool/yes"
"github.com/surdeus/goblin/src/tool/date"
"github.com/surdeus/goblin/src/tool/uniq" "github.com/surdeus/goblin/src/tool/uniq"
"github.com/surdeus/goblin/src/tool/quote"
"github.com/surdeus/goblin/src/tool/urlprs" "github.com/surdeus/goblin/src/tool/urlprs"
"github.com/surdeus/goblin/src/tool/noext"
"github.com/surdeus/goblin/src/tool/mergelbl"
"github.com/surdeus/goblin/src/tool/basename"
"github.com/surdeus/goblin/src/tool/ec"
"github.com/surdeus/goblin/src/tool/read"
"github.com/surdeus/goblin/src/tool/wc"
"github.com/surdeus/goblin/src/tool/ftest"
"github.com/surdeus/goblin/src/tool/grange"
"github.com/surdeus/goblin/src/tool/in"
"github.com/surdeus/goblin/src/tool/useprog" "github.com/surdeus/goblin/src/tool/useprog"
"github.com/surdeus/goblin/src/tool/path" "github.com/surdeus/goblin/src/tool/wc"
"github.com/surdeus/goblin/src/tool/mk"
"github.com/surdeus/goblin/src/tool/awk"
"github.com/surdeus/goblin/src/tool/paths"
"github.com/surdeus/goblin/src/tool/whoami" "github.com/surdeus/goblin/src/tool/whoami"
"github.com/surdeus/goblin/src/tool/yes"
mtool "github.com/surdeus/gomtool/src/multitool"
) )
func main() { func main() {
tools := mtool.Tools { tools := mtool.Tools{
"basename" : mtool.Tool{basename.Run, "get base name of file path"}, "basename": mtool.Tool{basename.Run, "get base name of file path"},
"cat": mtool.Tool{cat.Run, "print file data to the standard output"}, "cat": mtool.Tool{cat.Run, "print file data to the standard output"},
"mkdir" : mtool.Tool{mkdir.Run, "make new directory"}, "mkdir": mtool.Tool{mkdir.Run, "make new directory"},
"echo" : mtool.Tool{echo.Run, "print strings to the standard output"}, "echo": mtool.Tool{echo.Run, "print strings to the standard output"},
"true" : mtool.Tool{gtrue.Run, "exit with true status"}, "true": mtool.Tool{gtrue.Run, "exit with true status"},
"false" : mtool.Tool{gfalse.Run, "exit with false status"}, "false": mtool.Tool{gfalse.Run, "exit with false status"},
"sort" : mtool.Tool{sort.Run, "sort strings inputed from standard input"}, "sort": mtool.Tool{sort.Run, "sort strings inputed from standard input"},
"tac" : mtool.Tool{tac.Run, "print strings from standard input in reversed order"}, "tac": mtool.Tool{tac.Run, "print strings from standard input in reversed order"},
"ls" :mtool.Tool{ ls.Run, "list directory content"}, "ls": mtool.Tool{ls.Run, "list directory content"},
"yes" : mtool.Tool{ yes.Run, "print string infinite/exact amount times"}, "yes": mtool.Tool{yes.Run, "print string infinite/exact amount times"},
"date" : mtool.Tool{date.Run, "print current date"}, "date": mtool.Tool{date.Run, "print current date"},
"uniq" : mtool.Tool{uniq.Run, "filter repeated strings"}, "uniq": mtool.Tool{uniq.Run, "filter repeated strings"},
"quote" : mtool.Tool{quote.Run, "quote words containing space characters"}, "quote": mtool.Tool{quote.Run, "quote words containing space characters"},
"urlprs" : mtool.Tool{urlprs.Run, "parse URLs"}, "urlprs": mtool.Tool{urlprs.Run, "parse URLs"},
"noext" : mtool.Tool{noext.Run, "print file path without extension"}, "noext": mtool.Tool{noext.Run, "print file path without extension"},
"mergelbl" : mtool.Tool{mergelbl.Run, "merge line by line"}, "mergelbl": mtool.Tool{mergelbl.Run, "merge line by line"},
"ec" : mtool.Tool{ec.Run, "render escape sequences"}, "ec": mtool.Tool{ec.Run, "render escape sequences"},
"read" : mtool.Tool{read.Run, "read lines and exit"}, "read": mtool.Tool{read.Run, "read lines and exit"},
"wc" : mtool.Tool{wc.Run, "count words, bytes, runes etc"}, "wc": mtool.Tool{wc.Run, "count words, bytes, runes etc"},
"ftest" : mtool.Tool{ftest.Run, "filter files by specified features"}, "ftest": mtool.Tool{ftest.Run, "filter files by specified features"},
"range" : mtool.Tool{grange.Run, "too lazy"}, "range": mtool.Tool{grange.Run, "too lazy"},
"in" : mtool.Tool{in.Run, "filter strings from stdin that aren not in arguments"}, "in": mtool.Tool{in.Run, "filter strings from stdin that aren not in arguments"},
"useprog" : mtool.Tool{useprog.Run, "print the name of the first existing program in arg list"}, "useprog": mtool.Tool{useprog.Run, "print the name of the first existing program in arg list"},
"path" : mtool.Tool{path.Run, "print cross platform path based on cmd arguments"}, "path": mtool.Tool{path.Run, "print cross platform path based on cmd arguments"},
"mk" : mtool.Tool{mk.Run, "file dependency system, simpler make"}, "mk": mtool.Tool{mk.Run, "file dependency system, simpler make"},
"awk" : mtool.Tool{awk.Run, "simple scripting language for working with string templates"}, "awk": mtool.Tool{awk.Run, "simple scripting language for working with string templates"},
"paths" : mtool.Tool{ "paths": mtool.Tool{
paths.Run, paths.Run,
"convert UNIX slash separated paths into the OS compatible ones", "convert UNIX slash separated paths into the OS compatible ones",
}, },
@ -68,6 +69,10 @@ func main() {
whoami.Run, whoami.Run,
"print current user name", "print current user name",
}, },
"ln": mtool.Tool{
ln.Run,
"link files",
},
} }
mtool.Main("goblin", tools) mtool.Main("goblin", tools)

View file

@ -4,15 +4,15 @@ package pathx
// paths. // paths.
import ( import (
fp "path/filepath"
"path" "path"
fp "path/filepath"
"strings" "strings"
) )
type Value string type Value string
type Path struct { type Path struct {
Values []Value Values []Value
IsAbs bool IsAbs bool
} }
func (p Path) Append(values ...string) Path { func (p Path) Append(values ...string) Path {
@ -28,10 +28,10 @@ func From(p string) Path {
return ret return ret
} }
p = path.Clean(p) /* p = path.Clean(p)
if p[0] == '/' { if p[0] == '/' {
ret.IsAbs = true ret.IsAbs = true
} } */
p, _ = strings.CutSuffix(p, "/") p, _ = strings.CutSuffix(p, "/")
svalues := strings.Split(p, "/") svalues := strings.Split(p, "/")
@ -44,6 +44,10 @@ func From(p string) Path {
return ret return ret
} }
func FromReal(p string) Path {
return From(fp.ToSlash(p))
}
func (v Value) IsValid() bool { func (v Value) IsValid() bool {
return v.Err() == nil return v.Err() == nil
} }
@ -66,11 +70,17 @@ func (p Path) StringValues() []string {
} }
func (p Path) Real() string { func (p Path) Real() string {
return fp.Join(p.StringValues()...) return strings.Join(p.StringValues(), string(fp.Separator))
} }
func (p Path) String() string { func (p Path) String() string {
return path.Join(p.StringValues()...) ret := ""
if p.IsAbs {
ret = "/"
}
ret += path.Join(p.StringValues()...)
return ret
} }
func (p Path) IsValid() bool { func (p Path) IsValid() bool {
@ -92,4 +102,3 @@ func (p Path) Err() error {
return nil return nil
} }

35
src/tool/ln/main.go Normal file
View file

@ -0,0 +1,35 @@
package ln
import (
"flag"
"fmt"
"os"
)
func Run(args []string) {
var lflag bool
flagSet := flag.NewFlagSet(args[0], flag.ExitOnError)
flagSet.BoolVar(&lflag, "s", false, "make a symbolic link, not a hard one")
flagSet.Parse(args[1:])
args = flagSet.Args()
if len(args) != 2 {
flagSet.Usage()
os.Exit(1)
}
src := args[0]
dst := args[1]
var err error
if lflag {
err = os.Symlink(src, dst)
} else {
err = os.Link(src, dst)
}
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
}

View file

@ -9,6 +9,7 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
"sync" "sync"
"github.com/surdeus/goblin/src/pathx" "github.com/surdeus/goblin/src/pathx"
) )
@ -93,7 +94,6 @@ const (
) )
// Build a node's prereqs. Block until completed. // Build a node's prereqs. Block until completed.
//
func mkNodePrereqs(g *graph, u *node, e *edge, prereqs []*node, dryrun bool, func mkNodePrereqs(g *graph, u *node, e *edge, prereqs []*node, dryrun bool,
required bool) nodeStatus { required bool) nodeStatus {
prereqstat := make(chan nodeStatus) prereqstat := make(chan nodeStatus)
@ -131,11 +131,11 @@ func mkNodePrereqs(g *graph, u *node, e *edge, prereqs []*node, dryrun bool,
// concurrently. // concurrently.
// //
// Args: // Args:
// g: Graph in which the node lives.
// u: Node to (possibly) build.
// dryrun: Don't actually build anything, just pretend.
// required: Avoid building this node, unless its prereqs are out of date.
// //
// g: Graph in which the node lives.
// u: Node to (possibly) build.
// dryrun: Don't actually build anything, just pretend.
// required: Avoid building this node, unless its prereqs are out of date.
func mkNode(g *graph, u *node, dryrun bool, required bool) { func mkNode(g *graph, u *node, dryrun bool, required bool) {
// try to claim on this node // try to claim on this node
u.mutex.Lock() u.mutex.Lock()
@ -327,10 +327,10 @@ func Run(args []string) {
arg0 := args[0] arg0 := args[0]
args = args[1:] args = args[1:]
if mkincdir := os.Getenv("MKINCDIR") ; if mkincdir := os.Getenv("MKINCDIR"); mkincdir == "" {
mkincdir == "" {
homeDir, _ := os.UserHomeDir() homeDir, _ := os.UserHomeDir()
os.Setenv("MKINCDIR", homeDir + "/app/goblin/mk/inc" ) homeDir = pathx.FromReal(homeDir).String()
os.Setenv("MKINCDIR", homeDir+"/app/goblin/mk/inc")
} }
flags := flag.NewFlagSet(arg0, flag.ExitOnError) flags := flag.NewFlagSet(arg0, flag.ExitOnError)

View file

@ -10,6 +10,7 @@ import (
"path/filepath" "path/filepath"
"regexp" "regexp"
"strings" "strings"
"github.com/surdeus/goblin/src/pathx" "github.com/surdeus/goblin/src/pathx"
) )
@ -169,9 +170,11 @@ func parseRedirInclude(p *parser, t token) parserStateFun {
true, true,
)[0] )[0]
} }
file, err := os.Open(pathx.From(filename).Real()) pths := pathx.From(filename)
file, err := os.Open(pths.Real())
if err != nil { if err != nil {
p.basicWarnAtToken(fmt.Sprintf("cannot open %s", filename), p.tokenbuf[0]) p.basicWarnAtToken(fmt.Sprintf("cannot open %s", filename), p.tokenbuf[0])
//fmt.Printf("%q %q %q\n", pths.Values, pths.Real(), pths.String())
//p.basicErrorAtToken(fmt.Sprintf("cannot open %s", filename), p.tokenbuf[0]) //p.basicErrorAtToken(fmt.Sprintf("cannot open %s", filename), p.tokenbuf[0])
} }
input, _ := io.ReadAll(file) input, _ := io.ReadAll(file)