From 9a678140a2c523805f79d03bc0bcbbaf75d474d1 Mon Sep 17 00:00:00 2001 From: Refaktor Date: Sat, 4 May 2024 12:44:21 +0200 Subject: [PATCH] Devops1 - ryel tools POC, small fixes, script embedding (#207) * changing Rye shell to basic ansi colors, so it themable in terminals and works in emacs ansi-term * added testing for failures in various do functions, ssh sever basics * new funcs like nl and pink, ssh integration and example, errors tests starting * ryel tools, embed_main flag, small fixes all around --- .gitignore | 2 ++ _sandbox/ryel.rye | 39 -------------------------- bin/ryel | 12 ++++++++ bin/ryelc | 8 ++++++ env/object.go | 4 +-- evaldo/builtins.go | 21 +++++++------- evaldo/builtins_io.go | 3 +- evaldo/builtins_math.go | 2 +- evaldo/builtins_psutil.go | 2 +- evaldo/builtins_spreadsheet.go | 47 +++++++++++++++++-------------- go.sum | 1 + main.go | 29 +++++++++++++------ option_do_main.go | 6 ++++ option_do_main_not.go | 6 ++++ option_embed_main.go | 13 +++++++++ option_embed_main_not.go | 10 +++++++ planing.md | 2 +- serve_wasm.rye | 2 +- tests/misc.rye | 16 ++++++----- tests/structures.rye | 4 +-- util/microliner.go | 3 ++ util/ryel | 9 ------ util/ryel.rye | 51 ++++++++++++++++++++++++++++++++++ util/ryelc | 3 -- util/util.go | 2 +- wasm/ryeshell/index.html | 12 ++++++-- 26 files changed, 199 insertions(+), 110 deletions(-) delete mode 100644 _sandbox/ryel.rye create mode 100755 bin/ryel create mode 100755 bin/ryelc create mode 100644 option_do_main.go create mode 100644 option_do_main_not.go create mode 100644 option_embed_main.go create mode 100644 option_embed_main_not.go delete mode 100755 util/ryel create mode 100644 util/ryel.rye delete mode 100755 util/ryelc diff --git a/.gitignore b/.gitignore index 8ec5f920..cd7e8b66 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,5 @@ dist/ tests/*.html shell_*.rye console_*.rye + +buildtemp/main.rye \ No newline at end of file diff --git a/_sandbox/ryel.rye b/_sandbox/ryel.rye deleted file mode 100644 index 63686b60..00000000 --- a/_sandbox/ryel.rye +++ /dev/null @@ -1,39 +0,0 @@ -; # Rye local binary* -; -; *This is experimental way to work with rye interpreter* -; -; This Rye script looks at local rye.mod and tries to build Rye binary with listed bindings - -; for outside of rye source dir -; a=$PWD ; cd ~/go/src/rye ; go build -tags "b_tiny,b_http,b_bleve" -o "$a/ryel" ; cd "$a" - - -build-ryel: fn { } { - - print "___ ____, . __" - print "|__) \ / |__ | /\ |\ | / _`" - print "| \ | |___ |___ /~~\ | \| \__>" - print "============================================" - print "Building local Rye interpreter with modules:" - - open %rye.mod - |fix-either - { print "Create rye.mod file and list modules." " nil " } - { .read-all } - |load - |map { .to-string .concat* "b_" } - |join-with " " :modules |print - - command: $a=%PWD ; cd ~/go/src/rye ; go build -tags "b_tiny $ + modules + $" -o "%a/ryel" ; cd "%a"$ - command .replace "%" "$" :command - cmd command -} - -install-ryel: fn { } { - print "Installing Ryel ..." -} - -rye .args -> 2 :mode = "build" |if { build-ryel } -if mode = "install" { install-ryel } - -; Later when script is executed and it returns a failure of missing known binding it adds it to the list diff --git a/bin/ryel b/bin/ryel new file mode 100755 index 00000000..9eaef8b6 --- /dev/null +++ b/bin/ryel @@ -0,0 +1,12 @@ +#!/bin/bash + +# This is a first **proof of concept** only, the naming, the functionality might change. Please propose changes if you see any faults, +# especially security implications. + +FILE=$PWD/ryel +if [ -f "$FILE" ]; then +# echo "Starting local rye interpreter" + $FILE "$@" +else + echo "You don't have local Ryel binary yet. Define ryel.mod if needed and run ryelc build" +fi diff --git a/bin/ryelc b/bin/ryelc new file mode 100755 index 00000000..8a0ef20b --- /dev/null +++ b/bin/ryelc @@ -0,0 +1,8 @@ +#!/bin/bash + +# This is a first **proof of concept** only, the naming, the functionality might change. Please propose changes if you see any faults, +# especially security implications. + +# Assumes normal rye build (at least tiny is on the PATH), but we don't define RYE_HOME or anything like this for now, maybe we should + +rye $RYE_HOME/util/ryel.rye $@ diff --git a/env/object.go b/env/object.go index e1cfd1b3..9c3bfb12 100644 --- a/env/object.go +++ b/env/object.go @@ -410,7 +410,7 @@ func (b Block) Inspect(e Idxs) string { func (b Block) Print(e Idxs) string { var r strings.Builder - r.WriteString("{ ") + // r.WriteString("{ ") for i := 0; i < b.Series.Len(); i += 1 { if b.Series.Get(i) != nil { r.WriteString(b.Series.Get(i).Print(e)) @@ -419,7 +419,7 @@ func (b Block) Print(e Idxs) string { r.WriteString("[NIL]") } } - r.WriteString("}") + // r.WriteString("}") return r.String() } diff --git a/evaldo/builtins.go b/evaldo/builtins.go index e1c30ab0..e1d64f5b 100644 --- a/evaldo/builtins.go +++ b/evaldo/builtins.go @@ -233,9 +233,8 @@ func getFrom(ps *env.ProgramState, data any, key any, posMode bool) env.Object { if posMode { idx-- } - v := s1.Data[idx] - ok := true - if ok { + if len(s1.Data) >= int(idx)+1 { + v := s1.Data[idx] return env.ToRyeValue(v) } else { ps.FailureFlag = true @@ -249,9 +248,8 @@ func getFrom(ps *env.ProgramState, data any, key any, posMode bool) env.Object { if posMode { idx-- } - v := s1.Data[idx] - ok := true - if ok { + if len(s1.Data) >= int(idx)+1 { + v := s1.Data[idx] return env.ToRyeValue(v) } else { ps.FailureFlag = true @@ -265,9 +263,8 @@ func getFrom(ps *env.ProgramState, data any, key any, posMode bool) env.Object { if posMode { idx-- } - v := s1.Series.Get(int(idx)) - ok := true - if ok { + if len(s1.Series.S) >= int(idx)+1 { + v := s1.Series.Get(int(idx)) return v } else { ps.FailureFlag = true @@ -7405,7 +7402,11 @@ var builtins = map[string]*env.Builtin{ Argsn: 1, Doc: "", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { - return *env.NewString(strings.Join(os.Args[2:], " ")) + if len(os.Args) > 1 { + return *env.NewString(strings.Join(os.Args[2:], " ")) + } else { + return *env.NewString("") + } // block, _ := loader.LoadString(os.Args[0], false) // return block }, diff --git a/evaldo/builtins_io.go b/evaldo/builtins_io.go index bad3e06f..e9d1e259 100755 --- a/evaldo/builtins_io.go +++ b/evaldo/builtins_io.go @@ -42,8 +42,7 @@ func __input(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Ob func __open(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { switch s := arg0.(type) { case env.Uri: - path := strings.Split(s.Path, "://") - file, err := os.Open(path[1]) + file, err := os.Open(s.Path) if err != nil { return makeError(ps, err.Error()) } diff --git a/evaldo/builtins_math.go b/evaldo/builtins_math.go index 93de9f63..b93e3b11 100644 --- a/evaldo/builtins_math.go +++ b/evaldo/builtins_math.go @@ -393,7 +393,7 @@ var Builtins_math = map[string]*env.Builtin{ return DialectMath(ps, arg0) }, }, - "math": { + "calc": { Argsn: 1, Doc: "Do math dialect", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { diff --git a/evaldo/builtins_psutil.go b/evaldo/builtins_psutil.go index 129d4491..1265af05 100644 --- a/evaldo/builtins_psutil.go +++ b/evaldo/builtins_psutil.go @@ -116,7 +116,7 @@ var Builtins_devops = map[string]*env.Builtin{ }, }, - "ls": { + "lsd": { Argsn: 0, Doc: "Returns current working directory.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { diff --git a/evaldo/builtins_spreadsheet.go b/evaldo/builtins_spreadsheet.go index 7964d60f..5feafdbc 100644 --- a/evaldo/builtins_spreadsheet.go +++ b/evaldo/builtins_spreadsheet.go @@ -496,15 +496,38 @@ var Builtins_spreadsheet = map[string]*env.Builtin{ }, }, - "sort-col!": { - Argsn: 2, + "sort-by!": { + Argsn: 3, Doc: "Sorts row by given column.", Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { + dir, ok := arg2.(env.Word) + if !ok { + return MakeArgError(ps, 3, []env.Type{env.WordType}, "sort-col!") + } + var dirAsc bool + if dir.Index == ps.Idx.IndexWord("asc") { + dirAsc = true + } else if dir.Index == ps.Idx.IndexWord("desc") { + dirAsc = false + } else { + return MakeBuiltinError(ps, "Direction can be just asc or desc.", "sort-col!") + } switch spr := arg0.(type) { case env.Spreadsheet: switch col := arg1.(type) { + case env.String: + if dirAsc { + SortByColumn(ps, &spr, col.Value) + } else { + SortByColumnDesc(ps, &spr, col.Value) + } + return spr case env.Word: - SortByColumn(ps, &spr, ps.Idx.GetWord(col.Index)) + if dirAsc { + SortByColumn(ps, &spr, ps.Idx.GetWord(col.Index)) + } else { + SortByColumnDesc(ps, &spr, ps.Idx.GetWord(col.Index)) + } return spr default: return MakeArgError(ps, 2, []env.Type{env.WordType}, "sort-col!") @@ -514,24 +537,6 @@ var Builtins_spreadsheet = map[string]*env.Builtin{ } }, }, - "sort-col\\desc!": { - Argsn: 2, - Doc: "Sorts rows by given column, descending.", - Fn: func(ps *env.ProgramState, arg0 env.Object, arg1 env.Object, arg2 env.Object, arg3 env.Object, arg4 env.Object) env.Object { - switch spr := arg0.(type) { - case env.Spreadsheet: - switch col := arg1.(type) { - case env.Word: - SortByColumnDesc(ps, &spr, ps.Idx.GetWord(col.Index)) - return spr - default: - return MakeArgError(ps, 2, []env.Type{env.WordType}, "sort-col\\desc!") - } - default: - return MakeArgError(ps, 1, []env.Type{env.SpreadsheetType}, "sort-col\\desc!") - } - }, - }, "columns": { Argsn: 2, Doc: "Returs spreasheet with just given columns.", diff --git a/go.sum b/go.sum index 12889226..f15bfa70 100644 --- a/go.sum +++ b/go.sum @@ -178,6 +178,7 @@ github.com/refaktor/go-peg v0.0.0-20220116201714-31e3dfa8dc7d h1:FXrWUGgPRzhaZIB github.com/refaktor/go-peg v0.0.0-20220116201714-31e3dfa8dc7d/go.mod h1:iIkrsFobLIWX8kQ6Oqj4cl4nwdMSE92DWpWwk9YlG9s= github.com/refaktor/liner v1.2.10 h1:MjbQj9EfNuSFnNk9zan37xpkNIRpsWKenyIBg7FZdVw= github.com/refaktor/liner v1.2.10/go.mod h1:ziZSGVYZ4OzZ9kbeB254MtIrxxQlDibULRQGlDi1iK8= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= diff --git a/main.go b/main.go index 811bdda1..08f33e31 100644 --- a/main.go +++ b/main.go @@ -98,9 +98,21 @@ func main() { evaldo.ShowResults = !*silent + var code string + if *do != "" { + code = *do + } + // Check for --help flag if flag.NFlag() == 0 && flag.NArg() == 0 { - main_rye_repl(os.Stdin, os.Stdout, true, false) + if Option_Embed_Main { + main_rye_file("buildtemp/main.rye", false, true, *console, code) + } else if Option_Do_Main { + ryeFile := dotsToMainRye(".") + main_rye_file(ryeFile, false, true, *console, code) + } else { + main_rye_repl(os.Stdin, os.Stdout, true, false) + } } else { // Check for --help flag if *help { @@ -108,11 +120,6 @@ func main() { os.Exit(0) } - var code string - if *do != "" { - code = *do - } - args := flag.Args() // Check for subcommands (cont) and handle them if len(args) > 0 { @@ -218,7 +225,7 @@ func dotsToMainRye(ryeFile string) string { re := regexp.MustCompile(`^\.$|/\.$`) if re.MatchString(ryeFile) { main_path := ryeFile[:len(ryeFile)-1] + "main.rye" - if _, err := os.Stat(main_path); err == nil { + if _, err := os.Stat(main_path); err == nil || Option_Embed_Main { _, err := os.ReadFile(main_path) if err != nil { log.Fatal(err) @@ -397,7 +404,13 @@ func main_rye_file(file string, sig bool, subc bool, interactive bool, code stri content = util.ReadSecure(file, password) } else if file != "" { - bcontent, err := os.ReadFile(file) + var bcontent []byte + var err error + if Option_Embed_Main { + bcontent, err = Rye_files.ReadFile(file) + } else { + bcontent, err = os.ReadFile(file) + } if err != nil { log.Fatal(err) } diff --git a/option_do_main.go b/option_do_main.go new file mode 100644 index 00000000..1e4e255e --- /dev/null +++ b/option_do_main.go @@ -0,0 +1,6 @@ +//go:build do_main +// +build do_main + +package main + +const Option_Do_Main bool = true diff --git a/option_do_main_not.go b/option_do_main_not.go new file mode 100644 index 00000000..999c80a4 --- /dev/null +++ b/option_do_main_not.go @@ -0,0 +1,6 @@ +//go:build !do_main +// +build !do_main + +package main + +const Option_Do_Main bool = false diff --git a/option_embed_main.go b/option_embed_main.go new file mode 100644 index 00000000..e512aabf --- /dev/null +++ b/option_embed_main.go @@ -0,0 +1,13 @@ +//go:build embed_main +// +build embed_main + +package main + +import ( + "embed" +) + +const Option_Embed_Main bool = true + +//go:embed buildtemp/main.rye +var Rye_files embed.FS diff --git a/option_embed_main_not.go b/option_embed_main_not.go new file mode 100644 index 00000000..f453597d --- /dev/null +++ b/option_embed_main_not.go @@ -0,0 +1,10 @@ +//go:build !embed_main +// +build !embed_main + +package main + +import "embed" + +const Option_Embed_Main bool = false + +var Rye_files embed.FS diff --git a/planing.md b/planing.md index 949ec2c1..cffa1f8a 100644 --- a/planing.md +++ b/planing.md @@ -137,7 +137,7 @@ Pratik is adding standard math functions from https://pkg.go.dev/math to the con - Create standard commands / utils like cd / ls / mkdir / cp / mv [+-] - Integrate awesome script library for many standard piping commands https://github.com/bitfield/script [--] -### do_main build flag and Android test +### do_main build flag and Android test [+-] if build flag do_main is used make the dot behaviour work even without the dot. Usefull for distributing binary and main.rye , also to test to produce a mobil APK with Fyne. diff --git a/serve_wasm.rye b/serve_wasm.rye index 5ca9a913..b155cf41 100644 --- a/serve_wasm.rye +++ b/serve_wasm.rye @@ -5,7 +5,7 @@ rye .needs { http } -new-server ":8085" +http-server ":8085" |handle "/" new-static-handler %wasm |serve diff --git a/tests/misc.rye b/tests/misc.rye index bb5f05ae..848ab0b3 100644 --- a/tests/misc.rye +++ b/tests/misc.rye @@ -382,29 +382,31 @@ section "Math functions" equal { do\in math { atan 1 } } 0.7853981633974483 } -group "atan2" + group "atan2" mold\nowrap "" { { string } } { equal { do\in math { atan2 3 4 } } 0.6435011087932844 } - -group "atanh" + + group "atanh" mold\nowrap "" { { string } } { equal { do\in math { atanh 0.5 } } 0.5493061443340548 } - -group "ceil" + + group "ceil" mold\nowrap "" { { string } } { equal { do\in math { ceil 5.7 } } 6.000000 equal { do\in math { ceil 4.9 } } 5.000000 } - -group "cbrt" + + ; TODO add sin and cos ... need PI constant + + group "cbrt" mold\nowrap "" { { string } } { diff --git a/tests/structures.rye b/tests/structures.rye index 4442cd19..9d16581f 100644 --- a/tests/structures.rye +++ b/tests/structures.rye @@ -658,12 +658,12 @@ section "Spreadsheet related functions" mold\nowrap ?group-by { { block } } { - equal { spreadsheet { "name" "val" } { "a" 1 "b" 2 } |group-by 'name { } |sort-col! 'name + equal { spreadsheet { "name" "val" } { "a" 1 "b" 2 } |group-by 'name { } |sort-by! 'name 'asc } spreadsheet { "name" } { "a" "b" } equal { spreadsheet { "name" "val" } { "a" 1 "b" 6 "a" 5 "b" 10 "a" 7 } |group-by 'name { 'name count 'val sum 'val min 'val max 'val avg } - |sort-col! 'name + |sort-by! 'name 'asc } spreadsheet { "name" "name_count" "val_sum" "val_min" "val_max" "val_avg" } { "a" 3 13.0 1.0 7.0 4.333333333333333 diff --git a/util/microliner.go b/util/microliner.go index 714fc867..fa7877c5 100644 --- a/util/microliner.go +++ b/util/microliner.go @@ -464,6 +464,9 @@ startOfHere: line = line[:pos] s.needRefresh = true } + case "l": + s.eraseScreen() + s.needRefresh = true } } else if next.Alt { switch strings.ToLower(next.Key) { diff --git a/util/ryel b/util/ryel deleted file mode 100755 index b92a4803..00000000 --- a/util/ryel +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -FILE=$PWD/ryel -if [ -f "$FILE" ]; then - echo "Starting local rye interpreter" - $FILE "$@" -else - echo "You don't have local Ryel binary yet. Define ryel.mod if needed and run ryelc build" -fi diff --git a/util/ryel.rye b/util/ryel.rye new file mode 100644 index 00000000..9745a898 --- /dev/null +++ b/util/ryel.rye @@ -0,0 +1,51 @@ +; Rye local binary +; +; *This is experimental way to work with rye interpreter* +; +; This Rye script looks at local rye.mod and tries to build Rye binary with listed bindings + +; for outside of rye source dir +; a=$PWD ; cd ~/go/src/rye ; go build -tags "b_tiny,b_http,b_bleve" -o "$a/ryel" ; cd "$a" + +print-header: does { + print "___ ____, . __" + print "|__) \ / |__ | /\ |\ | / _`" + print "| \ | |___ |___ /~~\ | \| \__>" + print "====================================" + print "Building local Rye interpreter with modules:" +} + +build-ryel: fn { tags } { + + print-header + + open %ryel.mod + |fix\either + { print "Create rye.mod file and list modules." " nil " } + { .read-all } + |load + |map { .to-string .concat* "b_" } + |join\with " " :modules |print + + cp-embed: either tags = "embed_main" { "cp main.rye %RYE_HOME/buildtemp/. ; " } { "" } + + command: join { cp-embed $ a=%PWD ; cd %RYE_HOME ; go build -tags "$ + modules + " " + tags $" -o "%a/ryel" ; cd "%a"$ } ; $ delimiter for string is just temporary ... ' conflicts with lit-words and Rebols { } with blocks so this question is open so far + command .replace "%" "$" :command + ; print "Build command: " + command + cmd command +} + +install-ryel: fn { } { + print-header + print "TODO: Installing Ryel ..." +} + +rye .args -> 0 \fix { "" } :mode +rye .args -> 1 \fix { "" } :tags + +switch mode { + "build" { build-ryel tags } + "install" { install-ryel } +} + +; Later when script is executed and it returns a failure of missing known binding it adds it to the list diff --git a/util/ryelc b/util/ryelc deleted file mode 100755 index f4332f00..00000000 --- a/util/ryelc +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -/home/nano/go/src/rye/rye /home/nano/go/src/rye/ryel.rye $1 diff --git a/util/util.go b/util/util.go index 6304ce21..aebd72fc 100644 --- a/util/util.go +++ b/util/util.go @@ -71,6 +71,7 @@ func StringToFieldsWithQuoted(str string, sepa string, quote string) env.Block { return !quoted && string(r) == sepa }) lst := make([]env.Object, len(spl)) + re := regexp.MustCompile("[0-9]+") for i := 0; i < len(spl); i++ { //fmt.Println(spl[i]) @@ -78,7 +79,6 @@ func StringToFieldsWithQuoted(str string, sepa string, quote string) env.Block { // val, _ := loader.LoadString(spl[i], false) // numeric, _ := regexp.MatchString("[0-9]+", spl[i]) numeric := re.MatchString(spl[i]) - // fmt.Println(numeric) pass := false if numeric { num, err := strconv.Atoi(spl[i]) diff --git a/wasm/ryeshell/index.html b/wasm/ryeshell/index.html index 0bdf9861..fdfca722 100644 --- a/wasm/ryeshell/index.html +++ b/wasm/ryeshell/index.html @@ -261,7 +261,7 @@

{ + if (arg.ctrlKey && arg.code === "KeyV" && arg.type === "keydown") { + navigator.clipboard.readText() + .then(text => { + term.write(text); + }) + }; + return true; + }); // term.open(document.getElementById('terminal-container')) // var term = new Terminal();