mirror of
https://github.com/kevin-DL/revel-cmd.git
synced 2026-01-11 18:54:31 +00:00
Merge branch 'develop' into develop
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,3 +1,3 @@
|
||||
.idea/
|
||||
*.iml
|
||||
|
||||
.temp/
|
||||
|
||||
21
.vscode/launch.json
vendored
21
.vscode/launch.json
vendored
@@ -16,12 +16,12 @@
|
||||
"name": "Create new",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"preLaunchTask": "Clean",
|
||||
"preLaunchTask": "Clean-Test-Project",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceRoot}/revel",
|
||||
"args": ["new", "-a", "/tmp/revel/aaa"],
|
||||
"args": ["new", "-v","-a", "${workspaceRoot}/.temp/revel/reveltest", "-p","revel.com/testproject"],
|
||||
"env": {
|
||||
"GOPATH": "/tmp/revel/GOPATH"
|
||||
"GOPATH": "${workspaceRoot}/.temp/revel/GOPATH"
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -30,9 +30,20 @@
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceRoot}/revel",
|
||||
"args": ["run","-v", "-a", "/tmp/revel/aaa"],
|
||||
"args": ["run","-v", "-v","-a", "${workspaceRoot}/.temp/revel/reveltest"],
|
||||
"env": {
|
||||
"GOPATH": "/tmp/revel/GOPATH"
|
||||
"GOPATH": "${workspaceRoot}/.temp/revel/GOPATH"
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Run program Directly",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "auto",
|
||||
"program": "${workspaceRoot}/.temp/revel/reveltest/app/tmp/main.go",
|
||||
"args": ["-port=9000","-importPath=revel.com/testproject/reveltest", "-runMode={\"mode\":\"dev\", \"specialUseFlag\":true,\"packagePathMap\":{\"github.com/revel/modules/static\":\"/home/notzippy/go/pkg/mod/github.com/revel/modules@v1.0.0/static\",\"github.com/revel/modules/testrunner\":\"/home/notzippy/go/pkg/mod/github.com/revel/modules@v1.0.0/testrunner\",\"github.com/revel/revel\":\"/home/notzippy/go/pkg/mod/github.com/revel/revel@v1.0.0\",\"revel.com/testproject/reveltest\":\"/mnt/DevSystem/Work/Workareas/revel/revel3/cmd/.temp/revel/reveltest\"}}"],
|
||||
"env": {
|
||||
"GOPATH": "${workspaceRoot}/.temp/revel/GOPATH"
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
1
.vscode/load.sh
vendored
Executable file
1
.vscode/load.sh
vendored
Executable file
@@ -0,0 +1 @@
|
||||
http_load -rate 5 -seconds 10 load.web
|
||||
2
.vscode/load.web
vendored
Normal file
2
.vscode/load.web
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
http://localhost:9000/
|
||||
http://localhost:9000/miss
|
||||
14
.vscode/tasks.json
vendored
14
.vscode/tasks.json
vendored
@@ -4,9 +4,17 @@
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Clean",
|
||||
"label": "Clean-Test-Project",
|
||||
"type": "shell",
|
||||
"command": "rm -rf /tmp/revel/aaa"
|
||||
}
|
||||
"command": "rm -rf ${workspaceRoot}/.temp/revel/testproject"
|
||||
},
|
||||
{
|
||||
"label": "Update Go Mod",
|
||||
"type": "shell",
|
||||
"options": {
|
||||
"cwd": "${workspaceRoot}/.temp/revel/testproject"
|
||||
},
|
||||
"command": "go mod tidy && go mod edit -replace github.com/revel/revel => ../../../revel"
|
||||
},
|
||||
]
|
||||
}
|
||||
12
go.mod
12
go.mod
@@ -4,20 +4,20 @@ go 1.17
|
||||
|
||||
require (
|
||||
github.com/agtorre/gocolorize v1.0.0
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/go-stack/stack v1.8.0 // indirect
|
||||
github.com/inconshreveable/log15 v0.0.0-20201112154412-8562bdadbbac // indirect
|
||||
github.com/jessevdk/go-flags v1.4.0
|
||||
github.com/mattn/go-colorable v0.1.12
|
||||
github.com/mattn/go-colorable v0.1.8
|
||||
github.com/myesui/uuid v1.0.0 // indirect
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/revel/config v1.0.0
|
||||
github.com/revel/log15 v2.11.20+incompatible
|
||||
github.com/revel/revel v0.21.0
|
||||
github.com/revel/revel v1.0.0
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/tools v0.1.10
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
gopkg.in/stack.v0 v0.0.0-20141108040640-9b43fcefddd0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.0.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||
github.com/inconshreveable/log15 v0.0.0-20201112154412-8562bdadbbac // indirect
|
||||
|
||||
45
go.sum
45
go.sum
@@ -10,27 +10,33 @@ github.com/inconshreveable/log15 v0.0.0-20201112154412-8562bdadbbac h1:n1DqxAo4o
|
||||
github.com/inconshreveable/log15 v0.0.0-20201112154412-8562bdadbbac/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o=
|
||||
github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGARJA=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/myesui/uuid v1.0.0 h1:xCBmH4l5KuvLYc5L7AS7SZg9/jKdIFubM7OVoLqaQUI=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/myesui/uuid v1.0.0/go.mod h1:2CDfNgU0LR8mIdO8vdWd8i9gWWxLlcoIGGpSNgafq84=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/revel/config v0.21.0 h1:Bw4iXLGAuD/Di2HEhPSOyDywrTlFIXUMbds91lXTtTU=
|
||||
github.com/revel/config v0.21.0/go.mod h1:GT4a9px5kDGRqLizcw/md0QFErrhen76toz4qS3oIoI=
|
||||
github.com/revel/config v1.0.0 h1:UAzLPQ+x9nJeP6a+H93G+AKEosg3OO2oVLBXK9oSN2U=
|
||||
github.com/revel/config v1.0.0/go.mod h1:GT4a9px5kDGRqLizcw/md0QFErrhen76toz4qS3oIoI=
|
||||
github.com/revel/log15 v2.11.20+incompatible h1:JkA4tbwIo/UGEMumY50zndKq816RQW3LQ0wIpRc+32U=
|
||||
github.com/revel/log15 v2.11.20+incompatible/go.mod h1:l0WmLRs+IM1hBl4noJiBc2tZQiOgZyXzS1mdmFt+5Gc=
|
||||
github.com/revel/modules v0.21.0/go.mod h1:UBlNmO9VGZo4j6Ptn2uC/26Iclefuic+V40jYRPBxQE=
|
||||
github.com/revel/pathtree v0.0.0-20140121041023-41257a1839e9 h1:/d6kfjzjyx19ieWqMOXHSTLFuRxLOH15ZubtcAXExKw=
|
||||
github.com/revel/pathtree v0.0.0-20140121041023-41257a1839e9/go.mod h1:TmlwoRLDvgRjoTe6rbsxIaka/CulzYrgfef7iNJcEWY=
|
||||
github.com/revel/revel v0.21.0 h1:E6kDJmpJSDb0F8XwbyG5h4ayzpZ+8Wcw2IiPZW/2qSc=
|
||||
github.com/revel/revel v0.21.0/go.mod h1:VZWJnHjpDEtuGUuZJ2NO42XryitrtwsdVaJxfDeo5yc=
|
||||
github.com/revel/revel v1.0.0 h1:BsPFnKuuzXEkPtrjdjZHiDcvDmbBiBQvh7Z5c6kLb/Y=
|
||||
github.com/revel/revel v1.0.0/go.mod h1:VZWJnHjpDEtuGUuZJ2NO42XryitrtwsdVaJxfDeo5yc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk=
|
||||
github.com/twinj/uuid v1.0.0/go.mod h1:mMgcE1RHFUFqe5AfiwlINXisXfDGro23fWdPUfOMjRY=
|
||||
github.com/xeonx/timeago v1.0.0-rc4 h1:9rRzv48GlJC0vm+iBpLcWAr8YbETyN9Vij+7h2ammz4=
|
||||
@@ -41,24 +47,26 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5 h1:WQ8q63x+f/zpC8Ac1s9wLElVoHhm32p6tudrU72n1QA=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 h1:5B6i6EAiSYyejWfvc5Rc9BbI3rzIsrrXfAQBWnYfn+w=
|
||||
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 h1:id054HUawV2/6IGm2IV8KZQjqtwAOo2CYlOToYqa0d0=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20=
|
||||
@@ -71,6 +79,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo=
|
||||
gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/stack.v0 v0.0.0-20141108040640-9b43fcefddd0 h1:lMH45EKqD8Nf6LwoF+43YOKjOAEEHQRVgDyG8RCV4MU=
|
||||
|
||||
@@ -6,18 +6,28 @@ package harness
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/revel/cmd/model"
|
||||
"github.com/revel/cmd/utils"
|
||||
)
|
||||
|
||||
// Error is used for constant errors.
|
||||
type Error string
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e Error) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
const ErrTimedOut Error = "app timed out"
|
||||
|
||||
// App contains the configuration for running a Revel app. (Not for the app itself)
|
||||
// Its only purpose is constructing the command to execute.
|
||||
type App struct {
|
||||
@@ -64,6 +74,7 @@ func NewAppCmd(binPath string, port int, runMode string, paths *model.RevelConta
|
||||
func (cmd AppCmd) Start(c *model.CommandConfig) error {
|
||||
listeningWriter := &startupListeningWriter{os.Stdout, make(chan bool), c, &bytes.Buffer{}}
|
||||
cmd.Stdout = listeningWriter
|
||||
cmd.Stderr = listeningWriter
|
||||
utils.CmdInit(cmd.Cmd, !c.Vendored, c.AppPath)
|
||||
utils.Logger.Info("Exec app:", "path", cmd.Path, "args", cmd.Args, "dir", cmd.Dir, "env", cmd.Env)
|
||||
if err := cmd.Cmd.Start(); err != nil {
|
||||
@@ -74,15 +85,17 @@ func (cmd AppCmd) Start(c *model.CommandConfig) error {
|
||||
case exitState := <-cmd.waitChan():
|
||||
fmt.Println("Startup failure view previous messages, \n Proxy is listening :", c.Run.Port)
|
||||
err := utils.NewError("", "Revel Run Error", "starting your application there was an exception. See terminal output, "+exitState, "")
|
||||
atomic.SwapInt32(&startupError, 1)
|
||||
// TODO pretiffy command line output
|
||||
// err.MetaError = listeningWriter.getLastOutput()
|
||||
err.Stack = listeningWriter.buffer.String()
|
||||
return err
|
||||
|
||||
case <-time.After(60 * time.Second):
|
||||
println("Revel proxy is listening, point your browser to :", c.Run.Port)
|
||||
utils.Logger.Error("Killing revel server process did not respond after wait timeout.", "processid", cmd.Process.Pid)
|
||||
cmd.Kill()
|
||||
return errors.New("revel/harness: app timed out")
|
||||
|
||||
return fmt.Errorf("revel/harness: %w", ErrTimedOut)
|
||||
|
||||
case <-listeningWriter.notifyReady:
|
||||
println("Revel proxy is listening, point your browser to :", c.Run.Port)
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
var importErrorPattern = regexp.MustCompile("cannot find package \"([^\"]+)\"")
|
||||
var importErrorPattern2 = regexp.MustCompile("no required module provides package ([^;]+)+")
|
||||
var addPackagePattern = regexp.MustCompile(`to add:\n\tgo get (.*)\n`)
|
||||
|
||||
type ByString []*model.TypeInfo
|
||||
|
||||
@@ -214,6 +215,10 @@ func Build(c *model.CommandConfig, paths *model.RevelContainer) (_ *App, err err
|
||||
if matches == nil {
|
||||
matches = importErrorPattern2.FindAllStringSubmatch(stOutput, -1)
|
||||
}
|
||||
if matches == nil {
|
||||
matches = addPackagePattern.FindAllStringSubmatch(stOutput, -1)
|
||||
|
||||
}
|
||||
utils.Logger.Info("Build failed checking for missing imports", "message", stOutput, "missing_imports", len(matches))
|
||||
if matches == nil {
|
||||
utils.Logger.Info("Build failed no missing imports", "message", stOutput)
|
||||
|
||||
@@ -16,6 +16,7 @@ package harness
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"html/template"
|
||||
@@ -42,6 +43,8 @@ var (
|
||||
doNotWatch = []string{"tmp", "views", "routes"}
|
||||
|
||||
lastRequestHadError int32
|
||||
startupError int32
|
||||
startupErrorText error
|
||||
)
|
||||
|
||||
// Harness reverse proxies requests to the application server.
|
||||
@@ -69,6 +72,7 @@ func (h *Harness) renderError(iw http.ResponseWriter, ir *http.Request, err erro
|
||||
if err == nil {
|
||||
utils.Logger.Panic("Caller passed in a nil error")
|
||||
}
|
||||
|
||||
templateSet := template.New("__root__")
|
||||
seekViewOnPath := func(view string) (path string) {
|
||||
path = filepath.Join(h.paths.ViewsPath, "errors", view)
|
||||
@@ -86,26 +90,27 @@ func (h *Harness) renderError(iw http.ResponseWriter, ir *http.Request, err erro
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
target := []string{seekViewOnPath("500.html"), seekViewOnPath("500-dev.html")}
|
||||
if !utils.Exists(target[0]) {
|
||||
fmt.Fprintf(iw, "Target template not found not found %s<br />\n", target[0])
|
||||
fmt.Fprintf(iw, "An error occurred %s", err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
var revelError *utils.SourceError
|
||||
switch e := err.(type) {
|
||||
case *utils.SourceError:
|
||||
revelError = e
|
||||
case error:
|
||||
|
||||
if !errors.As(err, &revelError) {
|
||||
revelError = &utils.SourceError{
|
||||
Title: "Server Error",
|
||||
Description: e.Error(),
|
||||
Description: err.Error(),
|
||||
}
|
||||
}
|
||||
|
||||
if revelError == nil {
|
||||
panic("no error provided")
|
||||
}
|
||||
|
||||
viewArgs := map[string]interface{}{}
|
||||
viewArgs["RunMode"] = h.paths.RunMode
|
||||
viewArgs["DevMode"] = h.paths.DevMode
|
||||
@@ -204,8 +209,8 @@ func NewHarness(c *model.CommandConfig, paths *model.RevelContainer, runMode str
|
||||
// Refresh method rebuilds the Revel application and run it on the given port.
|
||||
// called by the watcher.
|
||||
func (h *Harness) Refresh() (err *utils.SourceError) {
|
||||
t := time.Now()
|
||||
fmt.Println("Changed detected, recompiling")
|
||||
t := time.Now();
|
||||
fmt.Println("Change detected, recompiling")
|
||||
err = h.refresh()
|
||||
if err != nil && !h.ranOnce && h.useProxy {
|
||||
addr := fmt.Sprintf("%s:%d", h.paths.HTTPAddr, h.paths.HTTPPort)
|
||||
@@ -236,32 +241,42 @@ func (h *Harness) refresh() (err *utils.SourceError) {
|
||||
h.app, newErr = Build(h.config, h.paths)
|
||||
if newErr != nil {
|
||||
utils.Logger.Error("Build detected an error", "error", newErr)
|
||||
if castErr, ok := newErr.(*utils.SourceError); ok {
|
||||
|
||||
var castErr *utils.SourceError
|
||||
if errors.As(newErr, &castErr) {
|
||||
return castErr
|
||||
}
|
||||
|
||||
err = &utils.SourceError{
|
||||
Title: "App failed to start up",
|
||||
Description: err.Error(),
|
||||
Description: newErr.Error(),
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if h.useProxy {
|
||||
h.app.Port = h.port
|
||||
runMode := h.runMode
|
||||
|
||||
if !h.config.HistoricMode {
|
||||
// Recalulate run mode based on the config
|
||||
var paths []byte
|
||||
if len(h.app.PackagePathMap) > 0 {
|
||||
paths, _ = json.Marshal(h.app.PackagePathMap)
|
||||
}
|
||||
runMode = fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v,"packagePathMap":%s}`, h.app.Paths.RunMode, h.config.Verbose, string(paths))
|
||||
|
||||
runMode = fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v,"packagePathMap":%s}`, h.app.Paths.RunMode, h.config.Verbose[0], string(paths))
|
||||
}
|
||||
|
||||
if err2 := h.app.Cmd(runMode).Start(h.config); err2 != nil {
|
||||
utils.Logger.Error("Could not start application", "error", err2)
|
||||
if err, k := err2.(*utils.SourceError); k {
|
||||
|
||||
var serr *utils.SourceError
|
||||
if errors.As(err2, &serr) {
|
||||
return err
|
||||
}
|
||||
|
||||
return &utils.SourceError{
|
||||
Title: "App failed to start up",
|
||||
Description: err2.Error(),
|
||||
@@ -297,8 +312,12 @@ func (h *Harness) Run() {
|
||||
paths = append(paths, h.paths.CodePaths...)
|
||||
h.watcher = watcher.NewWatcher(h.paths, false)
|
||||
h.watcher.Listen(h, paths...)
|
||||
go h.Refresh()
|
||||
// h.watcher.Notify()
|
||||
|
||||
go func() {
|
||||
if err := h.Refresh(); err != nil {
|
||||
utils.Logger.Error("Failed to refresh", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if h.useProxy {
|
||||
go func() {
|
||||
|
||||
@@ -39,8 +39,11 @@ func (h *CompositeMultiHandler) Log(r *Record) (err error) {
|
||||
|
||||
// Embed the caller function in the context
|
||||
if handler != nil {
|
||||
handler.Log(r)
|
||||
if err := handler.Log(r); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -91,8 +94,8 @@ func (h *CompositeMultiHandler) SetHandlers(handler LogHandler, options *LogOpti
|
||||
}
|
||||
}
|
||||
|
||||
func (h *CompositeMultiHandler) SetJson(writer io.Writer, options *LogOptions) {
|
||||
handler := CallerFileHandler(StreamHandler(writer, JsonFormatEx(
|
||||
func (h *CompositeMultiHandler) SetJSON(writer io.Writer, options *LogOptions) {
|
||||
handler := CallerFileHandler(StreamHandler(writer, JSONFormatEx(
|
||||
options.GetBoolDefault("pretty", false),
|
||||
options.GetBoolDefault("lineSeparated", true),
|
||||
)))
|
||||
@@ -103,7 +106,7 @@ func (h *CompositeMultiHandler) SetJson(writer io.Writer, options *LogOptions) {
|
||||
}
|
||||
|
||||
// Use built in rolling function.
|
||||
func (h *CompositeMultiHandler) SetJsonFile(filePath string, options *LogOptions) {
|
||||
func (h *CompositeMultiHandler) SetJSONFile(filePath string, options *LogOptions) {
|
||||
writer := &lumberjack.Logger{
|
||||
Filename: filePath,
|
||||
MaxSize: options.GetIntDefault("maxSizeMB", 1024), // megabytes
|
||||
@@ -111,7 +114,7 @@ func (h *CompositeMultiHandler) SetJsonFile(filePath string, options *LogOptions
|
||||
MaxBackups: options.GetIntDefault("maxBackups", 7),
|
||||
Compress: options.GetBoolDefault("compress", true),
|
||||
}
|
||||
h.SetJson(writer, options)
|
||||
h.SetJSON(writer, options)
|
||||
}
|
||||
|
||||
func (h *CompositeMultiHandler) SetTerminal(writer io.Writer, options *LogOptions) {
|
||||
|
||||
@@ -50,6 +50,7 @@ func CallerFileHandler(h LogHandler) LogHandler {
|
||||
// Adds in a context called `caller` to the record (contains file name and line number like `foo.go:12`)
|
||||
// Uses the `log15.CallerFuncHandler` to perform this task.
|
||||
func CallerFuncHandler(h LogHandler) LogHandler {
|
||||
// TODO: infinite recursion
|
||||
return CallerFuncHandler(h)
|
||||
}
|
||||
|
||||
@@ -137,8 +138,9 @@ func NotMatchHandler(key string, value interface{}, h LogHandler) LogHandler {
|
||||
func MultiHandler(hs ...LogHandler) LogHandler {
|
||||
return FuncHandler(func(r *Record) error {
|
||||
for _, h := range hs {
|
||||
// what to do about failures?
|
||||
h.Log(r)
|
||||
if err := h.Log(r); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@@ -189,6 +191,7 @@ func (ll *ListLogHandler) Log(r *Record) (err error) {
|
||||
handler.Log(r)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
func InitializeFromConfig(basePath string, config *config.Context) (c *CompositeMultiHandler) {
|
||||
// If running in test mode suppress anything that is not an error
|
||||
if config != nil && config.BoolDefault(TEST_MODE_FLAG, false) {
|
||||
if config != nil && config.BoolDefault(TestModeFlag, false) {
|
||||
// Preconfigure all the options
|
||||
config.SetOption("log.info.output", "none")
|
||||
config.SetOption("log.debug.output", "none")
|
||||
@@ -26,14 +26,14 @@ func InitializeFromConfig(basePath string, config *config.Context) (c *Composite
|
||||
c, _ = NewCompositeMultiHandler()
|
||||
|
||||
// Filters are assigned first, non filtered items override filters
|
||||
if config != nil && !config.BoolDefault(TEST_MODE_FLAG, false) {
|
||||
if config != nil && !config.BoolDefault(TestModeFlag, false) {
|
||||
initAllLog(c, basePath, config)
|
||||
}
|
||||
initLogLevels(c, basePath, config)
|
||||
if c.CriticalHandler == nil && c.ErrorHandler != nil {
|
||||
c.CriticalHandler = c.ErrorHandler
|
||||
}
|
||||
if config != nil && !config.BoolDefault(TEST_MODE_FLAG, false) {
|
||||
if config != nil && !config.BoolDefault(TestModeFlag, false) {
|
||||
initFilterLog(c, basePath, config)
|
||||
if c.CriticalHandler == nil && c.ErrorHandler != nil {
|
||||
c.CriticalHandler = c.ErrorHandler
|
||||
@@ -47,7 +47,7 @@ func InitializeFromConfig(basePath string, config *config.Context) (c *Composite
|
||||
// Init the log.all configuration options.
|
||||
func initAllLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
|
||||
if config != nil {
|
||||
extraLogFlag := config.BoolDefault(SPECIAL_USE_FLAG, false)
|
||||
extraLogFlag := config.BoolDefault(SpecialUseFlag, false)
|
||||
if output, found := config.String("log.all.output"); found {
|
||||
// Set all output for the specified handler
|
||||
if extraLogFlag {
|
||||
@@ -63,7 +63,7 @@ func initAllLog(c *CompositeMultiHandler, basePath string, config *config.Contex
|
||||
// log.error.filter ....
|
||||
func initFilterLog(c *CompositeMultiHandler, basePath string, config *config.Context) {
|
||||
if config != nil {
|
||||
extraLogFlag := config.BoolDefault(SPECIAL_USE_FLAG, false)
|
||||
extraLogFlag := config.BoolDefault(SpecialUseFlag, false)
|
||||
|
||||
for _, logFilter := range logFilterList {
|
||||
// Init for all filters
|
||||
@@ -102,7 +102,7 @@ func initLogLevels(c *CompositeMultiHandler, basePath string, config *config.Con
|
||||
"trace", // TODO trace is deprecated
|
||||
} {
|
||||
if config != nil {
|
||||
extraLogFlag := config.BoolDefault(SPECIAL_USE_FLAG, false)
|
||||
extraLogFlag := config.BoolDefault(SpecialUseFlag, false)
|
||||
output, found := config.String("log." + name + ".output")
|
||||
if found {
|
||||
if extraLogFlag {
|
||||
@@ -178,7 +178,7 @@ func initHandlerFor(c *CompositeMultiHandler, output, basePath string, options *
|
||||
}
|
||||
|
||||
if strings.HasSuffix(output, "json") {
|
||||
c.SetJsonFile(output, options)
|
||||
c.SetJSONFile(output, options)
|
||||
} else {
|
||||
// Override defaults for a terminal file
|
||||
options.SetExtendedOptions("noColor", true)
|
||||
|
||||
@@ -59,7 +59,7 @@ var singleCases = []testData{
|
||||
func TestSingleCases(t *testing.T) {
|
||||
rootLog := logger.New()
|
||||
for _, testCase := range singleCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
testCase.validate(t)
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ var filterCases = []testData{
|
||||
func TestFilterCases(t *testing.T) {
|
||||
rootLog := logger.New("module", "app")
|
||||
for _, testCase := range filterCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
testCase.validate(t)
|
||||
}
|
||||
}
|
||||
@@ -169,7 +169,7 @@ var nfilterCases = []testData{
|
||||
func TestNotFilterCases(t *testing.T) {
|
||||
rootLog := logger.New("module", "app")
|
||||
for _, testCase := range nfilterCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
testCase.validate(t)
|
||||
}
|
||||
}
|
||||
@@ -186,7 +186,7 @@ var offCases = []testData{
|
||||
func TestOffCases(t *testing.T) {
|
||||
rootLog := logger.New("module", "app")
|
||||
for _, testCase := range offCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
testCase.validate(t)
|
||||
}
|
||||
}
|
||||
@@ -203,7 +203,7 @@ var duplicateCases = []testData{
|
||||
func TestDuplicateCases(t *testing.T) {
|
||||
rootLog := logger.New("module", "app")
|
||||
for _, testCase := range duplicateCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
testCase.validate(t)
|
||||
}
|
||||
}
|
||||
@@ -232,7 +232,7 @@ var contradictCases = []testData{
|
||||
func TestContradictCases(t *testing.T) {
|
||||
rootLog := logger.New("module", "app")
|
||||
for _, testCase := range contradictCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
testCase.validate(t)
|
||||
}
|
||||
}
|
||||
@@ -253,12 +253,12 @@ var allCases = []testData{
|
||||
func TestAllCases(t *testing.T) {
|
||||
rootLog := logger.New("module", "app")
|
||||
for i, testCase := range allCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
allCases[i] = testCase
|
||||
}
|
||||
rootLog = logger.New()
|
||||
for i, testCase := range allCases {
|
||||
testCase.logTest(rootLog, t)
|
||||
testCase.logTest(t, rootLog)
|
||||
allCases[i] = testCase
|
||||
}
|
||||
for _, testCase := range allCases {
|
||||
@@ -284,7 +284,9 @@ func (c *testCounter) Log(r *logger.Record) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (td *testData) logTest(rootLog logger.MultiLogger, t *testing.T) {
|
||||
func (td *testData) logTest(t *testing.T, rootLog logger.MultiLogger) {
|
||||
t.Helper()
|
||||
|
||||
if td.tc == nil {
|
||||
td.tc = &testCounter{}
|
||||
counterInit(td.tc)
|
||||
@@ -317,6 +319,8 @@ func (td *testData) runLogTest(log logger.MultiLogger) {
|
||||
}
|
||||
|
||||
func (td *testData) validate(t *testing.T) {
|
||||
t.Helper()
|
||||
|
||||
t.Logf("Test %#v expected %#v", td.tc, td.result)
|
||||
assert.Equal(t, td.result.debug, td.tc.debug, "Debug failed "+strings.Join(td.config, " "))
|
||||
assert.Equal(t, td.result.info, td.tc.info, "Info failed "+strings.Join(td.config, " "))
|
||||
|
||||
@@ -197,10 +197,10 @@ func escapeString(s string) string {
|
||||
return ret
|
||||
}
|
||||
|
||||
// JsonFormatEx formats log records as JSON objects. If pretty is true,
|
||||
// JSONFormatEx formats log records as JSON objects. If pretty is true,
|
||||
// records will be pretty-printed. If lineSeparated is true, records
|
||||
// will be logged with a new line between each record.
|
||||
func JsonFormatEx(pretty, lineSeparated bool) LogFormat {
|
||||
func JSONFormatEx(pretty, lineSeparated bool) LogFormat {
|
||||
jsonMarshal := json.Marshal
|
||||
if pretty {
|
||||
jsonMarshal = func(v interface{}) ([]byte, error) {
|
||||
|
||||
@@ -20,9 +20,9 @@ var (
|
||||
|
||||
const (
|
||||
// The test mode flag overrides the default log level and shows only errors.
|
||||
TEST_MODE_FLAG = "testModeFlag"
|
||||
TestModeFlag = "testModeFlag"
|
||||
// The special use flag enables showing messages when the logger is setup.
|
||||
SPECIAL_USE_FLAG = "specialUseFlag"
|
||||
SpecialUseFlag = "specialUseFlag"
|
||||
)
|
||||
|
||||
// Returns the logger for the name.
|
||||
|
||||
@@ -9,6 +9,20 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Error is used for constant errors.
|
||||
type Error string
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e Error) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
const (
|
||||
ErrNotFunc Error = "not a function"
|
||||
ErrTakesArgs Error = "takes arguments"
|
||||
ErrNoReturn Error = "no return value"
|
||||
)
|
||||
|
||||
// Function handler wraps the declared function and returns the handler for it.
|
||||
func FuncHandler(fn func(r *Record) error) LogHandler {
|
||||
return funcHandler(fn)
|
||||
@@ -71,15 +85,15 @@ func evaluateLazy(lz Lazy) (interface{}, error) {
|
||||
t := reflect.TypeOf(lz.Fn)
|
||||
|
||||
if t.Kind() != reflect.Func {
|
||||
return nil, fmt.Errorf("INVALID_LAZY, not func: %+v", lz.Fn)
|
||||
return nil, fmt.Errorf("%w %+v", ErrNotFunc, lz.Fn)
|
||||
}
|
||||
|
||||
if t.NumIn() > 0 {
|
||||
return nil, fmt.Errorf("INVALID_LAZY, func takes args: %+v", lz.Fn)
|
||||
return nil, fmt.Errorf("%w %+v", ErrTakesArgs, lz.Fn)
|
||||
}
|
||||
|
||||
if t.NumOut() == 0 {
|
||||
return nil, fmt.Errorf("INVALID_LAZY, no func return val: %+v", lz.Fn)
|
||||
return nil, fmt.Errorf("%w %+v", ErrNoReturn, lz.Fn)
|
||||
}
|
||||
|
||||
value := reflect.ValueOf(lz.Fn)
|
||||
|
||||
@@ -28,6 +28,11 @@ const (
|
||||
VERSION
|
||||
)
|
||||
|
||||
const (
|
||||
ErrImportInvalid Error = "invalid import path, working dir is in GOPATH root"
|
||||
ErrUnableToImport Error = "unable to determine import path from"
|
||||
)
|
||||
|
||||
type (
|
||||
// The Revel command type.
|
||||
COMMAND int
|
||||
@@ -110,7 +115,7 @@ func (c *CommandConfig) UpdateImportPath() error {
|
||||
importPath = importPath[4:]
|
||||
} else if importPath == "src" {
|
||||
if c.Index != VERSION {
|
||||
return fmt.Errorf("invalid import path, working dir is in GOPATH root")
|
||||
return ErrImportInvalid
|
||||
}
|
||||
importPath = ""
|
||||
}
|
||||
@@ -122,7 +127,10 @@ func (c *CommandConfig) UpdateImportPath() error {
|
||||
|
||||
c.ImportPath = importPath
|
||||
// We need the source root determined at this point to check the setversions
|
||||
c.initAppFolder()
|
||||
if err := c.initAppFolder(); err != nil {
|
||||
utils.Logger.Error("Error initing app folder", "error", err)
|
||||
}
|
||||
|
||||
utils.Logger.Info("Returned import path", "path", importPath)
|
||||
if required && c.Index != NEW {
|
||||
if err := c.SetVersions(); err != nil {
|
||||
@@ -138,7 +146,7 @@ func (c *CommandConfig) UpdateImportPath() error {
|
||||
return nil
|
||||
}
|
||||
if len(importPath) == 0 {
|
||||
return fmt.Errorf("unable to determine import path from : %s", importPath)
|
||||
return fmt.Errorf("%w: %s", ErrUnableToImport, importPath)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -165,8 +173,6 @@ func (c *CommandConfig) initAppFolder() (err error) {
|
||||
} else {
|
||||
appFolder = filepath.Join(wd, appFolder)
|
||||
}
|
||||
} else if strings.Contains(appFolder, ".") {
|
||||
appFolder = filepath.Join(wd, filepath.Base(c.ImportPath))
|
||||
} else if !filepath.IsAbs(appFolder) {
|
||||
appFolder = filepath.Join(wd, appFolder)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
@@ -13,6 +12,24 @@ import (
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// Error is used for constant errors.
|
||||
type Error string
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e Error) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
const (
|
||||
ErrNoApp Error = "no app found at path"
|
||||
ErrNoConfig Error = "no config found at path"
|
||||
ErrNotFound Error = "not found"
|
||||
ErrMissingCert Error = "no http.sslcert provided"
|
||||
ErrMissingKey Error = "no http.sslkey provided"
|
||||
ErrNoFiles Error = "no files found in import path"
|
||||
ErrNoPackages Error = "no packages found for import"
|
||||
)
|
||||
|
||||
type (
|
||||
// The container object for describing all Revels variables.
|
||||
RevelContainer struct {
|
||||
@@ -123,10 +140,10 @@ func NewRevelPaths(mode, importPath, appSrcPath string, callback RevelCallback)
|
||||
|
||||
// Sanity check , ensure app and conf paths exist
|
||||
if !utils.DirExists(rp.AppPath) {
|
||||
return rp, fmt.Errorf("no application found at path %s", rp.AppPath)
|
||||
return rp, fmt.Errorf("%w: %s", ErrNoApp, rp.AppPath)
|
||||
}
|
||||
if !utils.DirExists(filepath.Join(rp.BasePath, "conf")) {
|
||||
return rp, fmt.Errorf("no configuration found at path %s", filepath.Join(rp.BasePath, "conf"))
|
||||
return rp, fmt.Errorf("%w: %s", ErrNoConfig, filepath.Join(rp.BasePath, "conf"))
|
||||
}
|
||||
|
||||
rp.ViewsPath = filepath.Join(rp.AppPath, "views")
|
||||
@@ -150,7 +167,7 @@ func NewRevelPaths(mode, importPath, appSrcPath string, callback RevelCallback)
|
||||
|
||||
rp.Config, err = config.LoadContext("app.conf", rp.ConfPaths)
|
||||
if err != nil {
|
||||
return rp, fmt.Errorf("unable to load configuration file %s", err)
|
||||
return rp, fmt.Errorf("unable to load configuration file %w", err)
|
||||
}
|
||||
|
||||
// Ensure that the selected runmode appears in app.conf.
|
||||
@@ -159,7 +176,7 @@ func NewRevelPaths(mode, importPath, appSrcPath string, callback RevelCallback)
|
||||
mode = config.DefaultSection
|
||||
}
|
||||
if !rp.Config.HasSection(mode) {
|
||||
return rp, fmt.Errorf("app.conf: No mode found: %s %s", "run-mode", mode)
|
||||
return rp, fmt.Errorf("app.conf: %w %s %s", ErrNotFound, "run-mode", mode)
|
||||
}
|
||||
rp.Config.SetSection(mode)
|
||||
|
||||
@@ -172,13 +189,14 @@ func NewRevelPaths(mode, importPath, appSrcPath string, callback RevelCallback)
|
||||
rp.HTTPSslKey = rp.Config.StringDefault("http.sslkey", "")
|
||||
if rp.HTTPSsl {
|
||||
if rp.HTTPSslCert == "" {
|
||||
return rp, errors.New("no http.sslcert provided")
|
||||
return rp, ErrMissingCert
|
||||
}
|
||||
|
||||
if rp.HTTPSslKey == "" {
|
||||
return rp, errors.New("no http.sslkey provided")
|
||||
return rp, ErrMissingKey
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
rp.AppName = rp.Config.StringDefault("app.name", "(not set)")
|
||||
rp.AppRoot = rp.Config.StringDefault("app.root", "")
|
||||
rp.CookiePrefix = rp.Config.StringDefault("cookie.prefix", "REVEL")
|
||||
@@ -201,7 +219,7 @@ func NewRevelPaths(mode, importPath, appSrcPath string, callback RevelCallback)
|
||||
func (rp *RevelContainer) LoadMimeConfig() (err error) {
|
||||
rp.MimeConfig, err = config.LoadContext("mime-types.conf", rp.ConfPaths)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load mime type config: %s %s", "error", err)
|
||||
return fmt.Errorf("failed to load mime type config: %s %w", "error", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -226,10 +244,14 @@ func (rp *RevelContainer) loadModules(callback RevelCallback) (err error) {
|
||||
modulePath, err := rp.ResolveImportPath(moduleImportPath)
|
||||
if err != nil {
|
||||
utils.Logger.Info("Missing module ", "module_import_path", moduleImportPath, "error", err)
|
||||
callback.PackageResolver(moduleImportPath)
|
||||
|
||||
if err := callback.PackageResolver(moduleImportPath); err != nil {
|
||||
return fmt.Errorf("failed to resolve package %w", err)
|
||||
}
|
||||
|
||||
modulePath, err = rp.ResolveImportPath(moduleImportPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to load module. Import of path failed %s:%s %s:%s ", "modulePath", moduleImportPath, "error", err)
|
||||
return fmt.Errorf("failed to load module. Import of path failed %s:%s %s:%w ", "modulePath", moduleImportPath, "error", err)
|
||||
}
|
||||
}
|
||||
// Drop anything between module.???.<name of module>
|
||||
@@ -280,7 +302,7 @@ func (rp *RevelContainer) ResolveImportPath(importPath string) (string, error) {
|
||||
config.Env = utils.ReducedEnv(false)
|
||||
pkgs, err := packages.Load(config, importPath)
|
||||
if len(pkgs) == 0 {
|
||||
return "", errors.New("No packages found for import " + importPath + " using app path " + rp.AppPath)
|
||||
return "", fmt.Errorf("%w %s using app path %s", ErrNoPackages, importPath, rp.AppPath)
|
||||
}
|
||||
// modPkg, err := build.Import(importPath, rp.AppPath, build.FindOnly)
|
||||
if err != nil {
|
||||
@@ -289,5 +311,5 @@ func (rp *RevelContainer) ResolveImportPath(importPath string) (string, error) {
|
||||
if len(pkgs[0].GoFiles) > 0 {
|
||||
return filepath.Dir(pkgs[0].GoFiles[0]), nil
|
||||
}
|
||||
return pkgs[0].PkgPath, errors.New("No files found in import path " + importPath)
|
||||
return pkgs[0].PkgPath, fmt.Errorf("%w: %s", ErrNoFiles, importPath)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ func NewTypeExprFromData(expr, pkgName string, pkgIndex int, valid bool) TypeExp
|
||||
|
||||
// NewTypeExpr returns the syntactic expression for referencing this type in Go.
|
||||
func NewTypeExprFromAst(pkgName string, expr ast.Expr) TypeExpr {
|
||||
error := ""
|
||||
err := ""
|
||||
switch t := expr.(type) {
|
||||
case *ast.Ident:
|
||||
if IsBuiltinType(t.Name) {
|
||||
@@ -41,14 +41,14 @@ func NewTypeExprFromAst(pkgName string, expr ast.Expr) TypeExpr {
|
||||
e := NewTypeExprFromAst(pkgName, t.Value)
|
||||
return NewTypeExprFromData("map["+identKey.Name+"]"+e.Expr, e.PkgName, e.pkgIndex+len("map["+identKey.Name+"]"), e.Valid)
|
||||
}
|
||||
error = fmt.Sprintf("Failed to generate name for Map field :%v. Make sure the field name is valid.", t.Key)
|
||||
err = fmt.Sprintf("Failed to generate name for Map field :%v. Make sure the field name is valid.", t.Key)
|
||||
case *ast.Ellipsis:
|
||||
e := NewTypeExprFromAst(pkgName, t.Elt)
|
||||
return NewTypeExprFromData("[]"+e.Expr, e.PkgName, e.pkgIndex+2, e.Valid)
|
||||
default:
|
||||
error = fmt.Sprintf("Failed to generate name for field: %v Package: %v. Make sure the field name is valid.", expr, pkgName)
|
||||
err = fmt.Sprintf("Failed to generate name for field: %v Package: %v. Make sure the field name is valid.", expr, pkgName)
|
||||
}
|
||||
return NewTypeExprFromData(error, "", 0, false)
|
||||
return NewTypeExprFromData(err, "", 0, false)
|
||||
}
|
||||
|
||||
// TypeName returns the fully-qualified type name for this expression.
|
||||
@@ -61,7 +61,7 @@ func (e TypeExpr) TypeName(pkgOverride string) string {
|
||||
return e.Expr[:e.pkgIndex] + pkgName + "." + e.Expr[e.pkgIndex:]
|
||||
}
|
||||
|
||||
var builtInTypes = map[string]struct{}{
|
||||
var builtInTypes = map[string]struct{}{ //nolint:gochecknoglobals
|
||||
"bool": {},
|
||||
"byte": {},
|
||||
"complex128": {},
|
||||
|
||||
@@ -8,6 +8,7 @@ package parser
|
||||
// It catalogs the controllers, their methods, and their arguments.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/scanner"
|
||||
@@ -83,7 +84,8 @@ func (pc *processContainer) processPath(path string, info os.FileInfo, err error
|
||||
0)
|
||||
|
||||
if err != nil {
|
||||
if errList, ok := err.(scanner.ErrorList); ok {
|
||||
var errList scanner.ErrorList
|
||||
if errors.As(err, &errList) {
|
||||
pos := errList[0].Pos
|
||||
newError := &utils.SourceError{
|
||||
SourceType: ".go source",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package parser2
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/scanner"
|
||||
@@ -151,7 +152,8 @@ func (s *SourceProcessor) processPath(path string, info os.FileInfo, err error)
|
||||
0)
|
||||
|
||||
if err != nil {
|
||||
if errList, ok := err.(scanner.ErrorList); ok {
|
||||
var errList scanner.ErrorList
|
||||
if errors.As(err, &errList) {
|
||||
pos := errList[0].Pos
|
||||
newError := &utils.SourceError{
|
||||
SourceType: ".go source",
|
||||
|
||||
@@ -19,7 +19,7 @@ func TestBuild(t *testing.T) {
|
||||
t.Run("Build", func(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
c := newApp("build-test", model.NEW, nil, a)
|
||||
main.Commands[model.NEW].RunWith(c)
|
||||
a.Nil(main.Commands[model.NEW].RunWith(c), "failed to run new")
|
||||
c.Index = model.BUILD
|
||||
c.Build.TargetPath = filepath.Join(gopath, "build-test", "target")
|
||||
c.Build.ImportPath = c.ImportPath
|
||||
@@ -34,7 +34,7 @@ func TestBuild(t *testing.T) {
|
||||
"build-test-WithFlags/app.AppVersion=SomeValue",
|
||||
"build-test-WithFlags/app.SomeOtherValue=SomeValue",
|
||||
}
|
||||
main.Commands[model.NEW].RunWith(c)
|
||||
a.Nil(main.Commands[model.NEW].RunWith(c), "failed to run new")
|
||||
c.Index = model.BUILD
|
||||
c.Build.TargetPath = filepath.Join(gopath, "build-test", "target")
|
||||
c.Build.ImportPath = c.ImportPath
|
||||
|
||||
@@ -19,9 +19,12 @@ func TestClean(t *testing.T) {
|
||||
t.Run("Clean", func(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
c := newApp("clean-test", model.NEW, nil, a)
|
||||
main.Commands[model.NEW].RunWith(c)
|
||||
|
||||
a.Nil(main.Commands[model.NEW].RunWith(c), "failed to run new")
|
||||
|
||||
c.Index = model.TEST
|
||||
main.Commands[model.TEST].RunWith(c)
|
||||
a.Nil(main.Commands[model.TEST].RunWith(c), "failed to run test")
|
||||
|
||||
a.True(utils.Exists(filepath.Join(gopath, "clean-test", "app", "tmp", "main.go")),
|
||||
"Missing main from path "+filepath.Join(gopath, "clean-test", "app", "tmp", "main.go"))
|
||||
c.Clean.ImportPath = c.ImportPath
|
||||
|
||||
@@ -33,7 +33,10 @@ func setup(suffix string, a *assert.Assertions) string {
|
||||
// But if you change into that directory and read the current folder it is
|
||||
// /private/var/folders/nz/vv4_9tw56nv9k3tkvyszvwg80000gn/T/revel-test/revel-test-build
|
||||
// So to make this work on darwin this code was added
|
||||
os.Chdir(gopath)
|
||||
if err := os.Chdir(gopath); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
newwd, _ := os.Getwd()
|
||||
gopath = newwd
|
||||
defaultBuild := build.Default
|
||||
|
||||
24
revel/new.go
24
revel/new.go
@@ -18,8 +18,10 @@ import (
|
||||
"github.com/revel/cmd/utils"
|
||||
)
|
||||
|
||||
const ErrNoSkeleton Error = "failed to find skeleton in filepath"
|
||||
|
||||
var cmdNew = &Command{
|
||||
UsageLine: "new -i [path] -s [skeleton]",
|
||||
UsageLine: "new -i [path] -s [skeleton] -p [package name]",
|
||||
Short: "create a skeleton Revel application",
|
||||
Long: `
|
||||
New creates a few files to get a new Revel application running quickly.
|
||||
@@ -92,7 +94,9 @@ func newApp(c *model.CommandConfig) (err error) {
|
||||
// This kicked off the download of the revel app, not needed for vendor
|
||||
if !c.Vendored {
|
||||
// At this point the versions can be set
|
||||
c.SetVersions()
|
||||
if err = c.SetVersions(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// copy files to new app directory
|
||||
@@ -114,11 +118,18 @@ func newApp(c *model.CommandConfig) (err error) {
|
||||
// Need to prep the run command
|
||||
c.Run.ImportPath = c.ImportPath
|
||||
updateRunConfig(c, nil)
|
||||
c.UpdateImportPath()
|
||||
runApp(c)
|
||||
|
||||
if err = c.UpdateImportPath(); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err = runApp(c); err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintln(os.Stdout, "\nYou can run it with:\n revel run -a", c.ImportPath)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -129,13 +140,16 @@ func createModVendor(c *model.CommandConfig) (err error) {
|
||||
utils.CmdInit(goModCmd, !c.Vendored, c.AppPath)
|
||||
|
||||
utils.Logger.Info("Exec:", "args", goModCmd.Args, "env", goModCmd.Env, "workingdir", goModCmd.Dir)
|
||||
|
||||
getOutput, err := goModCmd.CombinedOutput()
|
||||
if c.New.Callback != nil {
|
||||
err = c.New.Callback()
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return utils.NewBuildIfError(err, string(getOutput))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -206,7 +220,7 @@ func setSkeletonPath(c *model.CommandConfig) (err error) {
|
||||
c.New.SkeletonPath = fullpath
|
||||
utils.Logger.Info("Set skeleton path to ", fullpath)
|
||||
if !utils.DirExists(fullpath) {
|
||||
return fmt.Errorf("failed to find skeleton in filepath %s %s", fullpath, sp.String())
|
||||
return fmt.Errorf("%w %s %s", ErrNoSkeleton, fullpath, sp.String())
|
||||
}
|
||||
case "git":
|
||||
fallthrough
|
||||
|
||||
@@ -17,7 +17,7 @@ func TestPackage(t *testing.T) {
|
||||
t.Run("Package", func(t *testing.T) {
|
||||
a := assert.New(t)
|
||||
c := newApp("package-test", model.NEW, nil, a)
|
||||
main.Commands[model.NEW].RunWith(c)
|
||||
a.Nil(main.Commands[model.NEW].RunWith(c), "failed to run new")
|
||||
c.Index = model.PACKAGE
|
||||
c.Package.ImportPath = c.ImportPath
|
||||
a.Nil(main.Commands[model.PACKAGE].RunWith(c), "Failed to run package-test")
|
||||
|
||||
@@ -22,6 +22,16 @@ import (
|
||||
"github.com/revel/cmd/utils"
|
||||
)
|
||||
|
||||
// Error is used for constant errors.
|
||||
type Error string
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e Error) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
const ErrInvalidCommandLine Error = "invalid command line arguments"
|
||||
|
||||
const (
|
||||
// RevelCmdImportPath Revel framework cmd tool import path.
|
||||
RevelSkeletonsImportPath = "github.com/revel/skeletons"
|
||||
@@ -138,7 +148,7 @@ func ParseArgs(c *model.CommandConfig, parser *flags.Parser, args []string) (err
|
||||
if !Commands[c.Index].UpdateConfig(c, extraArgs) {
|
||||
buffer := &bytes.Buffer{}
|
||||
parser.WriteHelp(buffer)
|
||||
err = fmt.Errorf("invalid command line arguments %v\n%s", extraArgs, buffer.String())
|
||||
err = fmt.Errorf("%w %v\n%s", ErrInvalidCommandLine, extraArgs, buffer.String())
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -133,7 +133,7 @@ func runApp(c *model.CommandConfig) (err error) {
|
||||
// If the app is run in "watched" mode, use the harness to run it.
|
||||
if revelPath.Config.BoolDefault("watch", true) && revelPath.Config.BoolDefault("watch.code", true) {
|
||||
utils.Logger.Info("Running in watched mode.")
|
||||
runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v}`, revelPath.RunMode, c.Verbose)
|
||||
runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v}`, revelPath.RunMode, c.Verbose[0])
|
||||
if c.HistoricMode {
|
||||
runMode = revelPath.RunMode
|
||||
}
|
||||
@@ -152,7 +152,7 @@ func runApp(c *model.CommandConfig) (err error) {
|
||||
if len(app.PackagePathMap) > 0 {
|
||||
paths, _ = json.Marshal(app.PackagePathMap)
|
||||
}
|
||||
runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v,"packagePathMap":%s}`, app.Paths.RunMode, c.Verbose, string(paths))
|
||||
runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v,"packagePathMap":%s}`, app.Paths.RunMode, c.Verbose[0], string(paths))
|
||||
if c.HistoricMode {
|
||||
runMode = revelPath.RunMode
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ func testApp(c *model.CommandConfig) (err error) {
|
||||
if len(app.PackagePathMap) > 0 {
|
||||
paths, _ = json.Marshal(app.PackagePathMap)
|
||||
}
|
||||
runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v,"packagePathMap":%s}`, app.Paths.RunMode, c.Verbose, string(paths))
|
||||
runMode := fmt.Sprintf(`{"mode":"%s", "specialUseFlag":%v,"packagePathMap":%s}`, app.Paths.RunMode, c.Verbose[0], string(paths))
|
||||
if c.HistoricMode {
|
||||
runMode = app.Paths.RunMode
|
||||
}
|
||||
|
||||
@@ -82,7 +82,9 @@ func (v *VersionCommand) RunWith(c *model.CommandConfig) (err error) {
|
||||
if e := cmd.Start(); e != nil {
|
||||
fmt.Println("Go command error ", e)
|
||||
} else {
|
||||
cmd.Wait()
|
||||
if err = cmd.Wait(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
@@ -188,7 +190,9 @@ func (v *VersionCommand) versionFromBytes(sourceStream []byte) (version *model.V
|
||||
r := spec.Values[0].(*ast.BasicLit)
|
||||
switch spec.Names[0].Name {
|
||||
case "Version":
|
||||
version.ParseVersion(strings.ReplaceAll(r.Value, `"`, ""))
|
||||
if err = version.ParseVersion(strings.ReplaceAll(r.Value, `"`, "")); err != nil {
|
||||
return
|
||||
}
|
||||
case "BuildDate":
|
||||
version.BuildDate = r.Value
|
||||
case "MinimumGoVersion":
|
||||
@@ -202,7 +206,12 @@ func (v *VersionCommand) versionFromBytes(sourceStream []byte) (version *model.V
|
||||
// Fetch the local version of revel from the file system.
|
||||
func (v *VersionCommand) updateLocalVersions() {
|
||||
v.cmdVersion = &model.Version{}
|
||||
v.cmdVersion.ParseVersion(cmd.Version)
|
||||
|
||||
if err := v.cmdVersion.ParseVersion(cmd.Version); err != nil {
|
||||
utils.Logger.Warn("Error parsing version", "error", err, "version", cmd.Version)
|
||||
return
|
||||
}
|
||||
|
||||
v.cmdVersion.BuildDate = cmd.BuildDate
|
||||
v.cmdVersion.MinGoVersion = cmd.MinimumGoVersion
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main_test
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
@@ -34,8 +35,9 @@ func TestVersion(t *testing.T) {
|
||||
c.Version.ImportPath = c.ImportPath
|
||||
a.Nil(main.Commands[model.VERSION].RunWith(c), "Failed to run version-test")
|
||||
})
|
||||
|
||||
if !t.Failed() {
|
||||
if err := os.RemoveAll(gopath); err != nil && err != os.ErrNotExist {
|
||||
if err := os.RemoveAll(gopath); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
a.Fail("Failed to remove test path", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@@ -30,7 +31,8 @@ func NewBuildError(message string, args ...interface{}) (b *BuildError) {
|
||||
// Returns a new BuildError if err is not nil.
|
||||
func NewBuildIfError(err error, message string, args ...interface{}) (b error) {
|
||||
if err != nil {
|
||||
if berr, ok := err.(*BuildError); ok {
|
||||
var berr *BuildError
|
||||
if errors.As(err, &berr) {
|
||||
// This is already a build error so just append the args
|
||||
berr.Args = append(berr.Args, args...)
|
||||
return berr
|
||||
@@ -50,16 +52,16 @@ func (b *BuildError) Error() string {
|
||||
|
||||
// Parse the output of the "go build" command.
|
||||
// Return a detailed Error.
|
||||
func NewCompileError(importPath, errorLink string, error error) *SourceError {
|
||||
func NewCompileError(importPath, errorLink string, err error) *SourceError {
|
||||
// Get the stack from the error
|
||||
|
||||
errorMatch := regexp.MustCompile(`(?m)^([^:#]+):(\d+):(\d+:)? (.*)$`).
|
||||
FindSubmatch([]byte(error.Error()))
|
||||
FindSubmatch([]byte(err.Error()))
|
||||
if errorMatch == nil {
|
||||
errorMatch = regexp.MustCompile(`(?m)^(.*?):(\d+):\s(.*?)$`).FindSubmatch([]byte(error.Error()))
|
||||
errorMatch = regexp.MustCompile(`(?m)^(.*?):(\d+):\s(.*?)$`).FindSubmatch([]byte(err.Error()))
|
||||
|
||||
if errorMatch == nil {
|
||||
Logger.Error("Failed to parse build errors", "error", error)
|
||||
Logger.Error("Failed to parse build errors", "error", err)
|
||||
return &SourceError{
|
||||
SourceType: "Go code",
|
||||
Title: "Go Compilation Error",
|
||||
@@ -69,7 +71,7 @@ func NewCompileError(importPath, errorLink string, error error) *SourceError {
|
||||
|
||||
errorMatch = append(errorMatch, errorMatch[3])
|
||||
|
||||
Logger.Error("Build errors", "errors", error)
|
||||
Logger.Error("Build errors", "errors", err)
|
||||
}
|
||||
|
||||
// Read the source for the offending file.
|
||||
|
||||
@@ -17,6 +17,9 @@ func CmdInit(c *exec.Cmd, addGoPath bool, basePath string) {
|
||||
c.Env = ReducedEnv(addGoPath)
|
||||
|
||||
}
|
||||
|
||||
// ReducedEnv returns a list of environment vairables by using os.Env
|
||||
// it will remove the GOPATH, GOROOT if addGoPath is true
|
||||
func ReducedEnv(addGoPath bool) []string {
|
||||
realPath := &bytes.Buffer{}
|
||||
env := []string{}
|
||||
@@ -38,7 +41,7 @@ func ReducedEnv(addGoPath bool) []string {
|
||||
if pair[0] == "GOMODCACHE" {
|
||||
continue
|
||||
} else if !addGoPath && (pair[0] == "GOPATH" || pair[0] == "GOROOT") {
|
||||
|
||||
continue
|
||||
}
|
||||
env = append(env, e)
|
||||
}
|
||||
|
||||
@@ -150,8 +150,9 @@ func MustChmod(filename string, mode os.FileMode) {
|
||||
|
||||
// Called if panic.
|
||||
func PanicOnError(err error, msg string) {
|
||||
if revErr, ok := err.(*SourceError); (ok && revErr != nil) || (!ok && err != nil) {
|
||||
Logger.Panicf("Abort: %s: %s %s", msg, revErr, err)
|
||||
var serr *SourceError
|
||||
if (errors.As(err, &serr) && serr != nil) || err != nil {
|
||||
Logger.Panicf("Abort: %s: %s %s", msg, serr, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,9 +349,17 @@ func FindSrcPaths(appPath string, packageList []string, packageResolver func(pkg
|
||||
return
|
||||
}
|
||||
|
||||
// Error is used for constant errors.
|
||||
type Error string
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e Error) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
var (
|
||||
NO_APP_FOUND = errors.New("no app found")
|
||||
NO_REVEL_FOUND = errors.New("no revel found")
|
||||
ErrNoApp Error = "no app found"
|
||||
ErrNoRevel Error = "no revel found"
|
||||
)
|
||||
|
||||
// Find the full source dir for the import path, uses the build.Default.GOPATH to search for the directory.
|
||||
@@ -388,9 +397,9 @@ func findSrcPaths(appPath string, packagesList []string) (sourcePathsmap map[str
|
||||
}
|
||||
if !found {
|
||||
if packageName == "github.com/revel/revel" {
|
||||
err = NO_REVEL_FOUND
|
||||
err = ErrNoRevel
|
||||
} else {
|
||||
err = NO_APP_FOUND
|
||||
err = ErrNoApp
|
||||
}
|
||||
missingList = append(missingList, packageName)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func InitLogger(basePath string, logLevel logger.LogLevel) {
|
||||
|
||||
// This function is to throw a panic that may be caught by the packger so it can perform the needed
|
||||
// imports.
|
||||
func Retry(format string, args ...interface{}) {
|
||||
func Retryf(format string, args ...interface{}) {
|
||||
// Ensure the user's command prompt starts on the next line.
|
||||
if !strings.HasSuffix(format, "\n") {
|
||||
format += "\n"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
package cmd
|
||||
|
||||
const (
|
||||
// Version current Revel version
|
||||
// Version current Revel version.
|
||||
Version = "1.1.0-dev"
|
||||
|
||||
// BuildDate latest commit/release date.
|
||||
|
||||
@@ -46,16 +46,16 @@ type Watcher struct {
|
||||
timerMutex *sync.Mutex // A mutex to prevent concurrent updates
|
||||
refreshChannel chan *utils.SourceError
|
||||
refreshChannelCount int
|
||||
refreshTimerMS time.Duration // The number of milliseconds between refreshing builds
|
||||
refreshInterval time.Duration // The interval between refreshing builds
|
||||
}
|
||||
|
||||
// Creates a new watched based on the container.
|
||||
func NewWatcher(paths *model.RevelContainer, eagerRefresh bool) *Watcher {
|
||||
return &Watcher{
|
||||
forceRefresh: false,
|
||||
lastError: -1,
|
||||
paths: paths,
|
||||
refreshTimerMS: time.Duration(paths.Config.IntDefault("watch.rebuild.delay", 1000)),
|
||||
forceRefresh: true,
|
||||
lastError: -1,
|
||||
paths: paths,
|
||||
refreshInterval: time.Duration(paths.Config.IntDefault("watch.rebuild.delay", 1000)) * time.Millisecond,
|
||||
eagerRefresh: eagerRefresh ||
|
||||
paths.DevMode &&
|
||||
paths.Config.BoolDefault("watch", true) &&
|
||||
@@ -163,7 +163,10 @@ func (w *Watcher) NotifyWhenUpdated(listener Listener, watcher *fsnotify.Watcher
|
||||
} else {
|
||||
// Run refresh in parallel
|
||||
go func() {
|
||||
w.notifyInProcess(listener)
|
||||
if err := w.notifyInProcess(listener); err != nil {
|
||||
utils.Logger.Error("failed to notify",
|
||||
"error", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
@@ -238,11 +241,11 @@ func (w *Watcher) notifyInProcess(listener Listener) (err *utils.SourceError) {
|
||||
w.forceRefresh = true
|
||||
if w.refreshTimer != nil {
|
||||
utils.Logger.Info("Found existing timer running, resetting")
|
||||
w.refreshTimer.Reset(time.Millisecond * w.refreshTimerMS)
|
||||
w.refreshTimer.Reset(w.refreshInterval)
|
||||
shouldReturn = true
|
||||
w.refreshChannelCount++
|
||||
} else {
|
||||
w.refreshTimer = time.NewTimer(time.Millisecond * w.refreshTimerMS)
|
||||
w.refreshTimer = time.NewTimer(w.refreshInterval)
|
||||
}
|
||||
}()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user