Compare commits
	
		
			26 Commits
		
	
	
		
			debug
			...
			wrong-copy
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | df64c02b16 | ||
|   | 27a2113d30 | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | 3d6c3d10bf | ||
|   | 5f811693f1 | ||
|   | 0068fb92eb | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | 71174ead45 | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | 43c18caceb | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | 7b4c9c3154 | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | 9d2649433d | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | 6353fa7dd3 | ||
|   | bfa837c88d | ||
|   | bdc454e7e5 | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | 9b3e85754c | ||
| ![dependabot-preview[bot]](/assets/img/avatar_default.png)  | af3dcc5f31 | ||
|   | c375fb9eaf | ||
|   | 70c314229f | ||
|   | 66e23ead00 | ||
|   | 2e5666c2b6 | ||
|   | 7675656a54 | ||
|   | 3d7f7b0ad1 | ||
|   | a1ccbd6cab | ||
|   | 33cb4ce63c | ||
|   | aefb4497e2 | ||
|   | 0047e66f10 | ||
|   | 6bae4254af | ||
|   | a9689993b0 | 
							
								
								
									
										10
									
								
								.github/workflows/docker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/docker.yml
									
									
									
									
										vendored
									
									
								
							| @@ -57,11 +57,11 @@ jobs: | ||||
|         run: | | ||||
|           docker push metrue/fx-python-base:latest | ||||
|  | ||||
|       # - name: build and publish fx rust image | ||||
|       #   if: always() | ||||
|       #   run: | | ||||
|       #     docker build -t metrue/fx-rust-base:latest -f ./assets/dockerfiles/base/rust/Dockerfile ./assets/dockerfiles/base/python | ||||
|       #     docker push metrue/fx-rust-base:latest | ||||
|       - name: build and publish fx perl image | ||||
|         if: always() | ||||
|         run: | | ||||
|           docker build -t metrue/fx-perl-base:latest -f ./assets/dockerfiles/base/perl/Dockerfile ./assets/dockerfiles/base/perl | ||||
|           docker push metrue/fx-perl-base:latest | ||||
|  | ||||
|       - name: build and publish fx julia image | ||||
|         if: always() | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| run: | ||||
|   deadline: 10m | ||||
|   timeout: 10m | ||||
|   deadline: 20m | ||||
|   timeout: 20m | ||||
|   issues-exit-code: 1 | ||||
|   tests: true | ||||
|   skip-dirs: | ||||
|   | ||||
							
								
								
									
										22
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								README.md
									
									
									
									
									
								
							| @@ -206,8 +206,26 @@ But we would suggest you run `kubectl config current-context` to check if the cu | ||||
