lang: Refactor most functions to support modules
This is a giant refactor to move functions into a hierarchial module layout. While this isn't entirely implemented yet, it should work correctly once all the import bits have landed. What's broken at the moment is the template function, which currently doesn't understand the period separator.
This commit is contained in:
@@ -124,16 +124,15 @@ An example explains it best:
|
||||
### Example
|
||||
|
||||
```golang
|
||||
package simplepoly
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simplepoly"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("len", []*types.FuncValue{
|
||||
simplepoly.Register("len", []*types.FuncValue{
|
||||
{
|
||||
T: types.NewType("func([]variant) int"),
|
||||
V: Len,
|
||||
|
||||
@@ -285,11 +285,12 @@ class baz($a str, $b) {
|
||||
Classes can also be nested within other classes. Here's a contrived example:
|
||||
|
||||
```mcl
|
||||
import "fmt"
|
||||
class c1($a, $b) {
|
||||
# nested class definition
|
||||
class c2($c) {
|
||||
test $a {
|
||||
stringptr => printf("%s is %d", $b, $c),
|
||||
stringptr => fmt.printf("%s is %d", $b, $c),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# it was a lovely surprise to me, when i realized that mgmt had the answer!
|
||||
import "fmt"
|
||||
import "example"
|
||||
print "answer" {
|
||||
msg => printf("the answer to life, the universe, and everything is: %d", answer()),
|
||||
msg => fmt.printf("the answer to life, the universe, and everything is: %d", example.answer()),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import "fmt"
|
||||
import "sys"
|
||||
|
||||
$set = ["a", "b", "c", "d",]
|
||||
|
||||
$c1 = "x1" in ["x1", "x2", "x3",]
|
||||
@@ -5,18 +8,18 @@ $c2 = 42 in [4, 13, 42,]
|
||||
$c3 = "x" in $set
|
||||
$c4 = "b" in $set
|
||||
|
||||
$s = printf("1: %t, 2: %t, 3: %t, 4: %t\n", $c1, $c2, $c3, $c4)
|
||||
$s = fmt.printf("1: %t, 2: %t, 3: %t, 4: %t\n", $c1, $c2, $c3, $c4)
|
||||
|
||||
file "/tmp/mgmt/contains" {
|
||||
content => $s,
|
||||
}
|
||||
|
||||
$x = if hostname() in ["h1", "h3",] {
|
||||
printf("i (%s) am one of the chosen few!\n", hostname())
|
||||
$x = if sys.hostname() in ["h1", "h3",] {
|
||||
fmt.printf("i (%s) am one of the chosen few!\n", sys.hostname())
|
||||
} else {
|
||||
printf("i (%s) was not chosen :(\n", hostname())
|
||||
fmt.printf("i (%s) was not chosen :(\n", sys.hostname())
|
||||
}
|
||||
|
||||
file "/tmp/mgmt/hello-${hostname()}" {
|
||||
file "/tmp/mgmt/hello-${sys.hostname()}" {
|
||||
content => $x,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
$d = datetime()
|
||||
import "datetime"
|
||||
|
||||
$d = datetime.now()
|
||||
file "/tmp/mgmt/datetime" {
|
||||
content => template("Hello! It is now: {{ datetime_print . }}\n", $d),
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
$secplusone = datetime() + $ayear
|
||||
import "datetime"
|
||||
import "sys"
|
||||
|
||||
$secplusone = datetime.now() + $ayear
|
||||
|
||||
# note the order of the assignment (year can come later in the code)
|
||||
$ayear = 60 * 60 * 24 * 365 # is a year in seconds (31536000)
|
||||
|
||||
$tmplvalues = struct{year => $secplusone, load => $theload,}
|
||||
|
||||
$theload = structlookup(load(), "x1")
|
||||
$theload = structlookup(sys.load(), "x1")
|
||||
|
||||
if 5 > 3 {
|
||||
file "/tmp/mgmt/datetime" {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
$secplusone = datetime() + $ayear
|
||||
import "datetime"
|
||||
import "sys"
|
||||
|
||||
$secplusone = datetime.now() + $ayear
|
||||
|
||||
# note the order of the assignment (year can come later in the code)
|
||||
$ayear = 60 * 60 * 24 * 365 # is a year in seconds (31536000)
|
||||
|
||||
$tmplvalues = struct{year => $secplusone, load => $theload, vumeter => $vumeter,}
|
||||
|
||||
$theload = structlookup(load(), "x1")
|
||||
$theload = structlookup(sys.load(), "x1")
|
||||
|
||||
$vumeter = vumeter("====", 10, 0.9)
|
||||
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
# read and print environment variable
|
||||
# env TEST=123 EMPTY= ./mgmt run --tmp-prefix --lang=examples/lang/env0.mcl --converged-timeout=5
|
||||
|
||||
$x = getenv("TEST", "321")
|
||||
import "fmt"
|
||||
import "sys"
|
||||
|
||||
$x = sys.getenv("TEST", "321")
|
||||
|
||||
print "print1" {
|
||||
msg => printf("the value of the environment variable TEST is: %s", $x),
|
||||
msg => fmt.printf("the value of the environment variable TEST is: %s", $x),
|
||||
}
|
||||
|
||||
$y = getenv("DOESNOTEXIT", "321")
|
||||
$y = sys.getenv("DOESNOTEXIT", "321")
|
||||
|
||||
print "print2" {
|
||||
msg => printf("environment variable DOESNOTEXIT does not exist, defaulting to: %s", $y),
|
||||
msg => fmt.printf("environment variable DOESNOTEXIT does not exist, defaulting to: %s", $y),
|
||||
}
|
||||
|
||||
$z = getenv("EMPTY", "456")
|
||||
$z = sys.getenv("EMPTY", "456")
|
||||
|
||||
print "print3" {
|
||||
msg => printf("same goes for epmty variables like EMPTY: %s", $z),
|
||||
msg => fmt.printf("same goes for epmty variables like EMPTY: %s", $z),
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
$env = env()
|
||||
import "fmt"
|
||||
import "sys"
|
||||
|
||||
$env = sys.env()
|
||||
$m = maplookup($env, "GOPATH", "")
|
||||
|
||||
print "print0" {
|
||||
msg => if hasenv("GOPATH") {
|
||||
printf("GOPATH is: %s", $m)
|
||||
msg => if sys.hasenv("GOPATH") {
|
||||
fmt.printf("GOPATH is: %s", $m)
|
||||
} else {
|
||||
"GOPATH is missing!"
|
||||
},
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
# time ./mgmt run --lang examples/lang/exchange0.mcl --hostname h3 --seeds http://127.0.0.1:2379 --client-urls http://127.0.0.1:2383 --server-urls http://127.0.0.1:2384 --tmp-prefix --no-pgp
|
||||
# time ./mgmt run --lang examples/lang/exchange0.mcl --hostname h4 --seeds http://127.0.0.1:2379 --client-urls http://127.0.0.1:2385 --server-urls http://127.0.0.1:2386 --tmp-prefix --no-pgp
|
||||
|
||||
import "sys"
|
||||
|
||||
$rand = random1(8)
|
||||
$exchanged = exchange("keyns", $rand)
|
||||
|
||||
file "/tmp/mgmt/exchange-${hostname()}" {
|
||||
file "/tmp/mgmt/exchange-${sys.hostname()}" {
|
||||
content => template("Found: {{ . }}\n", $exchanged),
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
$dt = datetime()
|
||||
import "datetime"
|
||||
|
||||
$dt = datetime.now()
|
||||
|
||||
$hystvalues = {"ix0" => $dt, "ix1" => $dt{1}, "ix2" => $dt{2}, "ix3" => $dt{3},}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
file "/tmp/mgmt/${hostname()}" {
|
||||
content => "hello from ${hostname()}!\n",
|
||||
import "sys"
|
||||
|
||||
file "/tmp/mgmt/${sys.hostname()}" {
|
||||
content => "hello from ${sys.hostname()}!\n",
|
||||
state => "exists",
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import "fmt"
|
||||
|
||||
$x1 = ["a", "b", "c", "d",]
|
||||
print "print4" {
|
||||
msg => printf("length is: %d", len($x1)),
|
||||
msg => fmt.printf("length is: %d", len($x1)),
|
||||
}
|
||||
|
||||
$x2 = {"a" => 1, "b" => 2, "c" => 3,}
|
||||
print "print3" {
|
||||
msg => printf("length is: %d", len($x2)),
|
||||
msg => fmt.printf("length is: %d", len($x2)),
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
$theload = load()
|
||||
import "fmt"
|
||||
import "sys"
|
||||
|
||||
$theload = sys.load()
|
||||
|
||||
$x1 = structlookup($theload, "x1")
|
||||
$x5 = structlookup($theload, "x5")
|
||||
$x15 = structlookup($theload, "x15")
|
||||
|
||||
print "print1" {
|
||||
msg => printf("load average: %f, %f, %f", $x1, $x5, $x15),
|
||||
msg => fmt.printf("load average: %f, %f, %f", $x1, $x5, $x15),
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import "fmt"
|
||||
|
||||
$m = {"k1" => 42, "k2" => 13,}
|
||||
|
||||
$found = maplookup($m, "k1", 99)
|
||||
|
||||
print "print1" {
|
||||
msg => printf("found value of: %d", $found),
|
||||
msg => fmt.printf("found value of: %d", $found),
|
||||
}
|
||||
|
||||
$notfound = maplookup($m, "k3", 99)
|
||||
|
||||
print "print2" {
|
||||
msg => printf("notfound value of: %d", $notfound),
|
||||
msg => fmt.printf("notfound value of: %d", $notfound),
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import "fmt"
|
||||
|
||||
test "t1" {
|
||||
int64 => (4 + 32) * 15 - 8,
|
||||
anotherstr => printf("the answer is: %d", 42),
|
||||
anotherstr => fmt.printf("the answer is: %d", 42),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import "fmt"
|
||||
import "math"
|
||||
|
||||
print "print0" {
|
||||
msg => printf("13.0 ^ 4.2 is: %f", pow(13.0, 4.2)),
|
||||
msg => fmt.printf("13.0 ^ 4.2 is: %f", math.pow(13.0, 4.2)),
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import "fmt"
|
||||
|
||||
test "printf-a" {
|
||||
anotherstr => printf("the %s is: %d", "answer", 42),
|
||||
anotherstr => fmt.printf("the %s is: %d", "answer", 42),
|
||||
}
|
||||
|
||||
$format = "a %s is: %f"
|
||||
test "printf-b" {
|
||||
anotherstr => printf($format, "cool number", 3.14159),
|
||||
anotherstr => fmt.printf($format, "cool number", 3.14159),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import "sys"
|
||||
|
||||
# here are all the possible options:
|
||||
#$opts = struct{strategy => "rr", max => 3, reuse => false, ttl => 10,}
|
||||
|
||||
@@ -13,6 +15,6 @@ $set = schedule("xsched", $opts)
|
||||
# and if you want, you can omit the options entirely:
|
||||
#$set = schedule("xsched")
|
||||
|
||||
file "/tmp/mgmt/scheduled-${hostname()}" {
|
||||
file "/tmp/mgmt/scheduled-${sys.hostname()}" {
|
||||
content => template("set: {{ . }}\n", $set),
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import "fmt"
|
||||
|
||||
$ns = "estate"
|
||||
$exchanged = kvlookup($ns)
|
||||
$state = maplookup($exchanged, $hostname, "default")
|
||||
@@ -16,6 +18,6 @@ Exec["exec0"].output -> Kv["kv0"].value
|
||||
|
||||
if $state != "default" {
|
||||
file "/tmp/mgmt/state" {
|
||||
content => printf("state: %s\n", $state),
|
||||
content => fmt.printf("state: %s\n", $state),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import "fmt"
|
||||
|
||||
$st = struct{f1 => 42, f2 => true, f3 => 3.14,}
|
||||
|
||||
$f1 = structlookup($st, "f1")
|
||||
|
||||
print "print1" {
|
||||
msg => printf("f1 field is: %d", $f1),
|
||||
msg => fmt.printf("f1 field is: %d", $f1),
|
||||
}
|
||||
|
||||
$f2 = structlookup($st, "f2")
|
||||
|
||||
print "print2" {
|
||||
msg => printf("f2 field is: %t", $f2),
|
||||
msg => fmt.printf("f2 field is: %t", $f2),
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import "fmt"
|
||||
import "example"
|
||||
|
||||
$answer = 42
|
||||
$s = int2str($answer)
|
||||
$s = example.int2str($answer)
|
||||
|
||||
print "print1" {
|
||||
msg => printf("an str is: %s", $s),
|
||||
msg => fmt.printf("an str is: %s", $s),
|
||||
}
|
||||
|
||||
print "print2" {
|
||||
|
||||
27
lang/funcs/core/core.go
Normal file
27
lang/funcs/core/core.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2018+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
// import so the funcs register
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core/coredatetime"
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core/coreexample"
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core/corefmt"
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core/coremath"
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core/coresys"
|
||||
)
|
||||
23
lang/funcs/core/coredatetime/coredatetime.go
Normal file
23
lang/funcs/core/coredatetime/coredatetime.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2018+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package coredatetime
|
||||
|
||||
const (
|
||||
// moduleName is the prefix given to all the functions in this module.
|
||||
moduleName = "datetime"
|
||||
)
|
||||
@@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package coredatetime
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
facts.Register("datetime", func() facts.Fact { return &DateTimeFact{} }) // must register the fact and name
|
||||
facts.ModuleRegister(moduleName, "now", func() facts.Fact { return &DateTimeFact{} }) // must register the fact and name
|
||||
}
|
||||
|
||||
// DateTimeFact is a fact which returns the current date and time.
|
||||
@@ -15,19 +15,19 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package simple // TODO: should this be in its own individual package?
|
||||
package coredatetime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simple"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO: should we support namespacing these, eg: datetime.print ?
|
||||
// FIXME: consider renaming this to printf, and add in a format string?
|
||||
Register("datetime_print", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "print", &types.FuncValue{
|
||||
T: types.NewType("func(a int) str"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
epochDelta := input[0].Int()
|
||||
@@ -15,9 +15,10 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package simple // TODO: should this be in its own individual package?
|
||||
package coreexample
|
||||
|
||||
import (
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simple"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
)
|
||||
|
||||
@@ -25,7 +26,7 @@ import (
|
||||
const Answer = 42
|
||||
|
||||
func init() {
|
||||
Register("answer", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "answer", &types.FuncValue{
|
||||
T: types.NewType("func() int"),
|
||||
V: func([]types.Value) (types.Value, error) {
|
||||
return &types.IntValue{V: Answer}, nil
|
||||
23
lang/funcs/core/coreexample/coreexample.go
Normal file
23
lang/funcs/core/coreexample/coreexample.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2018+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package coreexample
|
||||
|
||||
const (
|
||||
// moduleName is the prefix given to all the functions in this module.
|
||||
moduleName = "example"
|
||||
)
|
||||
@@ -15,17 +15,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package simple // TODO: should this be in its own individual package?
|
||||
package coreexample
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simple"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO: should we support namespacing these, eg: example.errorbool ?
|
||||
Register("example_errorbool", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "errorbool", &types.FuncValue{
|
||||
T: types.NewType("func(a bool) str"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
if input[0].Bool() {
|
||||
@@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package coreexample
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -25,8 +25,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO: rename these `play` facts to start with a test_ prefix or similar
|
||||
facts.Register("flipflop", func() facts.Fact { return &FlipFlopFact{} }) // must register the fact and name
|
||||
facts.ModuleRegister(moduleName, "flipflop", func() facts.Fact { return &FlipFlopFact{} }) // must register the fact and name
|
||||
}
|
||||
|
||||
// FlipFlopFact is a fact which flips a bool repeatedly. This is an example fact
|
||||
@@ -15,16 +15,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package simple // TODO: should this be in its own individual package?
|
||||
package coreexample
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simple"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("int2str", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "int2str", &types.FuncValue{
|
||||
T: types.NewType("func(a int) str"),
|
||||
V: func(input []types.Value) (types.Value, error) {
|
||||
return &types.StrValue{
|
||||
@@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package coreexample
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -34,7 +34,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
funcs.Register("vumeter", func() interfaces.Func { return &VUMeterFunc{} }) // must register the func and name
|
||||
funcs.ModuleRegister(moduleName, "vumeter", func() interfaces.Func { return &VUMeterFunc{} }) // must register the func and name
|
||||
}
|
||||
|
||||
// VUMeterFunc is a gimmic function to display a vu meter from the microphone.
|
||||
23
lang/funcs/core/corefmt/corefmt.go
Normal file
23
lang/funcs/core/corefmt/corefmt.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2018+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package corefmt
|
||||
|
||||
const (
|
||||
// moduleName is the prefix given to all the functions in this module.
|
||||
moduleName = "fmt"
|
||||
)
|
||||
@@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package corefmt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
funcs.Register("printf", func() interfaces.Func { return &PrintfFunc{} })
|
||||
funcs.ModuleRegister(moduleName, "printf", func() interfaces.Func { return &PrintfFunc{} })
|
||||
}
|
||||
|
||||
const (
|
||||
23
lang/funcs/core/coremath/coremath.go
Normal file
23
lang/funcs/core/coremath/coremath.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2018+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package coremath
|
||||
|
||||
const (
|
||||
// moduleName is the prefix given to all the functions in this module.
|
||||
moduleName = "math"
|
||||
)
|
||||
@@ -15,17 +15,18 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package simple // TODO: should this be in its own individual package?
|
||||
package coremath
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simple"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("pow", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "pow", &types.FuncValue{
|
||||
T: types.NewType("func(x float, y float) float"),
|
||||
V: Pow,
|
||||
})
|
||||
23
lang/funcs/core/coresys/coresys.go
Normal file
23
lang/funcs/core/coresys/coresys.go
Normal file
@@ -0,0 +1,23 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2018+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package coresys
|
||||
|
||||
const (
|
||||
// moduleName is the prefix given to all the functions in this module.
|
||||
moduleName = "sys"
|
||||
)
|
||||
@@ -15,29 +15,30 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package simple // TODO: should this be in its own individual package?
|
||||
package coresys
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simple"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("getenv", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "getenv", &types.FuncValue{
|
||||
T: types.NewType("func(str) str"),
|
||||
V: GetEnv,
|
||||
})
|
||||
Register("defaultenv", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "defaultenv", &types.FuncValue{
|
||||
T: types.NewType("func(str, str) str"),
|
||||
V: DefaultEnv,
|
||||
})
|
||||
Register("hasenv", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "hasenv", &types.FuncValue{
|
||||
T: types.NewType("func(str) bool"),
|
||||
V: HasEnv,
|
||||
})
|
||||
Register("env", &types.FuncValue{
|
||||
simple.ModuleRegister(moduleName, "env", &types.FuncValue{
|
||||
T: types.NewType("func() map{str: str}"),
|
||||
V: Env,
|
||||
})
|
||||
@@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package coresys
|
||||
|
||||
import (
|
||||
"github.com/purpleidea/mgmt/lang/funcs/facts"
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
facts.Register("hostname", func() facts.Fact { return &HostnameFact{} }) // must register the fact and name
|
||||
facts.ModuleRegister(moduleName, "hostname", func() facts.Fact { return &HostnameFact{} }) // must register the fact and name
|
||||
}
|
||||
|
||||
// HostnameFact is a function that returns the hostname.
|
||||
@@ -15,7 +15,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package coresys
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -31,7 +31,7 @@ const (
|
||||
)
|
||||
|
||||
func init() {
|
||||
facts.Register("load", func() facts.Fact { return &LoadFact{} }) // must register the fact and name
|
||||
facts.ModuleRegister(moduleName, "load", func() facts.Fact { return &LoadFact{} }) // must register the fact and name
|
||||
}
|
||||
|
||||
// LoadFact is a fact which returns the current system load.
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
// +build darwin
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package coresys
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
// +build !darwin
|
||||
|
||||
package core // TODO: should this be in its own individual package?
|
||||
package coresys
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
@@ -15,16 +15,17 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package simplepoly // TODO: should this be in its own individual package?
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/funcs/simplepoly"
|
||||
"github.com/purpleidea/mgmt/lang/types"
|
||||
)
|
||||
|
||||
func init() {
|
||||
Register("len", []*types.FuncValue{
|
||||
simplepoly.Register("len", []*types.FuncValue{
|
||||
{
|
||||
T: types.NewType("func([]variant) int"),
|
||||
V: Len,
|
||||
@@ -188,6 +188,8 @@ func (obj *TemplateFunc) run(templateText string, vars types.Value) (string, err
|
||||
// FIXME: should we do this once in init() instead, or in the Register
|
||||
// function in the simple package?
|
||||
// TODO: loop through this map in a sorted, deterministic order
|
||||
// XXX: should this use the scope instead (so imports are used properly) ?
|
||||
// XXX: dots are not valid here, so maybe replace dots with underscores so we can do fmt_print???
|
||||
for name, fn := range simple.RegisteredFuncs {
|
||||
if _, exists := funcMap[name]; exists {
|
||||
obj.init.Logf("warning, existing function named: `%s` exists", name)
|
||||
@@ -47,6 +47,12 @@ func Register(name string, fn func() Fact) {
|
||||
RegisteredFacts[name] = fn
|
||||
}
|
||||
|
||||
// ModuleRegister is exactly like Register, except that it registers within a
|
||||
// named module. This is a helper function.
|
||||
func ModuleRegister(module, name string, fn func() Fact) {
|
||||
Register(module+funcs.ModuleSep+name, fn)
|
||||
}
|
||||
|
||||
// Info is a static representation of some information about the fact. It is
|
||||
// used for static analysis and type checking. If you break this contract, you
|
||||
// might cause a panic.
|
||||
|
||||
@@ -20,10 +20,18 @@ package funcs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/purpleidea/mgmt/lang/interfaces"
|
||||
)
|
||||
|
||||
const (
|
||||
// ModuleSep is the character used for the module scope separation. For
|
||||
// example when using `fmt.printf` or `math.sin` this is the char used.
|
||||
// It is included here for convenience when importing this package.
|
||||
ModuleSep = interfaces.ModuleSep
|
||||
)
|
||||
|
||||
// registeredFuncs is a global map of all possible funcs which can be used. You
|
||||
// should never touch this map directly. Use methods like Register instead. It
|
||||
// includes implementations which also satisfy PolyFunc as well.
|
||||
@@ -32,15 +40,33 @@ var registeredFuncs = make(map[string]func() interfaces.Func) // must initialize
|
||||
// Register takes a func and its name and makes it available for use. It is
|
||||
// commonly called in the init() method of the func at program startup. There is
|
||||
// no matching Unregister function. You may also register functions which
|
||||
// satisfy the PolyFunc interface.
|
||||
// satisfy the PolyFunc interface. To register a function which lives in a
|
||||
// module, you must join the module name to the function name with the ModuleSep
|
||||
// character. It is defined as a const and is probably the period character.
|
||||
func Register(name string, fn func() interfaces.Func) {
|
||||
if _, exists := registeredFuncs[name]; exists {
|
||||
panic(fmt.Sprintf("a func named %s is already registered", name))
|
||||
}
|
||||
|
||||
// can't contain more than one period in a row
|
||||
if strings.Index(name, ModuleSep+ModuleSep) >= 0 {
|
||||
panic(fmt.Sprintf("a func named %s is invalid", name))
|
||||
}
|
||||
// can't start or end with a period
|
||||
if strings.HasPrefix(name, ModuleSep) || strings.HasSuffix(name, ModuleSep) {
|
||||
panic(fmt.Sprintf("a func named %s is invalid", name))
|
||||
}
|
||||
|
||||
//gob.Register(fn())
|
||||
registeredFuncs[name] = fn
|
||||
}
|
||||
|
||||
// ModuleRegister is exactly like Register, except that it registers within a
|
||||
// named module.
|
||||
func ModuleRegister(module, name string, fn func() interfaces.Func) {
|
||||
Register(module+ModuleSep+name, fn)
|
||||
}
|
||||
|
||||
// Lookup returns a pointer to the function's struct. It may be convertible to a
|
||||
// PolyFunc if the particular function implements those additional methods.
|
||||
func Lookup(name string) (interfaces.Func, error) {
|
||||
@@ -50,3 +76,21 @@ func Lookup(name string) (interfaces.Func, error) {
|
||||
}
|
||||
return f(), nil
|
||||
}
|
||||
|
||||
// LookupPrefix returns a map of names to functions that start with a module
|
||||
// prefix. This search automatically adds the period separator. So if you want
|
||||
// functions in the `fmt` package, search for `fmt`, not `fmt.` and it will find
|
||||
// all the correctly registered functions. This removes that prefix from the
|
||||
// result in the map keys that it returns.
|
||||
func LookupPrefix(prefix string) (map[string]interfaces.Func, error) {
|
||||
result := make(map[string]interfaces.Func)
|
||||
for name, f := range registeredFuncs {
|
||||
sep := prefix + ModuleSep
|
||||
if !strings.HasPrefix(name, sep) {
|
||||
continue
|
||||
}
|
||||
s := strings.TrimPrefix(name, sep) // TODO: is it okay to remove the prefix?
|
||||
result[s] = f() // build
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -42,6 +42,12 @@ func Register(name string, fn *types.FuncValue) {
|
||||
funcs.Register(name, func() interfaces.Func { return &simpleFunc{Fn: fn} })
|
||||
}
|
||||
|
||||
// ModuleRegister is exactly like Register, except that it registers within a
|
||||
// named module. This is a helper function.
|
||||
func ModuleRegister(module, name string, fn *types.FuncValue) {
|
||||
Register(module+funcs.ModuleSep+name, fn)
|
||||
}
|
||||
|
||||
// simpleFunc is a scaffolding function struct which fulfills the boiler-plate
|
||||
// for the function API, but that can run a very simple, static, pure function.
|
||||
type simpleFunc struct {
|
||||
|
||||
@@ -62,6 +62,12 @@ func Register(name string, fns []*types.FuncValue) {
|
||||
funcs.Register(name, func() interfaces.Func { return &simplePolyFunc{Fns: fns} })
|
||||
}
|
||||
|
||||
// ModuleRegister is exactly like Register, except that it registers within a
|
||||
// named module. This is a helper function.
|
||||
func ModuleRegister(module, name string, fns []*types.FuncValue) {
|
||||
Register(module+funcs.ModuleSep+name, fns)
|
||||
}
|
||||
|
||||
// simplePolyFunc is a scaffolding function struct which fulfills the
|
||||
// boiler-plate for the function API, but that can run a very simple, static,
|
||||
// pure, polymorphic function.
|
||||
|
||||
24
lang/interfaces/const.go
Normal file
24
lang/interfaces/const.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Mgmt
|
||||
// Copyright (C) 2013-2018+ James Shubin and the project contributors
|
||||
// Written by James Shubin <james@shubin.ca> and the project contributors
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
package interfaces
|
||||
|
||||
const (
|
||||
// ModuleSep is the character used for the module scope separation. For
|
||||
// example when using `fmt.printf` or `math.sin` this is the char used.
|
||||
ModuleSep = "."
|
||||
)
|
||||
@@ -24,10 +24,7 @@ import (
|
||||
|
||||
"github.com/purpleidea/mgmt/engine"
|
||||
"github.com/purpleidea/mgmt/lang/funcs"
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core" // import so the funcs register
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/facts/core" // import so the facts register
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/simple" // import so the funcs register
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/simplepoly" // import so the funcs register
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core" // import so the funcs register
|
||||
"github.com/purpleidea/mgmt/lang/interfaces"
|
||||
"github.com/purpleidea/mgmt/lang/unification"
|
||||
"github.com/purpleidea/mgmt/pgraph"
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
"github.com/purpleidea/mgmt/engine"
|
||||
"github.com/purpleidea/mgmt/engine/resources"
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/facts/core" // load facts
|
||||
_ "github.com/purpleidea/mgmt/lang/funcs/core" // import so the funcs register
|
||||
"github.com/purpleidea/mgmt/pgraph"
|
||||
"github.com/purpleidea/mgmt/util"
|
||||
|
||||
@@ -497,9 +497,10 @@ func TestInterpretMany(t *testing.T) {
|
||||
// values = append(values, test{
|
||||
// name: "double include different printf types allowed",
|
||||
// code: `
|
||||
// import "fmt"
|
||||
// class c1($a, $b) {
|
||||
// test $a {
|
||||
// stringptr => printf("value is: %v", $b),
|
||||
// stringptr => fmt.printf("value is: %v", $b),
|
||||
// }
|
||||
// }
|
||||
// include c1("t1", "hello")
|
||||
@@ -667,6 +668,8 @@ func TestInterpretMany(t *testing.T) {
|
||||
values = append(values, test{
|
||||
name: "nested classes 1",
|
||||
code: `
|
||||
import "fmt"
|
||||
|
||||
include c1("t1", "hello") # test["t1"] -> hello is 42
|
||||
include c1("t2", "world") # test["t2"] -> world is 13
|
||||
|
||||
@@ -674,7 +677,7 @@ func TestInterpretMany(t *testing.T) {
|
||||
# nested class definition
|
||||
class c2($c) {
|
||||
test $a {
|
||||
stringptr => printf("%s is %d", $b, $c),
|
||||
stringptr => fmt.printf("%s is %d", $b, $c),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,6 +696,8 @@ func TestInterpretMany(t *testing.T) {
|
||||
values = append(values, test{
|
||||
name: "nested classes out of scope 1",
|
||||
code: `
|
||||
import "fmt"
|
||||
|
||||
include c1("t1", "hello") # test["t1"] -> hello is 42
|
||||
include c2(99) # out of scope
|
||||
|
||||
@@ -700,7 +705,7 @@ func TestInterpretMany(t *testing.T) {
|
||||
# nested class definition
|
||||
class c2($c) {
|
||||
test $a {
|
||||
stringptr => printf("%s is %d", $b, $c),
|
||||
stringptr => fmt.printf("%s is %d", $b, $c),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -742,13 +747,14 @@ func TestInterpretMany(t *testing.T) {
|
||||
// values = append(values, test{
|
||||
// name: "recursive classes 1",
|
||||
// code: `
|
||||
// import "fmt"
|
||||
// $max = 3
|
||||
// include c1(0) # start at zero
|
||||
// # test["done"] -> count is 3
|
||||
// class c1($count) {
|
||||
// if $count == $max {
|
||||
// test "done" {
|
||||
// stringptr => printf("count is %d", $count),
|
||||
// stringptr => fmt.printf("count is %d", $count),
|
||||
// }
|
||||
// } else {
|
||||
// include c1($count + 1)
|
||||
@@ -779,6 +785,7 @@ func TestInterpretMany(t *testing.T) {
|
||||
// values = append(values, test{
|
||||
// name: "recursive classes 2",
|
||||
// code: `
|
||||
// import "fmt"
|
||||
// include c1("ix", 3)
|
||||
// # test["ix:3"] -> count is 3
|
||||
// # test["ix:2"] -> count is 2
|
||||
@@ -787,12 +794,12 @@ func TestInterpretMany(t *testing.T) {
|
||||
// class c1($name, $count) {
|
||||
// if $count == 0 {
|
||||
// test "zero" {
|
||||
// stringptr => printf("count is %d", $count),
|
||||
// stringptr => fmt.printf("count is %d", $count),
|
||||
// }
|
||||
// } else {
|
||||
// include c1($name, $count - 1)
|
||||
// test "${name}:${count}" {
|
||||
// stringptr => printf("count is %d", $count),
|
||||
// stringptr => fmt.printf("count is %d", $count),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
@@ -806,12 +813,13 @@ func TestInterpretMany(t *testing.T) {
|
||||
values = append(values, test{
|
||||
name: "recursive classes fail 1",
|
||||
code: `
|
||||
import "fmt"
|
||||
$max = 3
|
||||
include c1(0) # start at zero
|
||||
class c1($count) {
|
||||
if $count == $max {
|
||||
test "done" {
|
||||
stringptr => printf("count is %d", $count),
|
||||
stringptr => fmt.printf("count is %d", $count),
|
||||
}
|
||||
} else {
|
||||
include c1($count + 1) # recursion not supported atm
|
||||
@@ -826,12 +834,13 @@ func TestInterpretMany(t *testing.T) {
|
||||
values = append(values, test{
|
||||
name: "recursive classes fail 2",
|
||||
code: `
|
||||
import "fmt"
|
||||
$max = 5
|
||||
include c1(0) # start at zero
|
||||
class c1($count) {
|
||||
if $count == $max {
|
||||
test "done" {
|
||||
stringptr => printf("count is %d", $count),
|
||||
stringptr => fmt.printf("count is %d", $count),
|
||||
}
|
||||
} else {
|
||||
include c2($count + 1) # recursion not supported atm
|
||||
@@ -840,7 +849,7 @@ func TestInterpretMany(t *testing.T) {
|
||||
class c2($count) {
|
||||
if $count == $max {
|
||||
test "done" {
|
||||
stringptr => printf("count is %d", $count),
|
||||
stringptr => fmt.printf("count is %d", $count),
|
||||
}
|
||||
} else {
|
||||
include c1($count + 1) # recursion not supported atm
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
$tmpdir = defaultenv("TMPDIR", "/tmp")
|
||||
import "fmt"
|
||||
import "sys"
|
||||
|
||||
$x = getenv("TEST")
|
||||
$y = getenv("DOESNOTEXIST")
|
||||
$z = getenv("EMPTY")
|
||||
$tmpdir = sys.defaultenv("TMPDIR", "/tmp")
|
||||
|
||||
$a = defaultenv("TEST", "321")
|
||||
$b = defaultenv("DOESNOTEXIST", "321")
|
||||
$c = defaultenv("EMPTY", "456")
|
||||
$x = sys.getenv("TEST")
|
||||
$y = sys.getenv("DOESNOTEXIST")
|
||||
$z = sys.getenv("EMPTY")
|
||||
|
||||
$t = hasenv("TEST")
|
||||
$f = hasenv("DOESNOTEXIST")
|
||||
$a = sys.defaultenv("TEST", "321")
|
||||
$b = sys.defaultenv("DOESNOTEXIST", "321")
|
||||
$c = sys.defaultenv("EMPTY", "456")
|
||||
|
||||
$env = env()
|
||||
$t = sys.hasenv("TEST")
|
||||
$f = sys.hasenv("DOESNOTEXIST")
|
||||
|
||||
$env = sys.env()
|
||||
$m = maplookup($env, "TEST", "321")
|
||||
|
||||
file "${tmpdir}/environ" {
|
||||
content => printf("%s,%s,%s:%s,%s,%s:%t,%t:%s", $x, $y, $z, $a, $b, $c, $t, $f, $m),
|
||||
content => fmt.printf("%s,%s,%s:%s,%s,%s:%t,%t:%s", $x, $y, $z, $a, $b, $c, $t, $f, $m),
|
||||
}
|
||||
|
||||
@@ -25,14 +25,17 @@ if [[ ! "$tmpdir" =~ "/tmp" ]]; then
|
||||
fi
|
||||
|
||||
cat > "$tmpdir/load0.mcl" <<EOF
|
||||
\$theload = load()
|
||||
import "fmt"
|
||||
import "sys"
|
||||
|
||||
\$theload = sys.load()
|
||||
|
||||
\$x1 = structlookup(\$theload, "x1")
|
||||
\$x5 = structlookup(\$theload, "x5")
|
||||
\$x15 = structlookup(\$theload, "x15")
|
||||
|
||||
file "${tmpdir}/loadavg" {
|
||||
content => printf("load average: %f, %f, %f", \$x1, \$x5, \$x15),
|
||||
content => fmt.printf("load average: %f, %f, %f", \$x1, \$x5, \$x15),
|
||||
state => "exists",
|
||||
}
|
||||
EOF
|
||||
|
||||
Reference in New Issue
Block a user