ä¸Â次 Tengo å¨æÂÂé Âç½®åºÂç¨åÂÂä½ÂéªÂ
âÂÂ
å¯以éÂÂæ¾ï¼Âä½Âä¸Âè¦ÂÃ¥ÂÂæÂÂãÂÂÃÂ
æÂÂ们çÂÂå¨è¿ÂéÂÂï¼Âä»ÂæÂ¥ä¸Âæ¯身ä¸Âç±己ãÂÂÃÂ
âÂÂâÂÂâ èÂÂæ¯éÂÂæ©å¨è¿ÂéÂÂç»ÂÃ¥ÂÂçÂÂæ´»
âÂÂ
ä¸Âå¡èÂÂæ¯
å¨ä¸Âå¡ä¸ÂæÂÂæ©å±ÂçÂÂèÂÂæ¯ä¸Âï¼ÂâÂÂæ°æ®â å âÂÂ计ç®Ââ çÂÂ解è¦éÂÂæ±ÂéÂÂæ¸Âå¸æ¾ãÂÂ计ç®Âè§ÂÃ¥ÂÂçÂÂçµ活æ§åÂÂÃ¥ÂÂï¼Âå æ¤å°Âå ¶ç´æÂ¥åµÂ堥主åºÂç¨ç¨ÂåºÂÃ¥ÂÂå¾Âä¸Â太éÂÂå®Âï¼Âå æ¤æÂÂ们éÂÂè¦Âä¸Â款强大çÂÂè§ÂÃ¥ÂÂå¼ÂæÂÂæÂÂå¨æÂÂé Â置平å°ãÂÂ
å¹³å°çÂÂ设计èÂÂèÂÂå°两个主è¦Âç¨æ·群ä½Âï¼ÂæÂÂæ¯人åÂÂÃ¥ÂÂéÂÂæÂÂæ¯人åÂÂãÂÂ
对äºÂéÂÂæÂÂæ¯ç¨æ·ï¼ÂæÂÂ们æÂÂä¾ÂäºÂç®ÂÃ¥ÂÂæÂÂç¨çÂÂçÂÂé¢åÂÂ交äºÂæ¹å¼Âï¼Â以éÂÂä½Âä»Â们çÂÂå¦习æÂÂæÂŒÂÂ使ç¨é¨æ§ÂãÂÂè¿Âå¯è½å æŒ¯è§ÂÃ¥ÂÂ工堷ãÂÂæÂÂæ¾å¼ÂçÂÂé¢åÂÂé¢Âå®Âä¹Â模æ¿çÂÂï¼Âæ¨å¨ç®ÂÃ¥ÂÂé Âç½®åÂÂè§ÂÃ¥ÂÂå®Âä¹Âè¿Âç¨ÂãÂÂ
Ã¥ÂÂæ¶ï¼Â对äºÂæÂÂæ¯ç¨æ·ï¼ÂæÂÂ们æÂÂä¾ÂäºÂä¸Âç§Âçµ活ä¸Âå¯æ©å±ÂçÂÂæ¹å¼ÂæÂ¥èªå®Âä¹ÂÃ¥ÂÂé Âç½®è§ÂÃ¥ÂÂï¼Â以满足ä»Â们çÂÂéÂÂæ±ÂãÂÂè¿ÂäºÂç¨æ·å¯è½æ´åÂÂ欢ç¼ÂÃ¥ÂÂèÂÂæ¬以å®Âç°å¤ÂæÂÂçÂÂä¸Âå¡é»è¾Âï¼Â以è·å¾Âæ´é«ÂçÂÂçµ活æ§åÂÂèªå®Âä¹Âè½åÂÂãÂÂ
æ 论ç¨æ·å±ÂäºÂåªä¸Âç±»ï¼ÂåºÂå±Âé½å¯以使ç¨ä¸Âå¥ÂéÂÂç¨äºÂé¢Âç¹ÂÃ¥ÂÂæ´åÂÂå¨æÂÂéÂ
Âç½®çÂÂèÂÂæ¬å¼ÂæÂÂãÂÂæÂÂ们éÂÂæ©亠Tengo
æÂ¥å®ÂæÂÂè¿Â项任å¡ï¼Âå®ÂéÂÂç¨äºÂæÂÂ建èªå®Âä¹ÂèÂÂæ¬å¼ÂæÂÂãÂÂæ©å±ÂåºÂç¨ç¨ÂåºÂÃ¥ÂÂè½åÂÂå®Âç°æÂÂ件系ç»ÂçÂÂå¤Âç§Âåºæ¯ãÂÂTengo
为æÂÂ们æÂÂä¾ÂäºÂ稳å®Âæ§åÂÂçµ活æ§ï¼Âå©åÂÂæÂÂ们æÂÂæÂÂåºÂ对ä¸ÂæÂÂÃ¥ÂÂÃ¥ÂÂçÂÂä¸Âå¡éÂÂæ±ÂãÂÂ
Tengo ä»Âç»Â
Tengo è¯Âè¨Âå ·æÂÂ类似亠Go è¯Âè¨ÂçÂÂè¯Âæ³ÂÃ¥ÂÂç¹æ§ï¼Â并ä¸Â被设计ç¨äºÂåµÂå ¥å°堶ä»ÂåºÂç¨ç¨ÂåºÂä¸Âï¼Â以æÂÂä¾ÂèÂÂæÂŒÂÂÃ¥ÂÂæ©å±Âè½åÂÂãÂÂ
Tengo æ¯ä»Âä¹Â
Tengo
æ¯ä¸Âé¨年轻èÂÂ强大çÂÂå¨æÂÂæ 类åÂÂèÂÂæ¬è¯Âè¨ÂãÂÂTengo
çÂÂåºÂå±Âä¾ÂèµÂäºÂGolang
ï¼Â堼堷ç®Âæ´ÂæÂÂæÂÂçÂÂè¯Âæ³ÂÃ¥ÂÂÃ¥ÂÂè¶ÂçÂÂæ§è½表ç°ãÂÂTengo
å ·å¤Âæ¯æÂÂå¤Âé¨åÂÂéÂÂÃ¥ÂÂå½æ°çÂÂç¹æ§ï¼Âè½å¤Âæ¹便å°导堥å¤Âé¨èµÂæºÂï¼ÂÃ¥ÂÂæ¶æ¯æÂÂå±Âé¨åÂÂéÂÂçÂÂå®Âä¹ÂÃ¥ÂÂæ§å¶è¯Âå¥çÂÂ使ç¨ãÂÂTengo
éÂÂ常éÂÂç¨äºÂä½Â为èÂÂæ¬å¼ÂæÂÂï¼Âå¨èÂÂæÂÂæºçÂÂå®Âç°æ¹å¼Âä¸Âï¼Âå®Âå¯以åºÂç¨äºÂå¤Â个åºÂç¨é¢ÂÃ¥ÂÂãÂÂ
Playground ä½ÂéªÂ
å¯以å¨ Playground
ä¸Âä½Â骠Tengo
ï¼Âtengolang.com/
Tengo åºÂç¨åºæ¯
å¨æÂÂé Âç½®åÂÂè§ÂÃ¥ÂÂå¼ÂæÂÂ
Tengo æ¯ä¸Â款强大çÂÂå¨æÂÂèÂÂæ¬è¯Âè¨Âï¼Âä¸Âä» è¯Âæ³Âç®ÂÃ¥ÂÂæÂÂç¨ï¼ÂèÂÂä¸Âåº亠Golang å®Âç°ï¼Âæ§è½åºè²ãÂÂå®Âå¯以åÂÂæ¶ä½Â为å¨æÂÂé Â置管çÂÂÃ¥ÂÂè§ÂÃ¥ÂÂå¼ÂæÂÂçÂÂçÂÂæ³æÂÂæ¡£ï¼Â为ä¸Âå¡è§ÂÃ¥ÂÂçÂÂå®Âä¹ÂãÂÂæ§è¡ÂÃ¥ÂÂ管çÂÂæÂÂä¾ÂäºÂçµ活æ§åÂÂ强大çÂÂ工堷ãÂÂ
使ç¨ Tengo
è¿Âè¡Âå¨æÂÂéÂ
Â置管çÂÂÃ¥ÂÂè§ÂÃ¥ÂÂå¼ÂæÂÂçÂÂä¼Âå¿å¦Âä¸Âï¼Â
- å¨æÂÂæ§ï¼Â
Tengo
å Â许你å¨è¿Âè¡Âæ¶å¨æÂÂä¿®æ¹é Âç½®åÂÂè§ÂÃ¥ÂÂï¼Âæ éÂÂéÂÂæ°å¯å¨åºÂç¨ç¨ÂåºÂãÂÂè¿ÂéÂÂç¨äºÂéÂÂè¦Âé¢Âç¹Âè°Âæ´åÂÂæµÂè¯ÂçÂÂåºæ¯ï¼Â使å¾Âå®Âæ¶é Âç½®åÂÂè§ÂÃ¥ÂÂè°Âæ´æÂÂ为å¯è½ã - çµ活æ§ï¼Â
Tengo
æÂÂä¾ÂäºÂä¸Âç§ÂèÂÂæÂŒÂÂçÂÂæ¹å¼Âæ¥修æ¹é Âç½®åÂÂå®Âä¹Âè§ÂÃ¥ÂÂãÂÂéÂÂè¿Âç¼ÂÃ¥ÂÂTengo
èÂÂæ¬ï¼Âä½ å¯以å©ç¨æ¡件é»è¾ÂãÂÂ循ç¯åÂÂèªå®Âä¹Âå½æ°æÂ¥å¤ÂçÂÂé Âç½®åÂÂè§ÂÃ¥ÂÂï¼Â使å¾Âé Âç½®åÂÂè§ÂÃ¥ÂÂçÂÂå®Âä¹Âè¿Âç¨Âæ´å çµ活åÂÂå¯æ§ã - å®ÂÃ¥Â
¨æ§ï¼Â
Tengo
æÂÂä¾ÂäºÂÃ¥ÂÂæ§çÂÂèÂÂ澧è¡Âç¯å¢Âï¼Âå¯以éÂÂå¶èÂÂæÂÂÃ¥ÂÂè½åÂÂ访é®æÂÂéÂÂï¼Âç¡®ä¿Âé Âç½®åÂÂè§ÂÃ¥ÂÂçÂÂå®Âå ¨æ§ãÂÂç¸æ¯Âç´æÂ¥æÂÂä½ÂæÂÂä½Âç³»ç»Âç¯å¢ÂÃ¥ÂÂéÂÂï¼Â使ç¨Tengo
æÂÂä¾Âæ´å¤ÂçÂÂå®Âå ¨ä¿ÂéÂÂã - å¯æ©å±Âæ§ï¼Â
Tengo
æ¯ä¸Â个å¯æ©å±ÂçÂÂèÂÂæ¬è¯Âè¨Âï¼Âå¯以ä¸ÂåºÂç¨ç¨ÂåºÂé»è¾ÂéÂÂæÂÂãÂÂä½ å¯以å¨Tengo
èÂÂæ¬ä¸Âå®Âä¹Âèªå®Âä¹Âå½æ°åÂÂæ°æ®ç»ÂæÂÂï¼Âæ´好å°å¤ÂçÂÂÃ¥ÂÂ管çÂÂé Âç½®åÂÂè§ÂÃ¥ÂÂï¼Âæ ¹æ®åºÂç¨éÂÂæ±Âè¿Âè¡Âå®Âå¶åÂÂæ©å±ÂãÂÂ
æÂȏÂÂè¨Âä¹Âï¼Â使ç¨ Tengo
å®Âç°å¨æÂÂéÂ
Â置管çÂÂÃ¥ÂÂè§ÂÃ¥ÂÂå¼ÂæÂÂæÂÂä¾ÂäºÂæ´å¤ÂçÂÂçµ活æ§ãÂÂæ§å¶åÂÂæ©å±Âæ§ãÂÂæ 论æ¯éÂ
Âç½®çÂÂå®Âæ¶è°Âæ´ï¼Âè¿Âæ¯å¤ÂæÂÂè§ÂÃ¥ÂÂçÂÂå®Âä¹ÂÃ¥ÂÂæ§è¡Âï¼ÂTengo
é½为è¿ÂäºÂéÂÂæ±ÂæÂÂä¾ÂäºÂé«ÂæÂÂÃ¥ÂÂçµ活çÂÂ解å³æ¹æ¡ÂãÂÂÃ¥ÂÂæ¶ï¼ÂTengo
çÂÂæ§è½åÂÂæÂÂç¨æ§ä¹Â使å¾Âå®Âå¨å®ÂéÂÂ
项ç®ä¸ÂåºÂç¨广æ³Âï¼ÂéÂÂç¨äºÂå¤Âç§Âå¤ÂæÂÂÃ¥ÂÂçµ活çÂÂéÂ
Âç½®åÂÂè§ÂÃ¥ÂÂ管çÂÂéÂÂæ±ÂãÂÂ
å·¥ä½ÂæµÂå¼ÂæÂÂ
æÂÂ们çÂÂå·¥ä½ÂæµÂå¼ÂæÂÂ设计ä¸ÂèÂÂÃ¥ÂÂäºÂÃ¥ÂÂ端çÂÂå¯è§ÂÃ¥ÂÂéÂ
Âç½®å Tengo
èÂÂæ¬å¼ÂæÂÂï¼Â以满足ä¸ÂÃ¥ÂÂç¨æ·çÂÂéÂÂæ±ÂãÂÂè¿Â个设计带æÂ¥çÂÂ好å¤Âå¦Âä¸Âï¼Â
- ç®ÂÃ¥ÂÂéÂ
Âç½®ï¼Â对äºÂéÂÂæÂÂæ¯ç¨æ·ï¼ÂæÂÂ们æÂÂä¾Âç´è§ÂçÂÂæÂÂæ½å¼ÂéÂ
Âç½®çÂÂé¢ï¼ÂéÂÂä½ÂäºÂé¨æ§Âï¼Â使ä»Â们è½å¤Âè½»æ¾å®Âä¹ÂÃ¥ÂÂéÂ
Â置工ä½Âä»»å¡æµÂãÂÂç¨æ·æ éÂÂæ·±åÂ
¥äºÂ解
Tengo
è¯Âè¨ÂçÂÂç»ÂèÂÂï¼Â便è½快éÂÂÃ¥ÂÂ建åÂÂ管çÂÂä»»å¡æµÂã - çµ活æ§ï¼ÂéÂÂè¿Â
Tengo
èÂÂæ¬å¼ÂæÂÂï¼ÂæÂÂ们为æÂÂæ¯ç¨æ·æÂÂä¾ÂäºÂ强大çÂÂèªå®Âä¹Âè½åÂÂãÂÂä»Â们å¯以å¨èÂÂæ¬ä¸Â使ç¨æ¡件é»è¾ÂãÂÂ循ç¯ãÂÂèªå®Âä¹Âå½æ°çÂÂÃ¥ÂÂè½ï¼Â以æ´çµ活çÂÂæ¹å¼Âå¤ÂçÂÂä»»å¡é»è¾Âï¼Â满足å¤ÂæÂÂçÂÂä¸Âå¡éÂÂæ±Âã - å®Âæ¶å¨æÂÂï¼ÂæÂÂ们çÂÂæ¶æÂÂæ¯æÂÂå¨è¿Âè¡Âæ¶å¨æÂÂä¿®æ¹é Âç½®åÂÂä»»å¡æµÂï¼Âæ éÂÂéÂÂæ°å¯å¨åºÂç¨ç¨ÂåºÂãÂÂè¿Â使å¾Âç¨æ·å¯以å®Âæ¶å°对é Âç½®è¿Âè¡Âè°Âæ´ï¼ÂéÂÂç¨äºÂéÂÂè¦Âé¢Âç¹Âè°Âæ´åÂÂæµÂè¯Âé Âç½®çÂÂåºæ¯ãÂÂ
- å®ÂÃ¥Â
¨ä¿ÂéÂÂï¼ÂéÂÂè¿ÂéÂÂå¶
Tengo
èÂÂæÂÂÃ¥ÂÂè½åÂÂ访é®æÂÂéÂÂï¼ÂæÂÂ们确ä¿ÂäºÂé Â置修æ¹åÂÂä»»å¡æ§è¡ÂçÂÂå®Âå ¨æ§ãÂÂç¸æ¯Âç´æÂ¥æÂÂä½ÂæÂÂä½Âç³»ç»Âç¯å¢ÂÃ¥ÂÂéÂÂï¼Âè¿Âç§Âæ¹å¼ÂæÂÂä¾ÂäºÂæ´å¤ÂçÂÂå®Âå ¨ä¿ÂéÂÂãÂÂ
è¿Â个设计æ¹æ¡Âå°ÂÃ¥ÂÂ端çÂÂé¢丠Tengo
èÂÂæ¬å¼ÂæÂÂç´§å¯Âç»ÂÃ¥ÂÂï¼Âæ¢满足äºÂéÂÂæÂÂæ¯ç¨æ·çÂÂéÂÂæ±Âï¼ÂÃ¥ÂÂ为æÂÂæ¯ç¨æ·æÂÂä¾ÂäºÂèªå®Âä¹ÂÃ¥ÂÂæ©å±ÂçÂÂè½åÂÂãÂÂå¸ÂæÂÂå¨ä¿ÂæÂÂç¨æ·åÂÂ好çÂÂé¢çÂÂÃ¥ÂÂæ¶ï¼ÂèµÂäºÂ强大çÂÂèÂÂæ¬å¤ÂçÂÂè½åÂÂï¼Â使å¾Âä»»å¡æµÂéÂ
Âç½®æ´å çµ活ãÂÂé«ÂæÂÂï¼Â满足åÂÂç§Âå¤ÂæÂÂçÂÂä¸Âå¡åºæ¯éÂÂæ±ÂãÂÂ
Tengo å¿«éÂÂå¼Âå§Â
The Tengo Language: Tengo is a small, dynamic, fast, secure script language for Go.
å¯ä½Â为ç¬ç«Âè¯Âè¨Âæ§è¡Â
å ¨å±Âå®Âè£Â
go install github.com/d5/tengo/v2
交äºÂ模å¼Â
ç´æÂ¥è¾ÂÃ¥Â
Â¥ tengo
è¿ÂÃ¥Â
¥ç»Â端交äºÂå½令è¡Â
â tengo
>> a := "foo"
foo
>> b := -19.84
-19.84
>> c := 5
5
>> d := true
true
è¿Âè¡ÂèÂÂæ¬
- ç¼ÂÃ¥ÂÂ
demo.tengo
èÂÂæ¬
// module import
fmt := import("fmt")
// variable definition and primitive types
a := "foo" // string
b := -19.84 // floating point
c := 5 // integer
d := true // boolean
fmt.println("a: ", a)
fmt.println("b: ", b)
fmt.println("c: ", c)
fmt.println("d: ", d)
- 使ç¨
Tengo
解éÂÂå¨ç´æ¥解éÂÂæ§è¡Â
â tengo demo.tengo
a: foo
b: -19.84
c: 5
d: true
- ä¹Âæ¯æÂÂå Âç¼Âè¯ÂäºÂè¿Âå¶æÂÂ件åÂÂæ§è¡Â
â tengo -o demo demo.tengo
demo
â ls -l demo
-rwxr-xr-x 1 mystic staff 1556 8 13 21:01 demo
â tengo demo
a: foo
b: -19.84
c: 5
d: true
代ç Â示ä¾Â
ç®å½Âç»ÂæÂÂï¼Â
.
âÂÂâÂÂâ base.tengo
âÂÂâÂÂâ demo.tengo
base.tengo
èÂÂæ¬ï¼Â
// base.tengo
fn := func() {
return {
a: true,
b: [1, 2, 3],
c: {d: "ddd", e: "eee"}
}
}
// å°Âå½åÂÂ空é´导åºä¾ÂÃ¥Â
¶ä»ÂèÂÂæ¬使ç¨
export {
data: fn(),
}
demo.tengo
èÂÂæ¬ï¼Â
// demo.tengo
fmt := import("fmt")
base := import("./base")
fmt.println(base.data.a) // true
fmt.println(base.data.b[0]) // 1
fmt.println(base.data.c.d) // ddd
æ§è¡ÂèÂÂæ¬ï¼Â
â tengo demo.tengo
true
1
ddd
使ç¨ Go çÂÂç¼Âè¯ÂæÂÂè¿Âè¡Âæ¶
ä¸Âé¢çÂÂ示ä¾Âæ¼Â示äºÂå¦Âä½Âå¨ Go 代ç Âä¸Â使ç¨ Tengo 解éÂÂå¨æÂ¥æ§衠Tengo èÂÂæ¬
åºÂå®Âè£Â
go get github.com/d5/tengo/v2
代ç Â示ä¾Â
使ç¨ Tengo
计ç®Âæ°ç»ÂÃ¥Â
Âç´ ä¹ÂÃ¥ÂÂ
package main
import (
"context"
"fmt"
"github.com/d5/tengo/v2"
)
func main() {
// Ã¥ÂÂ建ä¸Â个æ°ç Tengo Script å®Âä¾Â
script := tengo.NewScript([]byte(
// Tengo èÂÂæÂŒÂÂ符串
`each := func(seq, fn) {
for x in seq { fn(x) }
}
sum := 0
each([a, b, c, d], func(x) {
sum += x
})`))
// 设置åÂÂéÂÂå¼
_ = script.Add("a", 1)
_ = script.Add("b", 2)
_ = script.Add("c", 3)
_ = script.Add("d", 4)
// è¿Âè¡ÂèÂÂæ¬
compiled, err := script.RunContext(context.Background())
if err != nil {
panic(err)
}
// æ£Âç´¢å¼
sum := compiled.Get("sum")
fmt.Println(sum) // æÂÂå°æÂȌÂÂ(sum)çÂÂå¼
}
使ç¨ Tengo
è¿Âè¡Â表达å¼Âæ±Âå¼
package main
import (
"context"
"fmt"
"github.com/d5/tengo/v2"
)
func main() {
// Ã¥ÂÂ建ä¸Â个空çÂÂä¸Âä¸ÂæÂÂ
ctx := context.TODO()
// å®Âä¹ Tengo 表达å¼Â并设置åÂÂé input 为 true
expression := `input ? "success" : "fail"`
// 设置ä¸Âä¸ÂæÂÂÃ¥ÂÂé input çÂÂå¼为 true
vars := map[string]any{"input": true}
// éÂÂè¿ Tengo.Eval è¿Âè¡Â表达å¼Âæ±Âå¼
res, err := tengo.Eval(ctx, expression, vars)
if err != nil {
panic(err)
}
// æÂÂå°ç»ÂæÂÂï¼ÂåºÂ为 "success"
fmt.Println(res)
}
å¨æÂÂé Âç½®æ¡Âä¾Â
éÂÂæ±ÂÃ¥ÂÂæÂÂ
ç®æ ÂéÂÂæ±Âå¦Âä¸Âï¼Â
æÂÂ们éÂÂè¿Âä¸Â个æÂȾ§èÂÂæ¬(base.tengo
)æÂ¥æ§å¶åÂ
¶ä»Â两个èÂÂæ¬(dev.tengo
Ã¥ÂÂprod.tengo
)çÂÂéÂÂ项åÂÂæ°ãÂÂå¸ÂæÂÂå®Âç°çÂÂæÂÂæÂÂæ¯根æ® currentEnv
Ã¥ÂÂéÂÂçÂÂå¼ï¼Âå¨æÂÂå 载ä¸ÂÃ¥ÂÂçÂÂèÂÂæ‹ÂÂ
å¯以æÂÂ砧以ä¸Âæ¥骤è¿Âè¡Âå®Âç°ï¼Â
- å¨æÂȾ§èÂÂæ¬(
base.tengo
)ä¸Âï¼Âæ´é²currentEnv
éÂÂ项åÂÂæ°ã - å¨主åºÂç¨ç¨ÂåºÂ(
main.go
)ä¸Â读åÂÂæÂȾ§èÂÂæ¬ï¼Âæ ¹æ®currentEnv
çÂÂå¼æÂ¥å 载对åºÂçÂÂç¯å¢Âé Âç½®èÂÂæ¬(dev.tengo
æÂÂprod.tengo
)ã - å¦å¤Âï¼ÂéÂÂè¿Âå¼Âå¯
goroutine
æÂ¥å¨æÂÂæ§å°æ´æ°é Âç½®ï¼Âå®Âç°å¨æÂÂÃ¥ÂÂæ¢ãÂÂ
è¿Âæ ·çÂÂ设计åÂ
Â许你根æ®æÂȾ§èÂÂæÂÂ设å®Âï¼Âå¨æÂÂå°éÂÂæ©使ç¨åª个æ°æ®åºÂéÂ
Âç½®èÂÂæ¬ï¼Â并根æ® isEnabled
çÂÂå¼æÂ¥å³å®Âæ¯å¦è¿ÂæÂ¥å°æ°æ®åºÂï¼ÂèÂÂä¸ÂéÂÂè¦Â使åºÂç¨ç¨ÂåºÂÃ¥ÂÂéÂÂå¯æÂÂéÂÂåºãÂÂè¿Âç§Âæ¹æ¡Âè½å¤ÂæÂÂé«ÂåºÂç¨çÂÂçµ活æ§åÂÂå®Âæ¶æ§ï¼Â满足å¨æÂÂéÂ
Âç½®éÂÂæ±ÂãÂÂ
ç®å½Âç»ÂæÂÂ
.
âÂÂâÂÂâ config
âÂÂààâÂÂâÂÂâ base.tengo
âÂÂààâÂÂâÂÂâ dev.tengo
âÂÂààâÂÂâÂÂâ prod.tengo
âÂÂâÂÂâ main.go
代ç Âå®Âç°
config/base.tengo
æÂÂ件
// å½ÂÃ¥ÂÂç¯å¢Âï¼Â主åºÂç¨ç¨ÂåºÂéÂÂè¿Â该å¼çÂÂÃ¥ÂÂÃ¥ÂÂï¼ÂéÂÂæ©åÂ
·ä½ÂçÂÂtengoèÂÂæ¬ï¼Â并å¨æÂÂå 载åÂÂæ°
currentEnv := "dev" // æ "prod"
config/dev.tengo
æÂÂ件
// dev configuration
fmt := import("fmt")
sshCmd := func(isEnabled) {
sys := {
user: "root",
password: "12345",
ip: "192.168.0.100",
port: 22
}
if isEnabled {
cmd := fmt.sprintf("sshpass -p '%s' ssh -p %d %s@%s", sys.password, sys.port, sys.user, sys.ip)
return cmd
}
return ""
}(true)
mysql := func(isEnabled) {
if isEnabled {
return {
host: "dev.mysql.com",
port: 3306,
username: "dev_user",
password: "dev_pass",
dbname: "dev_db"
}
}
return {}
}(true)
redis := func(isEnabled) {
if isEnabled {
return {
host: "dev.redis.com",
port: 6379,
password: "12345",
dbNumber: 0
}
}
return {}
}(true)
// test function
test := func() {
fmt.println(sshCmd)
fmt.printf("mysql: %v\n", mysql)
fmt.printf("redis: %v\n", redis)
}
// test()
config/prod.tengo
æÂÂ件
// prod configuration
fmt := import("fmt")
sshCmd := func(isEnabled) {
sys := {
user: "root",
password: "admin@123",
ip: "10.50.0.2",
port: 10022
}
if isEnabled {
cmd := fmt.sprintf("sshpass -p '%s' ssh -p %d %s@%s", sys.password, sys.port, sys.user, sys.ip)
return cmd
}
return ""
}(true)
mysql := func(isEnabled) {
if isEnabled {
return {
host: "prod.mysql.com",
port: 13306,
username: "prod_user",
password: "prod_pass",
dbname: "prod_db"
}
}
return {}
}(true)
redis := func(isEnabled) {
if isEnabled {
return {
host: "prod.redis.com",
port: 16379,
password: "secret-password",
dbNumber: 1
}
}
return {}
}(true)
// test function
test := func() {
fmt.println(sshCmd)
fmt.printf("mysql: %v\n", mysql)
fmt.printf("redis: %v\n", redis)
}
// test()
main.go
主æÂÂ件
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
"time"
"github.com/d5/tengo/v2"
"github.com/d5/tengo/v2/stdlib"
)
func loadConfigFile(filename string) ([]byte, error) {
configData, err := ioutil.ReadFile(filename)
if err != nil {
return nil, err
}
return configData, nil
}
func runConfigScript(script *tengo.Script) (*tengo.Compiled, error) {
compiled, err := script.Run()
if err != nil {
return nil, err
}
return compiled, nil
}
func execConnection(env string, compiled *tengo.Compiled) {
// è¿ÂæÂÂ¥ssh
func() {
sshCmd := compiled.Get("sshCmd").Value().(string)
if sshCmd == "" {
sshCmd = "unable to ssh connect!"
}
log.Printf("| Linux SSH (%s) is connecting | %s\n", env, sshCmd)
}()
// è¿ÂæÂÂ¥mysql
func() {
mysql := compiled.Get("mysql").Value().(map[string]any)
host := mysql["host"]
port := mysql["port"]
user := mysql["username"]
password := mysql["password"]
dbname := mysql["dbname"]
var dsn string
if host == nil || port == nil || user == nil || password == nil || dbname == nil {
dsn = "unable to mysql connect!"
} else {
dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, host, port, dbname)
}
log.Printf("| MySQL DSN (%s) is connecting | %s\n", env, dsn)
}()
// è¿ÂæÂÂ¥redis
func() {
redis := compiled.Get("redis").Value().(map[string]any)
host := redis["host"]
port := redis["port"]
password := redis["password"]
dbNumber := redis["dbNumber"]
var dsn string
if host == nil || port == nil || password == nil || dbNumber == nil {
dsn = "unable to redis connect!"
} else {
dsn = fmt.Sprintf("redis://%s@%s:%d/%d", password, host, port, dbNumber)
}
log.Printf("| REDIS URL (%s) is connecting | %s\n", env, dsn)
}()
}
func runConfigUpdater() {
var i int = 1
for {
fmt.Println("è½®è®ÂçÂÂå¬次æ°ï¼Â", i)
// å 载 base.tengo æÂÂ件æÂ¥è·åÂÂå½ÂÃ¥ÂÂç¯å¢ÂéÂ
Âç½®
baseConfigData, err := loadConfigFile("config/base.tengo")
if err != nil {
log.Fatalf("Error reading base config file:", err)
}
// Ã¥ÂÂ建 Tengo 解éÂÂå¨并å 载 base.tengo èÂÂæ¬
baseScript := tengo.NewScript(baseConfigData)
baseScript.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...))
baseCompiled, err := runConfigScript(baseScript)
if err != nil {
log.Fatalf("Error running base config script:", err)
}
currentEnv := baseCompiled.Get("currentEnv").Value().(string)
// å 载å½ÂÃ¥ÂÂç¯å¢ÂçÂÂéÂ
Âç½®æÂÂ件
var envConfigData []byte
switch strings.ToLower(currentEnv) {
case "prod":
envConfigData, err = loadConfigFile("config/prod.tengo")
case "dev":
fallthrough
default:
envConfigData, err = loadConfigFile("config/dev.tengo")
}
if err != nil {
log.Fatalf("Error reading %s config file:", currentEnv, err)
}
// Ã¥ÂÂ建 Tengo 解éÂÂå¨并å 载å½ÂÃ¥ÂÂç¯å¢ÂçÂÂéÂ
Âç½®èÂÂæ¬
envScript := tengo.NewScript(envConfigData)
envScript.SetImports(stdlib.GetModuleMap(stdlib.AllModuleNames()...))
envCompiled, err := runConfigScript(envScript)
if err != nil {
log.Fatalf("Error running config script:", err)
} else {
// æ§è¡Âè¿ÂæÂÂ¥
execConnection(currentEnv, envCompiled)
}
// 毠3 ç§ÂéÂÂæ°å 载ä¸Â次 base.tengo Ã¥ÂÂå½ÂÃ¥ÂÂç¯å¢ÂçÂÂéÂ
Âç½®æÂÂ件
time.Sleep(3 * time.Second)
i++
}
}
func main() {
// å¯å¨å¨æÂÂæ§ç goroutine æ¥读åÂÂÃ¥ÂÂæ´æ°è¿ÂæÂ¥åÂÂæ°
runConfigUpdater()
// æÂÂÃ¥ÂÂ主 goroutineï¼Â以便å¨æÂÂæ§ç goroutine 继ç»Âæ§è¡Â
select {}
}
æÂÂæÂÂæ¼Â示
ð¡ å½Âç¶ï¼Âè¿Âä»Â
ä»Â
æ¯ Tengo
ä½Â为èÂÂæ¬å¼ÂæÂÂçÂÂä¸Â个éÂÂ常åºç¡ÂçÂÂÃ¥ÂÂæÂ¥å°Âè¯ÂãÂÂå¨å®ÂéÂÂ
çÂÂçÂÂ产ç¯å¢Âä¸Âï¼ÂæÂÂ们并ä¸Â建议åºäºÂçµ活æ§èÂÂéÂÂç¨è¿Âæ ·çÂÂ设计æÂ¥åÂÂæ¢çÂÂ产åÂÂæµÂè¯ÂåºÂï¼Â