| * Amazon Elastic Kubernetes Service (EKS) | ||||
|   TODO | ||||
|  | ||||
| * Google Kubernetes Engine (GKET) | ||||
|   TODO | ||||
| * Google Kubernetes Engine (GKE) | ||||
|  | ||||
| First you should create a Kubernetes cluster in your GKE, then make sure your KUBECONFIG is ready in `~/.kube/config`, if not, you can run following commands, | ||||
|  | ||||
| ``` shell | ||||
| $ gcloud auth login | ||||
| $ gcloud container clusters get-credentials <your cluster> --zone <zone> --project <project> | ||||
| ``` | ||||
|  | ||||
| Then make sure you current context is GKE cluster, you can check it with command, | ||||
|  | ||||
| ``` shell | ||||
| $ kubectl config current-context | ||||
| ``` | ||||
|  | ||||
| Then you can deploy your function onto GKE cluster with, | ||||
|  | ||||
| ```shell | ||||
| $ KUBECONFIG=~/.kube/config fx up examples/functions/JavaScript/func.js --name hellojs | ||||
| ``` | ||||
|  | ||||
| * Setup your own Kubernetes cluster | ||||
|  | ||||
|   | ||||
							
								
								
									
										26
									
								
								assets/dockerfiles/base/node/package-lock.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								assets/dockerfiles/base/node/package-lock.json
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| { | ||||
|   "name": "fx-node-base", | ||||
|   "version": "1.0.0", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
|     "@koa/cors": { | ||||
|       "version": "2.2.3", | ||||
|       "resolved": "https://registry.npmjs.org/@koa/cors/-/cors-2.2.3.tgz", | ||||
|       "integrity": "sha512-tCVVXa39ETsit5kGBtEWWimjLn1sDaeu8+0phgb8kT3GmBDZOykkI3ZO8nMjV2p3MGkJI4K5P+bxR8Ztq0bwsA==", | ||||
|       "requires": { | ||||
|         "vary": "^1.1.2" | ||||
|       } | ||||
|     }, | ||||
|     "node-fetch": { | ||||
|       "version": "2.6.0", | ||||
|       "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", | ||||
|       "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" | ||||
|     }, | ||||
|     "vary": { | ||||
|       "version": "1.1.2", | ||||
|       "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", | ||||
|       "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" | ||||
|     } | ||||
|   } | ||||
| } | ||||
							
								
								
									
										9
									
								
								assets/dockerfiles/base/node/package.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								assets/dockerfiles/base/node/package.json
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| { | ||||
|   "name": "aok", | ||||
|   "name": "fx-node-base", | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "main": "index.js", | ||||
| @@ -10,12 +10,11 @@ | ||||
|   "author": "", | ||||
|   "license": "ISC", | ||||
|   "dependencies": { | ||||
|     "@koa/cors": "^2.2.3", | ||||
|     "get-port": "^3.2.0", | ||||
|     "is-generator-function": "^1.0.6", | ||||
|     "koa": "^2.3.0", | ||||
|     "koa-bodyparser": "^4.2.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "get-port-cli": "^1.1.0" | ||||
|     "koa-bodyparser": "^4.2.0", | ||||
|     "node-fetch": "^2.6.0" | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								assets/dockerfiles/base/perl/cpanfile
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								assets/dockerfiles/base/perl/cpanfile
									
									
									
									
										vendored
									
									
								
							| @@ -1,2 +1,3 @@ | ||||
| requires "EV"; | ||||
| requires "JSON"; | ||||
| requires "Mojolicious::Lite"; | ||||
|   | ||||
							
								
								
									
										14
									
								
								config/env.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								config/env.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| ) | ||||
|  | ||||
| // DisableContainerAutoremove to tell if to run container with --rm | ||||
| var DisableContainerAutoremove = false | ||||
|  | ||||
| func init() { | ||||
| 	if os.Getenv("DISABLE_CONTAINER_AUTOREMOVE") == "true" { | ||||
| 		DisableContainerAutoremove = true | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										17
									
								
								config/env_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								config/env_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package config | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| var _ = func() (_ struct{}) { | ||||
| 	os.Setenv("DISABLE_CONTAINER_AUTOREMOVE", "true") | ||||
| 	return | ||||
| }() | ||||
|  | ||||
| func TestEnvLoad(t *testing.T) { | ||||
| 	if !DisableContainerAutoremove { | ||||
| 		t.Fatalf("should be true after set") | ||||
| 	} | ||||
| } | ||||
| @@ -23,6 +23,7 @@ import ( | ||||
| 	"github.com/docker/go-connections/nat" | ||||
| 	"github.com/google/go-querystring/query" | ||||
| 	"github.com/google/uuid" | ||||
| 	fxConfig "github.com/metrue/fx/config" | ||||
| 	containerruntimes "github.com/metrue/fx/container_runtimes" | ||||
| 	"github.com/metrue/fx/types" | ||||
| 	"github.com/metrue/fx/utils" | ||||
| @@ -402,7 +403,7 @@ func (api *API) StartContainer(ctx context.Context, name string, image string, b | ||||
| 	} | ||||
|  | ||||
| 	hostConfig := &dockerTypesContainer.HostConfig{ | ||||
| 		AutoRemove:   true, | ||||
| 		AutoRemove:   !fxConfig.DisableContainerAutoremove, | ||||
| 		PortBindings: portMap, | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -18,6 +18,7 @@ import ( | ||||
| 	"github.com/docker/docker/client" | ||||
| 	"github.com/docker/go-connections/nat" | ||||
| 	"github.com/google/uuid" | ||||
| 	fxConfig "github.com/metrue/fx/config" | ||||
| 	containerruntimes "github.com/metrue/fx/container_runtimes" | ||||
| 	"github.com/metrue/fx/types" | ||||
| 	"github.com/metrue/fx/utils" | ||||
| @@ -161,7 +162,7 @@ func (d *Docker) StartContainer(ctx context.Context, name string, image string, | ||||
| 	} | ||||
|  | ||||
| 	hostConfig := &dockerTypesContainer.HostConfig{ | ||||
| 		AutoRemove:   true, | ||||
| 		AutoRemove:   !fxConfig.DisableContainerAutoremove, | ||||
| 		PortBindings: portMap, | ||||
| 	} | ||||
| 	resp, err := d.ContainerCreate(ctx, config, hostConfig, nil, name) | ||||
|   | ||||
							
								
								
									
										38
									
								
								examples/functions/Perl/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								examples/functions/Perl/README.md
									
									
									
									
										vendored
									
									
								
							| @@ -1,10 +1,12 @@ | ||||
| # Make a Perl function a service with fx | ||||
|  | ||||
| Write a function like, | ||||
| [](https://asciinema.org/a/aXpr0jquwhhwhghiDCdC7nY8r) | ||||
|  | ||||
|  | ||||
| ### Hello World | ||||
|  | ||||
| ```perl | ||||
| sub fx { | ||||
|   my $ctx = shift; | ||||
|   return 'hello fx' | ||||
| } | ||||
|  | ||||
| @@ -14,7 +16,7 @@ sub fx { | ||||
| then deploy it with `fx up` command, | ||||
|  | ||||
| ```shell | ||||
| $ fx up -p 8080:3000 func.pl | ||||
| $ fx up -p 8080 --name helloworld func.pl | ||||
| ``` | ||||
|  | ||||
| test it using `curl` | ||||
| @@ -31,6 +33,36 @@ Date: Tue, 06 Aug 2019 15:58:41 GMT | ||||
| hello fx | ||||
| ``` | ||||
|  | ||||
| ### Sum | ||||
|  | ||||
| ```perl | ||||
| sub fx { | ||||
|   my $ctx = shift; | ||||
|   my $a = $ctx->req->json->{"a"}; | ||||
|   my $b = $ctx->req->json->{"b"}; | ||||
|   return int($a) + int($b) | ||||
| } | ||||
|  | ||||
| 1; | ||||
| ``` | ||||
|  | ||||
| ```shell | ||||
| fx up --name add --port 40002 --force add.pl | ||||
| ``` | ||||
|  | ||||
| Then test it with httpie. | ||||
| ```shell | ||||
| $ http post 0.0.0.0:40002 a=1 b=2 | ||||
|  | ||||
| HTTP/1.1 200 OK | ||||
| Content-Length: 1 | ||||
| Content-Type: application/json;charset=UTF-8 | ||||
| Date: Thu, 02 Jan 2020 15:39:49 GMT | ||||
| Server: Mojolicious (Perl) | ||||
|  | ||||
| 3 | ||||
| ``` | ||||
|  | ||||
| ### ctx | ||||
|  | ||||
| The `ctx` object is exactly the [Controller](https://mojolicious.org/perldoc/Mojolicious/Controller) of [Mojolicious](https://mojolicious.org/perldoc/Mojolicious) framework. | ||||
|   | ||||
							
								
								
									
										8
									
								
								examples/functions/Perl/add.pl
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/functions/Perl/add.pl
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| sub fx { | ||||
|   my $ctx = shift; | ||||
|   my $a = $ctx->req->json->{"a"}; | ||||
|   my $b = $ctx->req->json->{"b"}; | ||||
|   return int($a) + int($b) | ||||
| } | ||||
|  | ||||
| 1; | ||||
							
								
								
									
										417
									
								
								examples/functions/Perl/demo.cast
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										417
									
								
								examples/functions/Perl/demo.cast
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,417 @@ | ||||
| {"version": 2, "width": 204, "height": 47, "timestamp": 1577978477, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} | ||||
| [1.14954, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [1.150447, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007\u001b]1;..unctions/Perl\u0007"] | ||||
| [1.198859, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;31m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [1.199061, "o", "\u001b[?1h\u001b=\u001b[?2004h"] | ||||
| [2.253827, "o", "l"] | ||||
| [2.400431, "o", "\bls"] | ||||
| [2.55552, "o", "\u001b[?1l\u001b>"] | ||||
| [2.555606, "o", "\u001b[?2004l\r\r\n"] | ||||
| [2.557935, "o", "\u001b]2;ls -G\u0007\u001b]1;ls\u0007"] | ||||
| [2.565597, "o", "README.md add.pl    demo.cast hello.pl\r\n"] | ||||
| [2.566169, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [2.566464, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007\u001b]1;..unctions/Perl\u0007"] | ||||
| [2.616843, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [2.617034, "o", "\u001b[?1h\u001b=\u001b[?2004h"] | ||||
| [2.915162, "o", "v"] | ||||
| [2.988711, "o", "\bvi"] | ||||
| [3.202168, "o", "m"] | ||||
| [3.350667, "o", " "] | ||||
| [4.12655, "o", "h"] | ||||
| [4.274974, "o", "e"] | ||||
| [4.416048, "o", "llo.pl\u001b[1m \u001b[0m"] | ||||
| [4.787927, "o", "\b\u001b[0m \b"] | ||||
| [4.788014, "o", "\u001b[?1l\u001b>\u001b[?2004l"] | ||||
| [4.788292, "o", "\r\r\n"] | ||||
| [4.789415, "o", "\u001b]2;/usr/local/Cellar/vim/8.2.0/bin/vim hello.pl\u0007\u001b]1;vim\u0007"] | ||||
| [4.946445, "o", "\u001b[?1000h\u001b[?1049h\u001b[>4;2m\u001b[?1h\u001b=\u001b[?2004h\u001b[1;47r\u001b[?12h\u001b[?12l\u001b[22;2t\u001b[22;1t"] | ||||
| [4.947253, "o", "\u001b[27m\u001b[29m\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[H\u001b[2J\u001b[?25l\u001b[47;1H\"hello.pl\""] | ||||
| [4.947367, "o", " 5L, 35C"] | ||||
| [4.955849, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [4.974498, "o", "\u001b[?2004h\u001b[?1000h"] | ||||
| [5.109471, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [5.11056, "o", "\u001b[?2004h"] | ||||
| [5.110849, "o", "\u001b[?1000h\u001b[?1000l\u001b[?2004l"] | ||||
| [5.113119, "o", "\u001b[?2004h\u001b[?1000h"] | ||||
| [5.113304, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [5.116222, "o", "\u001b[?2004h\u001b[?1000h"] | ||||
| [5.116418, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [5.12038, "o", "\u001b[?2004h\u001b[?1000h\u001b[?1000l\u001b[?2004l"] | ||||
| [5.125489, "o", "\u001b[?2004h\u001b[?1000h\u001b[?1000l\u001b[?2004l"] | ||||
| [5.132998, "o", "\u001b[?2004h"] | ||||
| [5.133158, "o", "\u001b[?1000h\u001b[?2004h"] | ||||
| [5.134064, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [5.151895, "o", "\u001b[?2004h\u001b[?1000h"] | ||||
| [5.172471, "o", "\u001b[2;1H▽\u001b[6n\u001b[2;1H  \u001b[1;1H\u001b[>c"] | ||||
| [5.172688, "o", "\u001b]10;?\u0007\u001b]11;?\u0007"] | ||||
| [5.176877, "o", "\u001b[1;1H\u001b[38;2;75;82;99m  1 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;255;83;112msub \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;130;177;255mfx \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m{\r\n\u001b[38;2;75;82;99m  2 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m  \u001b[38;2;199;146;234mreturn\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m \u001b[38;2;195;232;141m'hello fx'\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\r\n\u001b[38;2;75;82;99m  3 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m}\r\n\u001b[38;2;75;82;99m  4 \r\n  5 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;247;140;108m1\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m;\r\n\u001b[38;2;59;64;72m~                                                                                                                                                                                                           \u001b[7;1H~                                                                                                                                                                                                           \u001b[8;1H~                     "] | ||||
| [5.177078, "o", "                                                                                                                                                                                      \u001b[9;1H~                                                                                                                                                                                                           \u001b[10;1H~                                                                                                                                                                                                           \u001b[11;1H~                                                                                                                                                                                                           \u001b[12;1H~                                                                                                                                                                                                          "] | ||||
| [5.177184, "o", " \u001b[13;1H~                                                                                                                                                                                                           \u001b[14;1H~                                                                                                                                                                                                           \u001b[15;1H~                                                                                                                                                                                                           \u001b[16;1H~                                                                                                                                                                                                           \u001b[17;1H~                                                                                                                                                                           "] | ||||
| [5.177303, "o", "                                \u001b[18;1H~                                                                                                                                                                                                           \u001b[19;1H~                                                                                                                                                                                                           \u001b[20;1H~                                                                                                                                                                                                           \u001b[21;1H~                                                                                                                                                                                                           \u001b[22;1H~                                                                                                                                            "] | ||||
| [5.17742, "o", "                                                               \u001b[23;1H~                                                                                                                                                                                                           \u001b[24;1H~                                                                                                                                                                                                           \u001b[25;1H~                                                                                                                                                                                                           \u001b[26;1H~                                                                                                                                                                                                           \u001b[27;1H~                                                                                                             "] | ||||
| [5.177516, "o", "                                                                                              \u001b[28;1H~                                                                                                                                                                                                           \u001b[29;1H~                                                                                                                                                                                                           \u001b[30;1H~                                                                                                                                                                                                           \u001b[31;1H~                                                                                                                                                                                                           \u001b[32;1H~                                                                              "] | ||||
| [5.177622, "o", "                                                                                                                             \u001b[33;1H~                                                                                                                                                                                                           \u001b[34;1H~                                                                                                                                                                                                           \u001b[35;1H~                                                                                                                                                                                                           \u001b[36;1H~                                                                                                                                                                                                           \u001b[37;1H~                                               "] | ||||
| [5.177732, "o", "                                                                                                                                                            \u001b[38;1H~                                                                                                                                                                                                           \u001b[39;1H~                                                                                                                                                                                                           \u001b[40;1H~                                                                                                                                                                                                           \u001b[41;1H~                                                                                                                                                                                                           "] | ||||
| [5.190961, "o", "\u001b[42;1H~                                                                                                                                                                                                           \u001b[43;1H~                                                                                                                                                                                                           \u001b[44;1H~                                                                                                                                                                                                           \u001b[45;1H~                                                                                                                                                                                                           \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;1H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222mNORMAL\u001b[m\u001b[38;2;191;19"] | ||||
| [5.192792, "o", "9;213m\u001b[48;2;41;45;62m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m ᚠ perl \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;191;199;213m\u001b[48;2;51;55;71m hello.pl                                                                                                                                          perl \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m utf-8[unix] \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m  20% \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m☰    1/5 ㏑\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m :  1 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;10H\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m+0 ~0 -0 ᚠ perl \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1C\u001b[38;2;191;199;213m\u001b[48;2;51;55;71mhello.pl\u001b[1;5H\u001b[?25h\u001b[?12$p"] | ||||
| [5.459655, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;10H\u001b[38;2;191;199;213m\u001b[48;2;71;75;89mᚠ perl! \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;191;199;213m\u001b[48;2;51;55;71m hello.pl        \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[149C\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m4\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[8C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m2/\u001b[2;5H"] | ||||
| [5.885479, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1;12H\u001b[38;2;130;177;255m{\u001b[3;5H}\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;10H\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m+0 ~0 -0 ᚠ perl! \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1C\u001b[38;2;191;199;213m\u001b[48;2;51;55;71mhello.pl\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[148C\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m6\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[8C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m3/\u001b[3;5H\u001b[?25h"] | ||||
| [6.061856, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1;12H{\u001b[3;5H}\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m8\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[8C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m4/\u001b[4;5H\u001b[?25h"] | ||||
| [6.227967, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;183H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m10\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[8C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m5/\u001b[5;5H"] | ||||
| [6.440828, "o", "\u0007"] | ||||
| [6.999501, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[47;1H\u001b[K\u001b[47;1H:\u001b[?1000l\u001b[?2004h\u001b[?25h"] | ||||
| [7.282638, "o", "q"] | ||||
| [7.580486, "o", "w"] | ||||
| [8.042814, "o", "\u001b[?25l\u001b[47;3H\u001b[K\u001b[47;3H\u001b[?25h"] | ||||
| [8.209127, "o", "\u001b[?25l\u001b[47;2H\u001b[K\u001b[47;2H\u001b[?25h"] | ||||
| [8.29389, "o", "w"] | ||||
| [8.364523, "o", "q"] | ||||
| [8.552089, "o", "\r"] | ||||
| [8.554758, "o", "\u001b[?1000h\u001b[?25l\u001b[?1000l\u001b[?2004l"] | ||||
| [8.555496, "o", "\"hello.pl\""] | ||||
| [8.564609, "o", " 5L, 35C written"] | ||||
| [8.595134, "o", "\r\u001b[23;2t\u001b[23;1t\r\r\n\u001b[39;49m\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[>4;m\u001b[?1049l"] | ||||
| [8.599757, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [8.600003, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007\u001b]1;..unctions/Perl\u0007"] | ||||
| [8.683359, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [8.683591, "o", "\u001b[?1h\u001b="] | ||||
| [8.683745, "o", "\u001b[?2004h"] | ||||
| [9.988453, "o", "f"] | ||||
| [10.203643, "o", "\bfx"] | ||||
| [10.533603, "o", " up --name add --port 40001 hello.pl --force"] | ||||
| [11.146588, "o", "\u001b[?1l\u001b>"] | ||||
| [11.146941, "o", "\u001b[?2004l\r\r\n"] | ||||
| [11.148205, "o", "\u001b]2;fx up --name add --port 40001 hello.pl --force\u0007"] | ||||
| [11.148443, "o", "\u001b]1;fx\u0007"] | ||||
| [11.24007, "o", "building \u001b[32m[                    ]\u001b[0m "] | ||||
| [11.340717, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.341114, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [11.341521, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kbuilding \u001b[32m[=>                  ]\u001b[0m "] | ||||
| [11.411368, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.411537, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [11.445379, "o", "destroying add \u001b[34m[===>                ]\u001b[0m "] | ||||
| [11.5467, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.547266, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [11.54763, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[=====>              ]\u001b[0m "] | ||||
| [11.652602, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.653023, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [11.653426, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[======>             ]\u001b[0m "] | ||||
| [11.756859, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.75701, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[========>           ]\u001b[0m "] | ||||
| [11.857969, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.858251, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [11.858445, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[==========>         ]\u001b[0m "] | ||||
| [11.962964, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.963505, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.963792, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [11.964263, "o", "\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[============>       ]\u001b[0m "] | ||||
| [12.066808, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.067166, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.067532, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [12.067729, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[==============>     ]\u001b[0m "] | ||||
| [12.11908, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.119302, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [12.167966, "o", "deploying add \u001b[36m[================>   ]\u001b[0m "] | ||||
| [12.271321, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.271512, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[==================> ]\u001b[0m "] | ||||
| [12.373093, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.373377, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [12.373483, "o", "deploying add \u001b[36m[===================>]\u001b[0m "] | ||||
| [12.475496, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.475887, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[                    ]\u001b[0m "] | ||||
| [12.576106, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.576491, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[=>                  ]\u001b[0m "] | ||||
| [12.681062, "o", "\b\b\b\b\b\b\b\b"] | ||||
| [12.681348, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [12.681596, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[===>                ]\u001b[0m "] | ||||
| [12.785704, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.786212, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [12.7866, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[=====>              ]\u001b[0m "] | ||||
| [12.889932, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.890131, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[======>             ]\u001b[0m "] | ||||
| [12.993483, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [12.993626, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[========>           ]\u001b[0m "] | ||||
| [13.09445, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.094945, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [13.095276, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[==========>         ]\u001b[0m "] | ||||
| [13.195321, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.195719, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [13.195845, "o", "\u001b[K\u001b[Kdeploying add \u001b[36m[============>       ]\u001b[0m "] | ||||
| [13.299457, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.299971, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[==============>     ]\u001b[0m "] | ||||
| [13.403608, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.404077, "o", "\b\b\b\b\b\b\b\b\b"] | ||||
| [13.404501, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[================>   ]\u001b[0m "] | ||||
| [13.505661, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.506245, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.506398, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.506526, "o", "\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [13.506799, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[==================> ]\u001b[0m "] | ||||
| [13.608501, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.608887, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [13.609235, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[===================>]\u001b[0m "] | ||||
| [13.709097, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.709286, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [13.709322, "o", "deploying add \u001b[36m[                    ]\u001b[0m "] | ||||
| [13.812622, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.813279, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.813713, "o", "\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[=>                  ]\u001b[0m "] | ||||
| [13.917566, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [13.917907, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[===>                ]\u001b[0m "] | ||||
| [14.02233, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [14.022513, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[=====>              ]\u001b[0m "] | ||||
| [14.125472, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [14.125627, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[======>             ]\u001b[0m "] | ||||
| [14.225728, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [14.226074, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[========>           ]\u001b[0m "] | ||||
| [14.326329, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [14.326708, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [14.327001, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [14.327291, "o", "deploying add \u001b[36m[==========>         ]\u001b[0m "] | ||||
| [14.430275, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [14.43045, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[36m[============>       ]\u001b[0m "] | ||||
| [14.477509, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [14.477667, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [14.480551, "o", "+------------------------------------------------------------------+------+---------------+\r\n|                                ID                                | NAME |   ENDPOINT    |\r\n+------------------------------------------------------------------+------+---------------+"] | ||||
| [14.480737, "o", "\r\n| dc546007a6b7c8738a3107efe18041da27ccc0f1dfd8e992bc0fb4b0514c9ba0 | /add | 0.0.0.0:40001 |\r\n+------------------------------------------------------------------+------+---------------+\r\n"] | ||||
| [14.48264, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [14.482857, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007\u001b]1;..unctions/Perl\u0007"] | ||||
| [14.538028, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [14.538161, "o", "\u001b[?1h\u001b="] | ||||
| [14.538226, "o", "\u001b[?2004h"] | ||||
| [15.721709, "o", "h"] | ||||
| [15.856214, "o", "\bht"] | ||||
| [16.027529, "o", "t"] | ||||
| [17.184631, "o", "p localhost:40001"] | ||||
| [17.671003, "o", "\u001b[?1l\u001b>"] | ||||
| [17.671086, "o", "\u001b[?2004l\r\r\n"] | ||||
| [17.672363, "o", "\u001b]2;http localhost:40001\u0007\u001b]1;http\u0007"] | ||||
| [17.96737, "o", "\u001b[34mHTTP\u001b[39;49;00m/\u001b[34m1.1\u001b[39;49;00m \u001b[34m200\u001b[39;49;00m \u001b[36mOK\u001b[39;49;00m\r\n\u001b[36mContent-Length\u001b[39;49;00m: 10\r\n\u001b[36mContent-Type\u001b[39;49;00m: application/json;charset=UTF-8\r\n\u001b[36mDate\u001b[39;49;00m: Thu, 02 Jan 2020 15:21:35 GMT\r\n\u001b[36mServer\u001b[39;49;00m: Mojolicious (Perl)\r\r\n\r\r\n"] | ||||
| [17.968554, "o", "\u001b[33m\"hello fx\"\u001b[39;49;00m\r\n\r\n"] | ||||
| [17.993945, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [17.994105, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007\u001b]1;..unctions/Perl\u0007"] | ||||
| [18.046585, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [18.046727, "o", "\u001b[?1h\u001b=\u001b[?2004h"] | ||||
| [19.712512, "o", "v"] | ||||
| [19.834568, "o", "\bvi"] | ||||
| [20.03562, "o", "m"] | ||||
| [20.145382, "o", " "] | ||||
| [20.224959, "o", "a"] | ||||
| [20.458989, "o", "."] | ||||
| [20.85012, "o", "\b \b"] | ||||
| [21.149959, "o", "dd.pl\u001b[1m \u001b[0m"] | ||||
| [21.640042, "o", "\b\u001b[0m \b"] | ||||
| [21.640125, "o", "\u001b[?1l\u001b>"] | ||||
| [21.640405, "o", "\u001b[?2004l\r\r\n"] | ||||
| [21.641586, "o", "\u001b]2;/usr/local/Cellar/vim/8.2.0/bin/vim add.pl\u0007\u001b]1;vim\u0007"] | ||||
| [21.809875, "o", "\u001b[?1000h\u001b[?1049h\u001b[>4;2m\u001b[?1h\u001b=\u001b[?2004h\u001b[1;47r\u001b[?12h\u001b[?12l\u001b[22;2t\u001b[22;1t"] | ||||
| [21.810887, "o", "\u001b[27m\u001b[29m\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[H\u001b[2J\u001b[?25l\u001b[47;1H\"add.pl\""] | ||||
| [21.811558, "o", " 8L, 129C"] | ||||
| [21.819874, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [21.836929, "o", "\u001b[?2004h"] | ||||
| [21.837071, "o", "\u001b[?1000h"] | ||||
| [21.966477, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [21.967556, "o", "\u001b[?2004h"] | ||||
| [21.967761, "o", "\u001b[?1000h\u001b[?1000l\u001b[?2004l"] | ||||
| [21.969825, "o", "\u001b[?2004h"] | ||||
| [21.969988, "o", "\u001b[?1000h\u001b[?1000l\u001b[?2004l"] | ||||
| [21.972986, "o", "\u001b[?2004h\u001b[?1000h"] | ||||
| [21.973119, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [21.977246, "o", "\u001b[?2004h\u001b[?1000h\u001b[?1000l\u001b[?2004l"] | ||||
| [21.982549, "o", "\u001b[?2004h\u001b[?1000h"] | ||||
| [21.982683, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [21.990047, "o", "\u001b[?2004h\u001b[?1000h\u001b[?2004h"] | ||||
| [21.991254, "o", "\u001b[?1000l\u001b[?2004l"] | ||||
| [22.007821, "o", "\u001b[?2004h\u001b[?1000h"] | ||||
| [22.024663, "o", "\u001b[2;1H▽\u001b[6n\u001b[2;1H  \u001b[1;1H\u001b[>c"] | ||||
| [22.02487, "o", "\u001b]10;?\u0007\u001b]11;?\u0007"] | ||||
| [22.032552, "o", "\u001b[1;1H\u001b[38;2;75;82;99m  1 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;255;83;112msub \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;130;177;255mfx \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m{\r\n\u001b[38;2;75;82;99m  2 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m  \u001b[38;2;199;146;234mmy\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m \u001b[38;2;255;83;112m$ctx\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m = \u001b[38;2;199;146;234mshift\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m;\r\n\u001b[38;2;75;82;99m  3 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m  \u001b[38;2;199;146;234mmy\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m \u001b[38;2;255;83;112m$a\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m = \u001b[38;2;255;83;112m$ctx->req->json->{\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;195;232;141m\"a\"\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;255;83;112m}\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m;\r\n\u001b[38;2;75;82;99m  4 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m  \u001b[38;2;199;146;234mmy\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m \u001b[38;2;255;83;112m$b\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m = \u001b[38;2;255;83;112m$ctx->req->json"] | ||||
| [22.032746, "o", "->{\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;195;232;141m\"b\"\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;255;83;112m}\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m;\r\n\u001b[38;2;75;82;99m  5 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m  \u001b[38;2;199;146;234mreturn\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m \u001b[38;2;199;146;234mint\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m(\u001b[38;2;255;83;112m$a\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m) + \u001b[38;2;199;146;234mint\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m(\u001b[38;2;255;83;112m$b\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m)\r\n\u001b[38;2;75;82;99m  6 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m}\r\n\u001b[38;2;75;82;99m  7 \r\n  8 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;247;140;108m1\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m;\r\n\u001b[38;2;59;64;72m~                                                                                                                                                                                                           \u001b[10;1H~                                                                                "] | ||||
| [22.032843, "o", "                                                                                                                           \u001b[11;1H~                                                                                                                                                                                                           \u001b[12;1H~                                                                                                                                                                                                           \u001b[13;1H~                                                                                                                                                                                                           \u001b[14;1H~                                                                                                                                                                                                           \u001b[15;1H~                                                 "] | ||||
| [22.03293, "o", "                                                                                                                                                          \u001b[16;1H~                                                                                                                                                                                                           \u001b[17;1H~                                                                                                                                                                                                           \u001b[18;1H~                                                                                                                                                                                                           \u001b[19;1H~                                                                                                                                                                                                           \u001b[20;1H~                  "] | ||||
| [22.033025, "o", "                                                                                                                                                                                         \u001b[21;1H~                                                                                                                                                                                                           \u001b[22;1H~                                                                                                                                                                                                           \u001b[23;1H~                                                                                                                                                                                                           \u001b[24;1H~                                                                                                                                                                                                      "] | ||||
| [22.03311, "o", "     \u001b[25;1H~                                                                                                                                                                                                           \u001b[26;1H~                                                                                                                                                                                                           \u001b[27;1H~                                                                                                                                                                                                           \u001b[28;1H~                                                                                                                                                                                                           \u001b[29;1H~                                                                                                                                                                       "] | ||||
| [22.033229, "o", "                                    \u001b[30;1H~                                                                                                                                                                                                           \u001b[31;1H~                                                                                                                                                                                                           \u001b[32;1H~                                                                                                                                                                                                           \u001b[33;1H~                                                                                                                                                                                                           \u001b[34;1H~                                                                                                                                        "] | ||||
| [22.033337, "o", "                                                                   \u001b[35;1H~                                                                                                                                                                                                           \u001b[36;1H~                                                                                                                                                                                                           \u001b[37;1H~                                                                                                                                                                                                           \u001b[38;1H~                                                                                                                                                                                                           \u001b[39;1H~                                                                             "] | ||||
| [22.042308, "o", "                                                                                                                              \u001b[40;1H~                                                                                                                                                                                                           \u001b[41;1H~                                                                                                                                                                                                           \u001b[42;1H~                                                                                                                                                                                                           \u001b[43;1H~                                                                                                                                                                                                           \u001b[44;1H~                                              "] | ||||
| [22.042505, "o", "                                                                                                                                                             \u001b[45;1H~                                                                                                                                                                                                           \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;1H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222mNORMAL\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m ᚠ perl \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;191;199;213m\u001b[48;2;51;55;71m add.pl                                                                                                                                            perl \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m"] | ||||
| [22.048105, "o", "\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m utf-8[unix] \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m  12% \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m☰    1/8 ㏑\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m :  1 \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;10H\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m+0 ~0 -0 ᚠ perl \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1C\u001b[38;2;191;199;213m\u001b[48;2;51;55;71madd.pl\u001b[1;5H\u001b[?25h"] | ||||
| [22.048832, "o", "\u001b[?12$p"] | ||||
| [22.111039, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;10H\u001b[38;2;191;199;213m\u001b[48;2;71;75;89mᚠ perl! \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[38;2;191;199;213m\u001b[48;2;51;55;71m add.pl        \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[151C\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m25\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m2/\u001b[2;5H"] | ||||
| [22.700162, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;10H\u001b[38;2;191;199;213m\u001b[48;2;71;75;89m+0 ~0 -0 ᚠ perl! \u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1C\u001b[38;2;191;199;213m\u001b[48;2;51;55;71madd.pl\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[150C\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m37\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m3/\u001b[3;5H"] | ||||
| [22.894195, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m50\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m4/\u001b[4;5H"] | ||||
| [23.081045, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m62\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m5/\u001b[5;5H"] | ||||
| [23.313711, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1;12H\u001b[38;2;130;177;255m{\u001b[6;5H}\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m75\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m6/\u001b[6;5H\u001b[?25h"] | ||||
| [23.602087, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1;12H{\u001b[6;5H}\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m87\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m7/\u001b[7;5H\u001b[?25h"] | ||||
| [23.962955, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;183H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m100\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m8/\u001b[8;5H"] | ||||
| [24.549961, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;183H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m 87\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m7/\u001b[7;5H"] | ||||
| [24.793843, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1;12H\u001b[38;2;130;177;255m{\u001b[6;5H}\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m75\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m6/\u001b[6;5H\u001b[?25h"] | ||||
| [24.99262, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[1;12H{\u001b[6;5H}\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m62\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m5/\u001b[5;5H\u001b[?25h"] | ||||
| [25.362512, "o", "\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[46;184H\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m50\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[7C\u001b[1m\u001b[38;2;41;45;62m\u001b[48;2;147;158;222m4/\u001b[4;5H"] | ||||
| [25.77714, "o", "\u001b[?25l\u001b[m\u001b[38;2;191;199;213m\u001b[48;2;41;45;62m\u001b[47;1H\u001b[K\u001b[47;1H:\u001b[?1000l\u001b[?2004h\u001b[?25h"] | ||||
| [25.945572, "o", "q"] | ||||
| [26.47528, "o", "\r"] | ||||
| [26.490539, "o", "\u001b[?1000h\u001b[?25l\u001b[?1000l\u001b[?2004l\u001b[23;2t\u001b[23;1t"] | ||||
| [26.490711, "o", "\u001b[47;1H\u001b[K\u001b[47;1H\u001b[?2004l\u001b[?1l\u001b>\u001b[?25h\u001b[>4;m\u001b[?1049l"] | ||||
| [26.493893, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [26.494036, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007\u001b]1;..unctions/Perl\u0007"] | ||||
| [26.55072, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [26.5509, "o", "\u001b[?1h\u001b=\u001b[?2004h"] | ||||
| [27.310856, "o", "f"] | ||||
| [27.553944, "o", "\bfx"] | ||||
| [28.138222, "o", " "] | ||||
| [28.326337, "o", "u"] | ||||
| [28.436765, "o", "p"] | ||||
| [28.894128, "o", " --name add --port 40001 hello.pl --force"] | ||||
| [29.129425, "o", "\u001b[18D2 add\u001b[P\u001b[P\u001b[11C  \b\b"] | ||||
| [32.439129, "o", "\u001b[?1l\u001b>\u001b[?2004l\r\r\n"] | ||||
| [32.440378, "o", "\u001b]2;fx up --name add --port 40002 add.pl --force\u0007"] | ||||
| [32.440597, "o", "\u001b]1;fx\u0007"] | ||||
| [32.556138, "o", "building \u001b[35m[                    ]\u001b[0m "] | ||||
| [32.660991, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [32.661456, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kbuilding \u001b[35m[=>                  ]\u001b[0m "] | ||||
| [32.762575, "o", "\b"] | ||||
| [32.763291, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [32.763534, "o", "building \u001b[35m[===>                ]\u001b[0m "] | ||||
| [32.783314, "o", "\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [32.783556, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [32.865981, "o", "destroying add \u001b[34m[=====>              ]\u001b[0m "] | ||||
| [32.966633, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [32.967025, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [32.967261, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[======>             ]\u001b[0m "] | ||||
| [33.069946, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.070613, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [33.070982, "o", "destroying add \u001b[34m[========>           ]\u001b[0m "] | ||||
| [33.170881, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.171194, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [33.171417, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[==========>         ]\u001b[0m "] | ||||
| [33.275611, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.276073, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[============>       ]\u001b[0m "] | ||||
| [33.380623, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.381102, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [33.381339, "o", "\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[==============>     ]\u001b[0m "] | ||||
| [33.48262, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.483143, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.483701, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [33.483998, "o", "destroying add \u001b[34m[================>   ]\u001b[0m "] | ||||
| [33.586747, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.58728, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [33.587416, "o", "destroying add \u001b[34m[==================> ]\u001b[0m "] | ||||
| [33.691358, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.691957, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [33.692362, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[===================>]\u001b[0m "] | ||||
| [33.792488, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.792889, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [33.793331, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[                    ]\u001b[0m "] | ||||
| [33.898149, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.89864, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [33.899119, "o", "\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[=>                  ]\u001b[0m "] | ||||
| [34.002146, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.002324, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[===>                ]\u001b[0m "] | ||||
| [34.106599, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.107121, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.107633, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[=====>              ]\u001b[0m "] | ||||
| [34.210556, "o", "\b"] | ||||
| [34.211072, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.21122, "o", "\b\b\b\b\b\b"] | ||||
| [34.211895, "o", "\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[======>             ]\u001b[0m "] | ||||
| [34.315191, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.315454, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [34.315605, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdestroying add \u001b[34m[========>           ]\u001b[0m "] | ||||
| [34.320443, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.320609, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K"] | ||||
| [34.320709, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [34.420121, "o", "deploying add \u001b[34m[==========>         ]\u001b[0m "] | ||||
| [34.523078, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.523295, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[============>       ]\u001b[0m "] | ||||
| [34.624895, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.62532, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.625574, "o", "\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[==============>     ]\u001b[0m "] | ||||
| [34.727629, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.728192, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.7286, "o", "\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[================>   ]\u001b[0m "] | ||||
| [34.831119, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.831739, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[==================> ]\u001b[0m "] | ||||
| [34.932013, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [34.932102, "o", ""] | ||||
| [34.932296, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[===================>]\u001b[0m "] | ||||
| [35.036361, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.036569, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.036826, "o", "\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.036903, "o", "\b\b\b\b\b\b\b\b\b"] | ||||
| [35.037301, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.037897, "o", "\u001b[Kdeploying add \u001b[34m[                    ]\u001b[0m "] | ||||
| [35.140429, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.14113, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.141475, "o", "deploying add \u001b[34m[=>                  ]\u001b[0m "] | ||||
| [35.241427, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.241811, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.242177, "o", "\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[===>                ]\u001b[0m "] | ||||
| [35.344792, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.345114, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.345431, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[=====>              ]\u001b[0m "] | ||||
| [35.44826, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.448627, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.448919, "o", "deploying add \u001b[34m[======>             ]\u001b[0m "] | ||||
| [35.55305, "o", "\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.55356, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.55388, "o", "\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[========>           ]\u001b[0m "] | ||||
| [35.65903, "o", "\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.65939, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.659725, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[==========>         ]\u001b[0m "] | ||||
| [35.75989, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.760206, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.760447, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[============>       ]\u001b[0m "] | ||||
| [35.86524, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.865663, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.866145, "o", "\u001b[K\u001b[Kdeploying add \u001b[34m[==============>     ]\u001b[0m "] | ||||
| [35.970426, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [35.970849, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [35.971211, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[================>   ]\u001b[0m "] | ||||
| [36.074506, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.07483, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [36.0751, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[==================> ]\u001b[0m "] | ||||
| [36.175231, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.175434, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[===================>]\u001b[0m "] | ||||
| [36.278976, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.279143, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [36.279243, "o", "deploying add \u001b[34m[                    ]\u001b[0m "] | ||||
| [36.380487, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.380963, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [36.381454, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[=>                  ]\u001b[0m "] | ||||
| [36.486341, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.487048, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[===>                ]\u001b[0m "] | ||||
| [36.588875, "o", "\b\b\b\b\b\b\b"] | ||||
| [36.589343, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.589578, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [36.589795, "o", "\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[=====>              ]\u001b[0m "] | ||||
| [36.691472, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.691721, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[Kdeploying add \u001b[34m[======>             ]\u001b[0m "] | ||||
| [36.711906, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b"] | ||||
| [36.712114, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K\u001b[K"] | ||||
| [36.714878, "o", "+------------------------------------------------------------------+------+---------------+\r\n|                                ID                                | NAME |   ENDPOINT    |"] | ||||
| [36.715104, "o", "\r\n+------------------------------------------------------------------+------+---------------+\r\n| 9ccf40c247b8cd6a82292fc526f6e1139432953b231ba4f51a1f18d4c13f6458 | /add | 0.0.0.0:40002 |\r\n+------------------------------------------------------------------+------+---------------+\r\n"] | ||||
| [36.716932, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [36.717114, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007"] | ||||
| [36.717147, "o", "\u001b]1;..unctions/Perl\u0007"] | ||||
| [36.779836, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [36.779976, "o", "\u001b[?1h\u001b=\u001b[?2004h"] | ||||
| [37.398193, "o", "h"] | ||||
| [37.594295, "o", "\bht"] | ||||
| [37.71095, "o", "t"] | ||||
| [37.85487, "o", "p"] | ||||
| [38.075195, "o", " "] | ||||
| [38.247123, "o", "p"] | ||||
| [38.426405, "o", "o"] | ||||
| [39.448868, "o", "st 0.0.0.0:40002 a=1 b=2"] | ||||
| [40.51774, "o", "\u001b[?1l\u001b>\u001b[?2004l"] | ||||
| [40.517813, "o", "\r\r\n"] | ||||
| [40.518991, "o", "\u001b]2;http post 0.0.0.0:40002 a=1 b=2\u0007"] | ||||
| [40.51914, "o", "\u001b]1;http\u0007"] | ||||
| [40.811478, "o", "\u001b[34mHTTP\u001b[39;49;00m/\u001b[34m1.1\u001b[39;49;00m \u001b[34m200\u001b[39;49;00m \u001b[36mOK\u001b[39;49;00m\r\n\u001b[36mContent-Length\u001b[39;49;00m: 1\r\n\u001b[36mContent-Type\u001b[39;49;00m: application/json;charset=UTF-8\r\n\u001b[36mDate\u001b[39;49;00m: Thu, 02 Jan 2020 15:21:57 GMT\r\n\u001b[36mServer\u001b[39;49;00m: Mojolicious (Perl)\r\r\n\r\r\n"] | ||||
| [40.812798, "o", "\u001b[34m3\u001b[39;49;00m\r\n\r\n"] | ||||
| [40.837697, "o", "\u001b[1m\u001b[7m%\u001b[27m\u001b[1m\u001b[0m                                                                                                                                                                                                           \r \r"] | ||||
| [40.837901, "o", "\u001b]2;minhuang@C02ZL0RJLVDN: ~/Codes/fx/examples/functions/Perl\u0007\u001b]1;..unctions/Perl\u0007"] | ||||
| [40.890525, "o", "\r\u001b[0m\u001b[27m\u001b[24m\u001b[J\u001b[01;32m➜  \u001b[36mPerl\u001b[00m \u001b[01;34mgit:(\u001b[31mperl\u001b[34m) \u001b[33m✗\u001b[00m \u001b[K"] | ||||
| [40.890681, "o", "\u001b[?1h\u001b=\u001b[?2004h"] | ||||
| [43.215524, "o", "\u001b[?2004l\r\r\n"] | ||||
| @@ -1,5 +1,4 @@ | ||||
| sub fx { | ||||
|   my $ctx = shift; | ||||
|   return 'hello fx' | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										10
									
								
								fx.go
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								fx.go
									
									
									
									
									
								
							| @@ -14,9 +14,10 @@ import ( | ||||
| 	"github.com/metrue/fx/handlers" | ||||
| 	"github.com/metrue/fx/middlewares" | ||||
| 	"github.com/urfave/cli" | ||||
| 	_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" | ||||
| ) | ||||
|  | ||||
| const version = "0.8.81" | ||||
| const version = "0.9.2" | ||||
|  | ||||
| func init() { | ||||
| 	go checkForUpdate() | ||||
| @@ -178,6 +179,13 @@ func main() { | ||||
| 			Name:    "list", | ||||
| 			Aliases: []string{"ls"}, | ||||
| 			Usage:   "list deployed services", | ||||
| 			Flags: []cli.Flag{ | ||||
| 				cli.StringFlag{ | ||||
| 					Name:  "format, f", | ||||
| 					Value: "table", | ||||
| 					Usage: "output format, 'table' and 'JSON' supported", | ||||
| 				}, | ||||
| 			}, | ||||
| 			Action: handle( | ||||
| 				middlewares.Parse("list"), | ||||
| 				middlewares.LoadConfig, | ||||
|   | ||||
							
								
								
									
										20
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								go.mod
									
									
									
									
									
								
							| @@ -5,16 +5,17 @@ go 1.12 | ||||
| require ( | ||||
| 	github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect | ||||
| 	github.com/Microsoft/go-winio v0.4.14 // indirect | ||||
| 	github.com/apex/log v1.1.1 | ||||
| 	github.com/briandowns/spinner v1.7.0 | ||||
| 	github.com/apex/log v1.1.2 | ||||
| 	github.com/briandowns/spinner v1.9.0 | ||||
| 	github.com/docker/distribution v2.7.1+incompatible // indirect | ||||
| 	github.com/docker/docker v0.0.0-20190313072916-46036c230805 | ||||
| 	github.com/docker/go-connections v0.4.0 | ||||
| 	github.com/docker/go-units v0.3.3 // indirect | ||||
| 	github.com/dsnet/compress v0.0.1 // indirect | ||||
| 	github.com/gin-gonic/gin v1.4.0 | ||||
| 	github.com/gobuffalo/envy v1.8.1 // indirect | ||||
| 	github.com/gobuffalo/packr v1.30.1 | ||||
| 	github.com/golang/mock v1.3.1 | ||||
| 	github.com/golang/mock v1.4.1 | ||||
| 	github.com/golang/snappy v0.0.1 // indirect | ||||
| 	github.com/google/go-querystring v1.0.0 | ||||
| 	github.com/google/uuid v1.1.1 | ||||
| @@ -33,15 +34,18 @@ require ( | ||||
| 	github.com/otiai10/copy v1.0.2 | ||||
| 	github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 | ||||
| 	github.com/pierrec/lz4 v0.0.0-20190222153722-062282ea0dcf // indirect | ||||
| 	github.com/pkg/errors v0.8.1 | ||||
| 	github.com/spf13/viper v1.6.1 | ||||
| 	github.com/stretchr/testify v1.4.0 | ||||
| 	github.com/pkg/errors v0.9.1 | ||||
| 	github.com/rogpeppe/go-internal v1.5.1 // indirect | ||||
| 	github.com/spf13/pflag v1.0.5 // indirect | ||||
| 	github.com/spf13/viper v1.6.2 | ||||
| 	github.com/stretchr/testify v1.5.1 | ||||
| 	github.com/ugorji/go v1.1.7 // indirect | ||||
| 	github.com/urfave/cli v1.22.2 | ||||
| 	github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 // indirect | ||||
| 	golang.org/x/crypto v0.0.0-20191219195013-becbf705a915 // indirect | ||||
| 	golang.org/x/sys v0.0.0-20191223224216-5a3cf8467b4e // indirect | ||||
| 	gopkg.in/inf.v0 v0.9.1 // indirect | ||||
| 	gopkg.in/yaml.v2 v2.2.7 | ||||
| 	gopkg.in/yaml.v2 v2.2.7 // indirect | ||||
| 	gotest.tools v2.2.0+incompatible // indirect | ||||
| 	k8s.io/api v0.0.0-20190925180651-d58b53da08f5 | ||||
| 	k8s.io/apimachinery v0.0.0-20190925235427-62598f38f24e | ||||
|   | ||||
							
								
								
									
										55
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								go.sum
									
									
									
									
									
								
							| @@ -1,5 +1,6 @@ | ||||
| cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||||
| cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||||
| cloud.google.com/go v0.38.0 h1:ROfEUZz+Gh5pa62DJWXSaonyu3StP6EA6lPEXPI6mCo= | ||||
| cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= | ||||
| github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8= | ||||
| github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= | ||||
| @@ -22,6 +23,9 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy | ||||
| github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||
| github.com/apex/log v1.1.1 h1:BwhRZ0qbjYtTob0I+2M+smavV0kOC8XgcnGZcyL9liA= | ||||
| github.com/apex/log v1.1.1/go.mod h1:Ls949n1HFtXfbDcjiTTFQqkVUrte0puoIBfO3SVgwOA= | ||||
| github.com/apex/log v1.1.2 h1:bnDuVoi+o98wOdVqfEzNDlY0tcmBia7r4YkjS9EqGYk= | ||||
| github.com/apex/log v1.1.2/go.mod h1:SyfRweFO+TlkIJ3DVizTSeI1xk7jOIIqOnUPZQTTsww= | ||||
| github.com/apex/logs v0.0.3/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= | ||||
| github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= | ||||
| github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= | ||||
| github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= | ||||
| @@ -31,6 +35,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24 | ||||
| github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | ||||
| github.com/briandowns/spinner v1.7.0 h1:aan1hBBOoscry2TXAkgtxkJiq7Se0+9pt+TUWaPrB4g= | ||||
| github.com/briandowns/spinner v1.7.0/go.mod h1://Zf9tMcxfRUA36V23M6YGEAv+kECGfvpnLTnb8n4XQ= | ||||
| github.com/briandowns/spinner v1.9.0 h1:+OMAisemaHar1hjuJ3Z2hIvNhQl9Y7GLPWUwwz2Pxo8= | ||||
| github.com/briandowns/spinner v1.9.0/go.mod h1://Zf9tMcxfRUA36V23M6YGEAv+kECGfvpnLTnb8n4XQ= | ||||
| github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= | ||||
| github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= | ||||
| github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= | ||||
| @@ -87,11 +93,15 @@ github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dp | ||||
| github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | ||||
| github.com/gobuffalo/envy v1.7.0 h1:GlXgaiBkmrYMHco6t4j7SacKO4XUjvh5pwXh0f4uxXU= | ||||
| github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= | ||||
| github.com/gobuffalo/envy v1.8.1 h1:RUr68liRvs0TS1D5qdW3mQv2SjAsu1QWMCx1tG4kDjs= | ||||
| github.com/gobuffalo/envy v1.8.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= | ||||
| github.com/gobuffalo/logger v1.0.0 h1:xw9Ko9EcC5iAFprrjJ6oZco9UpzS5MQ4jAwghsLHdy4= | ||||
| github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= | ||||
| github.com/gobuffalo/packd v0.3.0 h1:eMwymTkA1uXsqxS0Tpoop3Lc0u3kTfiMBE6nKtQU4g4= | ||||
| github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= | ||||
| github.com/gobuffalo/packr v1.30.1 h1:hu1fuVR3fXEZR7rXNW3h8rqSML8EVAf6KNm0NKO/wKg= | ||||
| github.com/gobuffalo/packr v1.30.1/go.mod h1:ljMyFO2EcrnzsHsN99cvbq055Y9OhRrIaviy289eRuk= | ||||
| github.com/gobuffalo/packr/v2 v2.5.1 h1:TFOeY2VoGamPjQLiNDT3mn//ytzk236VMO2j7iHxJR4= | ||||
| github.com/gobuffalo/packr/v2 v2.5.1/go.mod h1:8f9c96ITobJlPzI44jj+4tHnEKNt0xXWSVlXRN9X1Iw= | ||||
| github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||
| github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= | ||||
| @@ -105,6 +115,10 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb | ||||
| github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s= | ||||
| github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= | ||||
| github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg= | ||||
| github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= | ||||
| github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U= | ||||
| github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= | ||||
| github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| @@ -131,6 +145,7 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsC | ||||
| github.com/googleapis/gnostic v0.3.1 h1:WeAefnSUHlBb0iJKwxFDZdbfGwkd7xRNuV+IpXMJhYk= | ||||
| github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= | ||||
| github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= | ||||
| github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= | ||||
| github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= | ||||
| github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= | ||||
| github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= | ||||
| @@ -147,6 +162,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO | ||||
| github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= | ||||
| github.com/imdario/mergo v0.3.7 h1:Y+UAYTZ7gDEuOfhxKWy+dvb5dRQ6rJjFSdX2HZY1/gI= | ||||
| github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= | ||||
| github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= | ||||
| github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= | ||||
| github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= | ||||
| github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= | ||||
| @@ -158,6 +174,7 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV | ||||
| github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo= | ||||
| github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||
| github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= | ||||
| github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= | ||||
| github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= | ||||
| github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= | ||||
| github.com/karrick/godirwalk v1.10.12 h1:BqUm+LuJcXjGv1d2mj3gBiQyrQ57a0rYoAmhvJQ7RDU= | ||||
| @@ -191,15 +208,9 @@ github.com/mattn/go-isatty v0.0.7 h1:UvyT9uN+3r7yLEYSlJsbQGdsaB/a0DlgWP3pql6iwOc | ||||
| github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||||
| github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= | ||||
| github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= | ||||
| github.com/mattn/go-runewidth v0.0.6 h1:V2iyH+aX9C5fsYCpK60U8BYIvmhqxuOL3JZcqc1NB7k= | ||||
| github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= | ||||
| github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54= | ||||
| github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||
| github.com/metrue/go-ssh-client v0.0.0-20191125030649-4ac058ee958b h1:JGD0sJ44XzhsT1voOg00zji4ubuMNcVNK3m7d9GI88k= | ||||
| github.com/metrue/go-ssh-client v0.0.0-20191125030649-4ac058ee958b/go.mod h1:ERHOEBrDy6+8vfoJjjmhdmBpOzdvvP7bLtwYTTK6LOs= | ||||
| github.com/metrue/go-ssh-client v0.0.0-20191209160027-5773243a8bc9 h1:HHfMhG77ZLn3FOH3AGXW/F5RpAABVH6Fr5mVZZ97S6w= | ||||
| github.com/metrue/go-ssh-client v0.0.0-20191209160027-5773243a8bc9/go.mod h1:aPG/JtXTyLliKDDlkv+nzHbSbz2p2CBMAjNJRK4uhzY= | ||||
| github.com/metrue/go-ssh-client v0.0.0-20191219103445-1f07b67e2b29 h1:ENoMPMVc24XbBuVZ7guZmTB/7MSd+vqOkImSu9UUiJw= | ||||
| github.com/metrue/go-ssh-client v0.0.0-20191219103445-1f07b67e2b29/go.mod h1:aPG/JtXTyLliKDDlkv+nzHbSbz2p2CBMAjNJRK4uhzY= | ||||
| github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= | ||||
| @@ -224,8 +235,6 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+ | ||||
| github.com/nwaples/rardecode v1.0.0 h1:r7vGuS5akxOnR4JQSkko62RJ1ReCMXxQRPtxsiFMBOs= | ||||
| github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= | ||||
| github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= | ||||
| github.com/olekukonko/tablewriter v0.0.3 h1:i0LBnzgiChAWHJYTQAZJDOgf8MNxAVYZJ2m63SIDimI= | ||||
| github.com/olekukonko/tablewriter v0.0.3/go.mod h1:YZeBtGzYYEsCHp2LST/u/0NDwGkRoBtmn1cIWCJiS6M= | ||||
| github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8= | ||||
| github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA= | ||||
| github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| @@ -239,7 +248,9 @@ github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVo | ||||
| github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= | ||||
| github.com/otiai10/copy v1.0.2 h1:DDNipYy6RkIkjMwy+AWzgKiNTyj2RUI9yEMeETEpVyc= | ||||
| github.com/otiai10/copy v1.0.2/go.mod h1:c7RpqBkwMom4bYTSkLSym4VSJz/XtncWRAj/J4PEIMY= | ||||
| github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95 h1:+OLn68pqasWca0z5ryit9KGfp3sUsW4Lqg32iRMJyzs= | ||||
| github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= | ||||
| github.com/otiai10/mint v1.3.0 h1:Ady6MKVezQwHBkGzLFbrsywyp09Ah7rkmfjV3Bcr5uc= | ||||
| github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= | ||||
| github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= | ||||
| github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= | ||||
| @@ -251,6 +262,10 @@ github.com/pierrec/lz4 v0.0.0-20190222153722-062282ea0dcf/go.mod h1:3/3N9NVKO0je | ||||
| github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= | ||||
| github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/errors v0.9.0 h1:J8lpUdobwIeCI7OiSxHqEwJUKvJwicL5+3v1oe2Yb4k= | ||||
| github.com/pkg/errors v0.9.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||||
| github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= | ||||
| github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| @@ -269,6 +284,9 @@ github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L | ||||
| github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | ||||
| github.com/rogpeppe/go-internal v1.5.1 h1:asQ0uD7BN9RU5Im41SEEZTwCi/zAXdMOLS3npYaos2g= | ||||
| github.com/rogpeppe/go-internal v1.5.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | ||||
| github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= | ||||
| github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= | ||||
| github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= | ||||
| @@ -281,8 +299,10 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB | ||||
| github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= | ||||
| github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= | ||||
| github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= | ||||
| github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8= | ||||
| github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= | ||||
| github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= | ||||
| github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= | ||||
| github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= | ||||
| github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= | ||||
| github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= | ||||
| @@ -299,10 +319,14 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6 | ||||
| github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||
| github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | ||||
| github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||
| github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||||
| github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||||
| github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= | ||||
| github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= | ||||
| github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk= | ||||
| github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= | ||||
| github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= | ||||
| github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= | ||||
| github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| @@ -312,6 +336,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= | ||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
| github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= | ||||
| github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||||
| github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= | ||||
| github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= | ||||
| github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= | ||||
| @@ -327,8 +353,6 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs | ||||
| github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= | ||||
| github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= | ||||
| github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= | ||||
| github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= | ||||
| github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||||
| github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= | ||||
| github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= | ||||
| github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= | ||||
| @@ -349,6 +373,8 @@ golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8U | ||||
| golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc= | ||||
| golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20191219195013-becbf705a915 h1:aJ0ex187qoXrJHPo8ZasVTASQB7llQP6YeNzgDALPRk= | ||||
| golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | ||||
| @@ -396,9 +422,10 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 h1:LepdCS8Gf/MVejFIt8lsiexZATdoGVyp5bcyS+rYoUI= | ||||
| golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191223224216-5a3cf8467b4e h1:z2Flw7sLy7DxaQi3zDOvI9X+Kb06+G9iZJlkEyHvujE= | ||||
| golang.org/x/sys v0.0.0-20191223224216-5a3cf8467b4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= | ||||
| @@ -477,6 +504,10 @@ k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf/go.mod h1:1TqjTSzOxsLGIKf | ||||
| k8s.io/utils v0.0.0-20190920012459-5008bf6f8cd6/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= | ||||
| k8s.io/utils v0.0.0-20190923111123-69764acb6e8e h1:BXSmdH6S3YGLlhC89DZp+sNdYSmwNeDU6Xu5ZpzGOlM= | ||||
| k8s.io/utils v0.0.0-20190923111123-69764acb6e8e/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= | ||||
| rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= | ||||
| rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= | ||||
| rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= | ||||
| rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= | ||||
| sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= | ||||
| sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= | ||||
| sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import ( | ||||
| 	"github.com/metrue/fx/constants" | ||||
| 	containerruntimes "github.com/metrue/fx/container_runtimes" | ||||
| 	"github.com/metrue/fx/context" | ||||
| 	"github.com/metrue/fx/hook" | ||||
| 	"github.com/metrue/fx/packer" | ||||
| 	"github.com/metrue/fx/pkg/spinner" | ||||
| 	"github.com/metrue/fx/utils" | ||||
| @@ -39,6 +40,9 @@ func BuildImage(ctx context.Contexter) (err error) { | ||||
| 		if err := packer.Pack(workdir, sources...); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if err := hook.RunBeforeBuildHook(workdir); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	docker := ctx.Get("docker").(containerruntimes.ContainerRuntime) | ||||
| @@ -68,6 +72,9 @@ func ExportImage(ctx context.Contexter) (err error) { | ||||
| 		if err := packer.Pack(outputDir, sources...); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if err := hook.RunBeforeBuildHook(outputDir); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	log.Infof("exported to %v: %v", outputDir, constants.CheckedSymbol) | ||||
|   | ||||
| @@ -3,19 +3,19 @@ package handlers | ||||
| import ( | ||||
| 	"github.com/metrue/fx/context" | ||||
| 	"github.com/metrue/fx/infra" | ||||
| 	"github.com/metrue/fx/pkg/render" | ||||
| 	"github.com/metrue/fx/pkg/renderrer" | ||||
| ) | ||||
|  | ||||
| // List command handle | ||||
| func List(ctx context.Contexter) (err error) { | ||||
| 	cli := ctx.GetCliContext() | ||||
| 	deployer := ctx.Get("deployer").(infra.Deployer) | ||||
| 	format := ctx.Get("format").(string) | ||||
|  | ||||
| 	services, err := deployer.List(ctx.GetContext(), cli.Args().First()) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	render.Table(services) | ||||
| 	return nil | ||||
| 	return renderrer.Render(services, format) | ||||
| } | ||||
|   | ||||
| @@ -1,9 +1,10 @@ | ||||
| package handlers | ||||
|  | ||||
| import ( | ||||
| 	"github.com/apex/log" | ||||
| 	"github.com/metrue/fx/context" | ||||
| 	"github.com/metrue/fx/infra" | ||||
| 	"github.com/metrue/fx/pkg/render" | ||||
| 	"github.com/metrue/fx/pkg/renderrer" | ||||
| 	"github.com/metrue/fx/types" | ||||
| ) | ||||
|  | ||||
| @@ -20,6 +21,12 @@ func Up(ctx context.Contexter) (err error) { | ||||
| 	name := ctx.Get("name").(string) | ||||
| 	deployer := ctx.Get("deployer").(infra.Deployer) | ||||
| 	bindings := ctx.Get("bindings").([]types.PortBinding) | ||||
| 	force := ctx.Get("force").(bool) | ||||
| 	if force && name != "" { | ||||
| 		if err := deployer.Destroy(ctx.GetContext(), name); err != nil { | ||||
| 			log.Warnf("destroy service %s failed: %v", name, err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if err := deployer.Deploy( | ||||
| 		ctx.GetContext(), | ||||
| @@ -35,6 +42,5 @@ func Up(ctx context.Contexter) (err error) { | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	render.Table([]types.Service{service}) | ||||
| 	return nil | ||||
| 	return renderrer.Render([]types.Service{service}, "table") | ||||
| } | ||||
|   | ||||
| @@ -11,30 +11,64 @@ import ( | ||||
| ) | ||||
|  | ||||
| func TestUp(t *testing.T) { | ||||
| 	ctrl := gomock.NewController(t) | ||||
| 	defer ctrl.Finish() | ||||
| 	t.Run("normally up", func(t *testing.T) { | ||||
| 		ctrl := gomock.NewController(t) | ||||
| 		defer ctrl.Finish() | ||||
|  | ||||
| 	ctx := mockCtx.NewMockContexter(ctrl) | ||||
| 	deployer := mockDeployer.NewMockDeployer(ctrl) | ||||
| 		ctx := mockCtx.NewMockContexter(ctrl) | ||||
| 		deployer := mockDeployer.NewMockDeployer(ctrl) | ||||
|  | ||||
| 	bindings := []types.PortBinding{} | ||||
| 	name := "sample-name" | ||||
| 	image := "sample-image" | ||||
| 	data := "sample-data" | ||||
| 	ctx.EXPECT().Get("name").Return(name) | ||||
| 	ctx.EXPECT().Get("image").Return(image) | ||||
| 	ctx.EXPECT().Get("deployer").Return(deployer) | ||||
| 	ctx.EXPECT().Get("bindings").Return(bindings) | ||||
| 	ctx.EXPECT().Get("data").Return(data) | ||||
| 	ctx.EXPECT().GetContext().Return(context.Background()).Times(2) | ||||
| 	deployer.EXPECT().Deploy(gomock.Any(), data, name, image, bindings).Return(nil) | ||||
| 	deployer.EXPECT().GetStatus(gomock.Any(), name).Return(types.Service{ | ||||
| 		ID:   "id-1", | ||||
| 		Name: name, | ||||
| 		Host: "127.0.0.1", | ||||
| 		Port: 2100, | ||||
| 	}, nil) | ||||
| 	if err := Up(ctx); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 		bindings := []types.PortBinding{} | ||||
| 		name := "sample-name" | ||||
| 		image := "sample-image" | ||||
| 		data := "sample-data" | ||||
| 		ctx.EXPECT().Get("name").Return(name) | ||||
| 		ctx.EXPECT().Get("image").Return(image) | ||||
| 		ctx.EXPECT().Get("deployer").Return(deployer) | ||||
| 		ctx.EXPECT().Get("bindings").Return(bindings) | ||||
| 		ctx.EXPECT().Get("data").Return(data) | ||||
| 		ctx.EXPECT().Get("force").Return(false) | ||||
| 		ctx.EXPECT().GetContext().Return(context.Background()).Times(2) | ||||
| 		deployer.EXPECT().Deploy(gomock.Any(), data, name, image, bindings).Return(nil) | ||||
| 		deployer.EXPECT().GetStatus(gomock.Any(), name).Return(types.Service{ | ||||
| 			ID:   "id-1", | ||||
| 			Name: name, | ||||
| 			Host: "127.0.0.1", | ||||
| 			Port: 2100, | ||||
| 		}, nil) | ||||
| 		if err := Up(ctx); err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("normally up forcely", func(t *testing.T) { | ||||
| 		ctrl := gomock.NewController(t) | ||||
| 		defer ctrl.Finish() | ||||
|  | ||||
| 		ctx := mockCtx.NewMockContexter(ctrl) | ||||
| 		deployer := mockDeployer.NewMockDeployer(ctrl) | ||||
|  | ||||
| 		bindings := []types.PortBinding{} | ||||
| 		name := "sample-name" | ||||
| 		image := "sample-image" | ||||
| 		data := "sample-data" | ||||
| 		ctx.EXPECT().Get("name").Return(name) | ||||
| 		ctx.EXPECT().Get("image").Return(image) | ||||
| 		ctx.EXPECT().Get("deployer").Return(deployer) | ||||
| 		ctx.EXPECT().Get("bindings").Return(bindings) | ||||
| 		ctx.EXPECT().Get("data").Return(data) | ||||
| 		ctx.EXPECT().Get("force").Return(true) | ||||
| 		ctx.EXPECT().GetContext().Return(context.Background()).Times(3) | ||||
| 		deployer.EXPECT().Deploy(gomock.Any(), data, name, image, bindings).Return(nil) | ||||
| 		deployer.EXPECT().Destroy(gomock.Any(), name).Return(nil) | ||||
| 		deployer.EXPECT().GetStatus(gomock.Any(), name).Return(types.Service{ | ||||
| 			ID:   "id-1", | ||||
| 			Name: name, | ||||
| 			Host: "127.0.0.1", | ||||
| 			Port: 2100, | ||||
| 		}, nil) | ||||
| 		if err := Up(ctx); err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
							
								
								
									
										1
									
								
								hook/.hooks/before_build
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								hook/.hooks/before_build
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| npm install | ||||
							
								
								
									
										15
									
								
								hook/fixture/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								hook/fixture/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| { | ||||
|   "name": "fixture", | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "main": "index.js", | ||||
|   "scripts": { | ||||
|     "test": "echo \"Error: no test specified\" && exit 1" | ||||
|   }, | ||||
|   "keywords": [], | ||||
|   "author": "", | ||||
|   "license": "ISC", | ||||
|   "dependencies": { | ||||
|     "leftpad": "0.0.1" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										73
									
								
								hook/hook.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								hook/hook.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | ||||
| package hook | ||||
|  | ||||
| import ( | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"os/exec" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/metrue/fx/utils" | ||||
| ) | ||||
|  | ||||
| // Hooker defines hook interface | ||||
| type Hooker interface { | ||||
| 	Run() error | ||||
| } | ||||
|  | ||||
| // Hook to run | ||||
| type Hook struct { | ||||
| 	name   string | ||||
| 	script string | ||||
| } | ||||
|  | ||||
| // New a hook | ||||
| func New(name string, script string, workdir string) *Hook { | ||||
| 	return &Hook{ | ||||
| 		name:   name, | ||||
| 		script: script, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Run execute a hook | ||||
| func (h *Hook) Run(workdir string) error { | ||||
| 	var script string | ||||
| 	if !utils.IsRegularFile(h.script) { | ||||
| 		hookScript, err := ioutil.TempFile(os.TempDir(), "fx-hook-script-") | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		defer os.Remove(hookScript.Name()) | ||||
|  | ||||
| 		content := []byte(h.script) | ||||
| 		if _, err = hookScript.Write(content); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if err := hookScript.Close(); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		script = hookScript.Name() | ||||
| 	} else { | ||||
| 		absScript, err := filepath.Abs(h.script) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		script = absScript | ||||
| 	} | ||||
|  | ||||
| 	cmd := exec.Command("/bin/sh", script) | ||||
| 	cmd.Stdout = os.Stdout | ||||
| 	cmd.Stderr = os.Stderr | ||||
| 	if workdir != "" { | ||||
| 		cmd.Dir = workdir | ||||
| 	} | ||||
|  | ||||
| 	if err := cmd.Run(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Name hook name | ||||
| func (h *Hook) Name() string { | ||||
| 	return h.name | ||||
| } | ||||
							
								
								
									
										54
									
								
								hook/hook_manager.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								hook/hook_manager.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| package hook | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
|  | ||||
| 	"github.com/metrue/fx/utils" | ||||
| ) | ||||
|  | ||||
| // HookNameBeforeBuild before build hook | ||||
| const HookNameBeforeBuild = "before_build" | ||||
|  | ||||
| // RunBeforeBuildHook trigger before_build hook | ||||
| func RunBeforeBuildHook(workdir string) error { | ||||
| 	hooks, err := descovery("") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	for _, h := range hooks { | ||||
| 		if h.Name() == HookNameBeforeBuild { | ||||
| 			if err := h.Run(workdir); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func descovery(hookdir string) ([]*Hook, error) { | ||||
| 	if hookdir == "" { | ||||
| 		dir, err := os.Getwd() | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		hookdir = filepath.Join(dir, ".hooks") | ||||
| 	} | ||||
|  | ||||
| 	hooks := []*Hook{} | ||||
| 	if !utils.IsDir(hookdir) { | ||||
| 		return hooks, nil | ||||
| 	} | ||||
| 	if err := filepath.Walk(hookdir, func(path string, info os.FileInfo, err error) error { | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if info.Name() == HookNameBeforeBuild { | ||||
| 			hooks = append(hooks, New("before_build", path, "")) | ||||
| 		} | ||||
| 		return nil | ||||
| 	}); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return hooks, nil | ||||
| } | ||||
							
								
								
									
										40
									
								
								hook/hook_manager_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								hook/hook_manager_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| package hook | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestHookManager(t *testing.T) { | ||||
| 	t.Run("descovery in default hookdir .hooks", func(t *testing.T) { | ||||
| 		hooks, err := descovery("") | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
|  | ||||
| 		if len(hooks) != 1 { | ||||
| 			t.Fatalf("should have one hook, but got %d", len(hooks)) | ||||
| 		} | ||||
|  | ||||
| 		if hooks[0].Name() != HookNameBeforeBuild { | ||||
| 			t.Fatalf("should be before_build hook, but got %s", hooks[0].Name()) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("descovery in empty hookdir", func(t *testing.T) { | ||||
| 		hooks, err := descovery(filepath.Join(os.TempDir(), ".hooks")) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 		if len(hooks) != 0 { | ||||
| 			t.Fatalf("should get 0 hooks, but got %d", len(hooks)) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("run before_build hook", func(t *testing.T) { | ||||
| 		if err := RunBeforeBuildHook("fixture"); err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										21
									
								
								hook/hook_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								hook/hook_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| package hook | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| func TestHook(t *testing.T) { | ||||
| 	t.Run("text", func(t *testing.T) { | ||||
| 		h := New("before_build", "npm install leftpad", "fixture") | ||||
| 		if err := h.Run("fixture"); err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("script", func(t *testing.T) { | ||||
| 		h := New("before_build", ".hooks/before_build", "fixture") | ||||
| 		if err := h.Run("fixture"); err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
| @@ -86,12 +86,6 @@ func (d *Deployer) Ping(ctx context.Context) error { | ||||
|  | ||||
| // List services | ||||
| func (d *Deployer) List(ctx context.Context, name string) (svcs []types.Service, err error) { | ||||
| 	const task = "listing" | ||||
| 	spinner.Start(task) | ||||
| 	defer func() { | ||||
| 		spinner.Stop(task, err) | ||||
| 	}() | ||||
|  | ||||
| 	// FIXME support remote host | ||||
| 	return d.cli.ListContainer(ctx, name) | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
|  | ||||
| 	containerruntimes "github.com/metrue/fx/container_runtimes" | ||||
| 	"github.com/metrue/fx/context" | ||||
| 	"github.com/metrue/fx/hook" | ||||
| 	"github.com/metrue/fx/packer" | ||||
| 	"github.com/metrue/fx/pkg/spinner" | ||||
| 	"github.com/metrue/fx/types" | ||||
| @@ -54,6 +55,9 @@ func Build(ctx context.Contexter) (err error) { | ||||
| 		if err := packer.Pack(workdir, sources...); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if err := hook.RunBeforeBuildHook(workdir); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	cloudType := ctx.Get("cloud_type").(string) | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import ( | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/metrue/fx/context" | ||||
| 	"github.com/metrue/fx/utils" | ||||
| ) | ||||
|  | ||||
| // Parse parse input | ||||
| @@ -15,13 +16,19 @@ func Parse(action string) func(ctx context.Contexter) (err error) { | ||||
| 		case "up": | ||||
| 			sources := []string{} | ||||
| 			for _, s := range cli.Args() { | ||||
| 				sources = append(sources, s) | ||||
| 				if utils.IsDir(s) || utils.IsRegularFile(s) { | ||||
| 					sources = append(sources, s) | ||||
| 				} else { | ||||
| 					return fmt.Errorf("no such file or directory: %s", s) | ||||
| 				} | ||||
| 			} | ||||
| 			ctx.Set("sources", sources) | ||||
| 			name := cli.String("name") | ||||
| 			ctx.Set("name", name) | ||||
| 			port := cli.Int("port") | ||||
| 			ctx.Set("port", port) | ||||
| 			force := cli.Bool("force") | ||||
| 			ctx.Set("force", force) | ||||
| 		case "down": | ||||
| 			services := cli.Args() | ||||
| 			if len(services) == 0 { | ||||
| @@ -35,6 +42,8 @@ func Parse(action string) func(ctx context.Contexter) (err error) { | ||||
| 		case "list": | ||||
| 			name := cli.Args().First() | ||||
| 			ctx.Set("filter", name) | ||||
| 			format := cli.String("format") | ||||
| 			ctx.Set("format", format) | ||||
| 		case "image_build": | ||||
| 			sources := []string{} | ||||
| 			for _, s := range cli.Args() { | ||||
|   | ||||
							
								
								
									
										49
									
								
								middlewares/parse_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								middlewares/parse_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| package middlewares | ||||
|  | ||||
| import ( | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	"flag" | ||||
|  | ||||
| 	"github.com/golang/mock/gomock" | ||||
| 	mockCtx "github.com/metrue/fx/context/mocks" | ||||
| 	"github.com/urfave/cli" | ||||
| ) | ||||
|  | ||||
| func TestParse(t *testing.T) { | ||||
| 	t.Run("source code not existed", func(t *testing.T) { | ||||
| 		ctrl := gomock.NewController(t) | ||||
| 		defer ctrl.Finish() | ||||
|  | ||||
| 		ctx := mockCtx.NewMockContexter(ctrl) | ||||
| 		argset := flag.NewFlagSet("test", 0) | ||||
| 		cli := cli.NewContext(nil, argset, nil) | ||||
| 		argset.Parse([]string{"this_file_should_not_existed"}) | ||||
| 		ctx.EXPECT().GetCliContext().Return(cli) | ||||
| 		if err := Parse("up")(ctx); err == nil { | ||||
| 			t.Fatal("should got file or directory not existed error") | ||||
| 		} | ||||
| 	}) | ||||
| 	t.Run("source code ready", func(t *testing.T) { | ||||
| 		ctrl := gomock.NewController(t) | ||||
| 		defer ctrl.Finish() | ||||
|  | ||||
| 		ctx := mockCtx.NewMockContexter(ctrl) | ||||
| 		argset := flag.NewFlagSet("test", 0) | ||||
| 		cli := cli.NewContext(nil, argset, nil) | ||||
| 		pwd, err := os.Getwd() | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| 		argset.Parse([]string{pwd}) | ||||
| 		ctx.EXPECT().GetCliContext().Return(cli) | ||||
| 		ctx.EXPECT().Set("sources", []string{pwd}) | ||||
| 		ctx.EXPECT().Set("name", "") | ||||
| 		ctx.EXPECT().Set("port", 0) | ||||
| 		ctx.EXPECT().Set("force", false) | ||||
| 		if err := Parse("up")(ctx); err != nil { | ||||
| 			t.Fatal("should got file or directory not existed error") | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										48
									
								
								packer/a_packer-packr.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								packer/a_packer-packr.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										4
									
								
								packer/images/node/app.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								packer/images/node/app.js
									
									
									
									
										vendored
									
									
								
							| @@ -1,8 +1,12 @@ | ||||
| const Koa = require('koa'); | ||||
| const bodyParser = require('koa-bodyparser'); | ||||
| const cors = require('@koa/cors'); | ||||
| const fx = require('./fx'); | ||||
|  | ||||
| const app = new Koa(); | ||||
| app.use(cors({ | ||||
|   origin: '*', | ||||
| })); | ||||
| app.use(bodyParser()); | ||||
| app.use(fx); | ||||
|  | ||||
|   | ||||
| @@ -70,7 +70,7 @@ func Pack(output string, input ...string) error { | ||||
| 					return err | ||||
| 				} | ||||
|  | ||||
| 				if isHandler(path) { | ||||
| 				if isHandler(path, language) { | ||||
| 					if err := copy.Copy(input[0], path); err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| @@ -84,7 +84,7 @@ func Pack(output string, input ...string) error { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	if !hasFxHandleFile(input...) { | ||||
| 	if !hasFxHandleFile(language, input...) { | ||||
| 		msg := `it requires a fx handle file when input is not a single file function, e.g. | ||||
| fx.go for Golang | ||||
| Fx.java for Java | ||||
| @@ -149,9 +149,21 @@ func merge(dest string, input ...string) error { | ||||
| 					return err | ||||
| 				} | ||||
|  | ||||
| 				if err := copy.Copy(file, dest); err != nil { | ||||
| 				stat, err := os.Stat(path) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				if stat.Mode().IsRegular() { | ||||
| 					destDir := filepath.Join(dest, filepath.Dir(path)) | ||||
| 					if err := utils.EnsureDir(destDir); err != nil { | ||||
| 						return err | ||||
| 					} | ||||
|  | ||||
| 					if err := copy.Copy(file, destDir); err != nil { | ||||
| 						return err | ||||
| 					} | ||||
| 				} | ||||
|  | ||||
| 				return nil | ||||
| 			}); err != nil { | ||||
| 				return err | ||||
|   | ||||
| @@ -23,12 +23,18 @@ var ExtLangMapping = map[string]string{ | ||||
| 	".pl":   "perl", | ||||
| } | ||||
|  | ||||
| func isHandler(name string) bool { | ||||
| func isHandler(name string, lang string) bool { | ||||
| 	basename := filepath.Base(name) | ||||
| 	nameWithoutExt := strings.TrimSuffix(basename, filepath.Ext(basename)) | ||||
| 	return nameWithoutExt == "fx" || | ||||
| 		nameWithoutExt == "Fx" || // Fx is for Java | ||||
| 		nameWithoutExt == "mod" // mod.rs is for Rust | ||||
| 	if ExtLangMapping[filepath.Ext(basename)] != lang { | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return (nameWithoutExt == "fx" || | ||||
| 		// Fx is for Java | ||||
| 		nameWithoutExt == "Fx" || | ||||
| 		// mod.rs is for Rust) | ||||
| 		nameWithoutExt == "mod") | ||||
| } | ||||
|  | ||||
| func langFromFileName(fileName string) (string, error) { | ||||
| @@ -44,10 +50,10 @@ func langFromFileName(fileName string) (string, error) { | ||||
| 	return lang, nil | ||||
| } | ||||
|  | ||||
| func hasFxHandleFile(input ...string) bool { | ||||
| func hasFxHandleFile(lang string, input ...string) bool { | ||||
| 	var handleFile string | ||||
| 	for _, file := range input { | ||||
| 		if utils.IsRegularFile(file) && isHandler(file) { | ||||
| 		if utils.IsRegularFile(file) && isHandler(file, lang) { | ||||
| 			handleFile = file | ||||
| 			break | ||||
| 		} else if utils.IsDir(file) { | ||||
| @@ -56,7 +62,7 @@ func hasFxHandleFile(input ...string) bool { | ||||
| 					return err | ||||
| 				} | ||||
|  | ||||
| 				if utils.IsRegularFile(path) && isHandler(info.Name()) { | ||||
| 				if utils.IsRegularFile(path) && isHandler(info.Name(), lang) { | ||||
| 					handleFile = path | ||||
| 				} | ||||
| 				return nil | ||||
|   | ||||
| @@ -1,27 +0,0 @@ | ||||
| package render | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
|  | ||||
| 	"github.com/metrue/fx/types" | ||||
| 	"github.com/olekukonko/tablewriter" | ||||
| ) | ||||
|  | ||||
| // Table output services as table format | ||||
| func Table(services []types.Service) { | ||||
| 	data := [][]string{} | ||||
| 	for _, s := range services { | ||||
| 		col := []string{ | ||||
| 			s.ID, | ||||
| 			s.Name, | ||||
| 			fmt.Sprintf("%s:%d", s.Host, +s.Port), | ||||
| 		} | ||||
| 		data = append(data, col) | ||||
| 	} | ||||
|  | ||||
| 	table := tablewriter.NewWriter(os.Stdout) | ||||
| 	table.SetHeader([]string{"ID", "Name", "Endpoint"}) | ||||
| 	table.AppendBulk(data) | ||||
| 	table.Render() | ||||
| } | ||||
| @@ -1,19 +0,0 @@ | ||||
| package render | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/metrue/fx/types" | ||||
| ) | ||||
|  | ||||
| func TestTable(t *testing.T) { | ||||
| 	services := []types.Service{ | ||||
| 		types.Service{ | ||||
| 			ID:   "id-1", | ||||
| 			Name: "name-1", | ||||
| 			Host: "127.0.0.1", | ||||
| 			Port: 1000, | ||||
| 		}, | ||||
| 	} | ||||
| 	Table(services) | ||||
| } | ||||
							
								
								
									
										53
									
								
								pkg/renderrer/renderrer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								pkg/renderrer/renderrer.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | ||||
| package renderrer | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/metrue/fx/types" | ||||
| 	"github.com/olekukonko/tablewriter" | ||||
| ) | ||||
|  | ||||
| const formatJSON = "json" | ||||
|  | ||||
| //nolint:unused,varcheck,deadcode | ||||
| const formatTable = "table" | ||||
|  | ||||
| // Render render output with given format | ||||
| func Render(services []types.Service, format string) error { | ||||
| 	if strings.ToLower(format) == formatJSON { | ||||
| 		return toJSON(services) | ||||
| 	} | ||||
| 	return toTable(services) | ||||
| } | ||||
|  | ||||
| func toTable(services []types.Service) error { | ||||
| 	data := [][]string{} | ||||
| 	for _, s := range services { | ||||
| 		col := []string{ | ||||
| 			s.ID, | ||||
| 			s.Name, | ||||
| 			fmt.Sprintf("%s:%d", s.Host, +s.Port), | ||||
| 		} | ||||
| 		data = append(data, col) | ||||
| 	} | ||||
|  | ||||
| 	table := tablewriter.NewWriter(os.Stdout) | ||||
| 	table.SetHeader([]string{"ID", "Name", "Endpoint"}) | ||||
| 	table.AppendBulk(data) | ||||
| 	table.Render() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func toJSON(services []types.Service) error { | ||||
| 	output, err := json.Marshal(services) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if _, err := fmt.Print(string(output)); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
							
								
								
									
										24
									
								
								pkg/renderrer/renderrer_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								pkg/renderrer/renderrer_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| package renderrer | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/metrue/fx/types" | ||||
| ) | ||||
|  | ||||
| func TestRenderrer(t *testing.T) { | ||||
| 	services := []types.Service{ | ||||
| 		types.Service{ | ||||
| 			ID:   "id-1", | ||||
| 			Name: "name-1", | ||||
| 			Host: "127.0.0.1", | ||||
| 			Port: 1000, | ||||
| 		}, | ||||
| 	} | ||||
| 	t.Run("toTable", func(t *testing.T) { | ||||
| 		Render(services, "table") | ||||
| 	}) | ||||
| 	t.Run("toJSON", func(t *testing.T) { | ||||
| 		Render(services, "json") | ||||
| 	}) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user