mirror of
https://github.com/go-task/task.git
synced 2025-06-15 00:15:10 +02:00
Merge branch 'master' into master
This commit is contained in:
3
.github/CONTRIBUTING.md
vendored
3
.github/CONTRIBUTING.md
vendored
@ -1,9 +1,6 @@
|
|||||||
* Bug reports and feature requests are welcome in [the issues][issues]
|
* Bug reports and feature requests are welcome in [the issues][issues]
|
||||||
* For questions and discussion there's the [Slack room][slack] ([invititation here][slackinvite])
|
|
||||||
* Pull Requests are welcome. For more complex changes and features it's
|
* Pull Requests are welcome. For more complex changes and features it's
|
||||||
recommended to open an issue with the feature request first
|
recommended to open an issue with the feature request first
|
||||||
* Documentation contributions are as important as code contributions
|
* Documentation contributions are as important as code contributions
|
||||||
|
|
||||||
[issues]: https://github.com/go-task/task/issues
|
[issues]: https://github.com/go-task/task/issues
|
||||||
[slack]: https://gophers.slack.com/messages/task
|
|
||||||
[slackinvite]: https://invite.slack.golangbridge.org/
|
|
||||||
|
3
.github/ISSUE_TEMPLATE.md
vendored
3
.github/ISSUE_TEMPLATE.md
vendored
@ -1,7 +1,4 @@
|
|||||||
<!--
|
<!--
|
||||||
For questions and general talk there's the Slack room: https://gophers.slack.com/messages/task
|
|
||||||
Invite to the Slack is available in this link: https://invite.slack.golangbridge.org/
|
|
||||||
|
|
||||||
If relevant, include the following information:
|
If relevant, include the following information:
|
||||||
- Task version
|
- Task version
|
||||||
- OS
|
- OS
|
||||||
|
83
Gopkg.lock
generated
83
Gopkg.lock
generated
@ -3,129 +3,186 @@
|
|||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:f3960e064201714a3507bf96183be246b3d941568af01dc5cff2a388ac4c7515"
|
||||||
name = "github.com/Masterminds/semver"
|
name = "github.com/Masterminds/semver"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "3c560837130448941620d7694991d3ec440aefc0"
|
pruneopts = "NUT"
|
||||||
|
revision = "4ca3c04fd4fe2a472df0d7121b1b9462f2214c43"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
digest = "1:43f9a530dfe36fb355b05fbc7a5712f8149a7f6bdfd131bc0ccc634e25c4dd1e"
|
||||||
name = "github.com/Masterminds/sprig"
|
name = "github.com/Masterminds/sprig"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "6b2a58267f6a8b1dc8e2eb5519b984008fa85e8c"
|
revision = "6b2a58267f6a8b1dc8e2eb5519b984008fa85e8c"
|
||||||
version = "v2.15.0"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
digest = "1:975108e8d4f5dab096fc991326e96a5716ee8d02e5e7386bb4796171afc4ab9a"
|
||||||
name = "github.com/aokoli/goutils"
|
name = "github.com/aokoli/goutils"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "3391d3790d23d03408670993e957e8f408993c34"
|
revision = "3391d3790d23d03408670993e957e8f408993c34"
|
||||||
version = "v1.0.1"
|
version = "v1.0.1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
|
||||||
name = "github.com/davecgh/go-spew"
|
name = "github.com/davecgh/go-spew"
|
||||||
packages = ["spew"]
|
packages = ["spew"]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||||
version = "v1.1.0"
|
version = "v1.1.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
digest = "1:1bb197a3b5db4e06e00b7560f8e89836c486627f2a0338332ed37daa003d259e"
|
||||||
name = "github.com/google/uuid"
|
name = "github.com/google/uuid"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "064e2069ce9c359c118179501254f67d7d37ba24"
|
revision = "064e2069ce9c359c118179501254f67d7d37ba24"
|
||||||
version = "0.2"
|
version = "0.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
digest = "1:f5db19d350bd0b542d17f7e7cf4e7068bac416c08adb6a129b3c6d1db8211051"
|
||||||
name = "github.com/huandu/xstrings"
|
name = "github.com/huandu/xstrings"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "2bf18b218c51864a87384c06996e40ff9dcff8e1"
|
revision = "2bf18b218c51864a87384c06996e40ff9dcff8e1"
|
||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
digest = "1:65300ccc4bcb38b107b868155c303312978981e56bca707c81efec57575b5e06"
|
||||||
name = "github.com/imdario/mergo"
|
name = "github.com/imdario/mergo"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "9316a62528ac99aaecb4e47eadd6dc8aa6533d58"
|
revision = "9316a62528ac99aaecb4e47eadd6dc8aa6533d58"
|
||||||
version = "v0.3.5"
|
version = "v0.3.5"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:fdf499904ff0a8b5e05a32d98a1e65ddaff6b358640dbd8696ce8bb4e8d2d246"
|
||||||
name = "github.com/mattn/go-zglob"
|
name = "github.com/mattn/go-zglob"
|
||||||
packages = [
|
packages = [
|
||||||
".",
|
".",
|
||||||
"fastwalk"
|
"fastwalk",
|
||||||
]
|
]
|
||||||
revision = "49693fbb3fe3c3a75fc4e4d6fb1d7cedcbdeb385"
|
pruneopts = "NUT"
|
||||||
|
revision = "c436403c742d0b6d8fc37e69eadf33e024fe74fa"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "master"
|
||||||
|
digest = "1:9db29b604bd78452d167abed82386ddd2f93973df3841896fb6ab8aff936f1d6"
|
||||||
|
name = "github.com/mitchellh/go-homedir"
|
||||||
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
|
revision = "3864e76763d94a6df2f9960b16a20a33da9f9a66"
|
||||||
|
|
||||||
|
[[projects]]
|
||||||
|
digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
|
||||||
name = "github.com/pmezard/go-difflib"
|
name = "github.com/pmezard/go-difflib"
|
||||||
packages = ["difflib"]
|
packages = ["difflib"]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:5089085e1b27a57be4fb7acf32bfa71fb6236dc0e8371165651c9e15285a9ce0"
|
||||||
name = "github.com/radovskyb/watcher"
|
name = "github.com/radovskyb/watcher"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "0d9d32686dbf6395752c9b209398a59e302a7f1e"
|
revision = "0d9d32686dbf6395752c9b209398a59e302a7f1e"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:8c05fbdaac9713aed2a89d171a8b4e98a563f6c84e48352d0bcb10b1a5122488"
|
||||||
name = "github.com/spf13/pflag"
|
name = "github.com/spf13/pflag"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "3ebe029320b2676d667ae88da602a5f854788a8a"
|
revision = "3ebe029320b2676d667ae88da602a5f854788a8a"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
digest = "1:bacb8b590716ab7c33f2277240972c9582d389593ee8d66fc10074e0508b8126"
|
||||||
name = "github.com/stretchr/testify"
|
name = "github.com/stretchr/testify"
|
||||||
packages = ["assert"]
|
packages = ["assert"]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
|
revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
|
||||||
version = "v1.2.2"
|
version = "v1.2.2"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:17ff32de9f3bf39f76d339ddffcd380140721b112bea96837a86d4dc26c2c633"
|
||||||
name = "golang.org/x/crypto"
|
name = "golang.org/x/crypto"
|
||||||
packages = [
|
packages = [
|
||||||
"pbkdf2",
|
"pbkdf2",
|
||||||
"scrypt",
|
"scrypt",
|
||||||
"ssh/terminal"
|
"ssh/terminal",
|
||||||
]
|
]
|
||||||
revision = "a49355c7e3f8fe157a85be2f77e6e269a0f89602"
|
pruneopts = "NUT"
|
||||||
|
revision = "a2144134853fc9a27a7b1e3eb4f19f1a76df13c9"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:76ee51c3f468493aff39dbacc401e8831fbb765104cbf613b89bef01cf4bad70"
|
||||||
name = "golang.org/x/net"
|
name = "golang.org/x/net"
|
||||||
packages = ["context"]
|
packages = ["context"]
|
||||||
revision = "afe8f62b1d6bbd81f31868121a50b06d8188e1f9"
|
pruneopts = "NUT"
|
||||||
|
revision = "a680a1efc54dd51c040b3b5ce4939ea3cf2ea0d1"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:39ebcc2b11457b703ae9ee2e8cca0f68df21969c6102cb3b705f76cca0ea0239"
|
||||||
name = "golang.org/x/sync"
|
name = "golang.org/x/sync"
|
||||||
packages = ["errgroup"]
|
packages = ["errgroup"]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
|
revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:64107e3c8f52f341891a565d117bf263ed396fe0c16bad19634b25be25debfaa"
|
||||||
name = "golang.org/x/sys"
|
name = "golang.org/x/sys"
|
||||||
packages = [
|
packages = [
|
||||||
"unix",
|
"unix",
|
||||||
"windows"
|
"windows",
|
||||||
]
|
]
|
||||||
revision = "63fc586f45fe72d95d5240a5d5eb95e6503907d3"
|
pruneopts = "NUT"
|
||||||
|
revision = "ac767d655b305d4e9612f5f6e33120b9176c4ad4"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "v2"
|
||||||
|
digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082"
|
||||||
name = "gopkg.in/yaml.v2"
|
name = "gopkg.in/yaml.v2"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
|
pruneopts = "NUT"
|
||||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||||
version = "v2.2.1"
|
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
digest = "1:01be9a02fb8bcae03383a7422d0bd48813fd49834a50be5ef933e430604b3423"
|
||||||
name = "mvdan.cc/sh"
|
name = "mvdan.cc/sh"
|
||||||
packages = [
|
packages = [
|
||||||
"interp",
|
"interp",
|
||||||
"shell",
|
"shell",
|
||||||
"syntax"
|
"syntax",
|
||||||
]
|
]
|
||||||
revision = "ca7561fd34910fd8575a3830d3cded291c0ce8b2"
|
pruneopts = "NUT"
|
||||||
|
revision = "54e5852f101469e5ff9b03902ce0d4ff2ef09809"
|
||||||
|
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "600bd482208fdedec60141bfaffe55eb403df077944bfdf5c007a33132c8ab5a"
|
input-imports = [
|
||||||
|
"github.com/Masterminds/semver",
|
||||||
|
"github.com/Masterminds/sprig",
|
||||||
|
"github.com/mattn/go-zglob",
|
||||||
|
"github.com/mitchellh/go-homedir",
|
||||||
|
"github.com/radovskyb/watcher",
|
||||||
|
"github.com/spf13/pflag",
|
||||||
|
"github.com/stretchr/testify/assert",
|
||||||
|
"golang.org/x/sync/errgroup",
|
||||||
|
"gopkg.in/yaml.v2",
|
||||||
|
"mvdan.cc/sh/interp",
|
||||||
|
"mvdan.cc/sh/shell",
|
||||||
|
"mvdan.cc/sh/syntax",
|
||||||
|
]
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
@ -7,10 +7,6 @@
|
|||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/Masterminds/sprig"
|
name = "github.com/Masterminds/sprig"
|
||||||
|
|
||||||
[[constraint]]
|
|
||||||
branch = "master"
|
|
||||||
name = "github.com/imdario/mergo"
|
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/mattn/go-zglob"
|
name = "github.com/mattn/go-zglob"
|
||||||
|
11
README.md
11
README.md
@ -1,4 +1,3 @@
|
|||||||
[](https://gophers.slack.com/messages/task)
|
|
||||||
[](https://travis-ci.org/go-task/task)
|
[](https://travis-ci.org/go-task/task)
|
||||||
|
|
||||||
# Task - A task runner / simpler Make alternative written in Go
|
# Task - A task runner / simpler Make alternative written in Go
|
||||||
@ -127,7 +126,7 @@ tasks:
|
|||||||
|
|
||||||
### OS specific task
|
### OS specific task
|
||||||
|
|
||||||
If you add a `Taskfile_{{GOOS}}.yml` you can override or amend your taskfile
|
If you add a `Taskfile_{{GOOS}}.yml` you can override or amend your Taskfile
|
||||||
based on the operating system.
|
based on the operating system.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
@ -146,13 +145,18 @@ tasks:
|
|||||||
Taskfile_linux.yml:
|
Taskfile_linux.yml:
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
|
version: '2'
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
build:
|
build:
|
||||||
cmds:
|
cmds:
|
||||||
- echo "linux"
|
- echo "linux"
|
||||||
```
|
```
|
||||||
|
|
||||||
Will print out `linux` and not default.
|
Will print out `linux` and not `default`.
|
||||||
|
|
||||||
|
Keep in mind that the version of the files should match. Also, when redefining
|
||||||
|
a task the whole task is replaced, properties of the task are not merged.
|
||||||
|
|
||||||
It's also possible to have an OS specific `Taskvars.yml` file, like
|
It's also possible to have an OS specific `Taskvars.yml` file, like
|
||||||
`Taskvars_windows.yml`, `Taskfile_linux.yml`, or `Taskvars_darwin.yml`. See the
|
`Taskvars_windows.yml`, `Taskfile_linux.yml`, or `Taskvars_darwin.yml`. See the
|
||||||
@ -325,7 +329,6 @@ If you prefer this check to be made by the content of the files, instead of
|
|||||||
its timestamp, just set the `method` property to `checksum`.
|
its timestamp, just set the `method` property to `checksum`.
|
||||||
You will probably want to ignore the `.task` folder in your `.gitignore` file
|
You will probably want to ignore the `.task` folder in your `.gitignore` file
|
||||||
(It's there that Task stores the last checksum).
|
(It's there that Task stores the last checksum).
|
||||||
This feature is still experimental and can change until it's stable.
|
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
version: '2'
|
version: '2'
|
||||||
|
38
Taskfile.yml
38
Taskfile.yml
@ -5,24 +5,13 @@ vars:
|
|||||||
sh: git log -n 1 --format=%h
|
sh: git log -n 1 --format=%h
|
||||||
|
|
||||||
GO_PACKAGES:
|
GO_PACKAGES:
|
||||||
.
|
sh: go list ./...
|
||||||
./cmd/task
|
|
||||||
./internal/args
|
|
||||||
./internal/compiler
|
|
||||||
./internal/compiler/v1
|
|
||||||
./internal/compiler/v2
|
|
||||||
./internal/execext
|
|
||||||
./internal/logger
|
|
||||||
./internal/osext
|
|
||||||
./internal/output
|
|
||||||
./internal/status
|
|
||||||
./internal/taskfile
|
|
||||||
./internal/taskfile/version
|
|
||||||
./internal/templater
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
# compiles current source code and make "task" executable available on
|
default:
|
||||||
# $GOPATH/bin/task{.exe}
|
cmds:
|
||||||
|
- task: test
|
||||||
|
|
||||||
install:
|
install:
|
||||||
desc: Installs Task
|
desc: Installs Task
|
||||||
cmds:
|
cmds:
|
||||||
@ -35,8 +24,6 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- task: go-get
|
- task: go-get
|
||||||
vars: {REPO: github.com/golang/lint/golint}
|
vars: {REPO: github.com/golang/lint/golint}
|
||||||
- task: go-get
|
|
||||||
vars: {REPO: github.com/asticode/go-astitodo/astitodo}
|
|
||||||
- task: go-get
|
- task: go-get
|
||||||
vars: {REPO: github.com/golang/dep/cmd/dep}
|
vars: {REPO: github.com/golang/dep/cmd/dep}
|
||||||
- task: go-get
|
- task: go-get
|
||||||
@ -58,14 +45,14 @@ tasks:
|
|||||||
lint:
|
lint:
|
||||||
desc: Runs golint
|
desc: Runs golint
|
||||||
cmds:
|
cmds:
|
||||||
- golint {{.GO_PACKAGES}}
|
- golint {{catLines .GO_PACKAGES}}
|
||||||
silent: true
|
silent: true
|
||||||
|
|
||||||
test:
|
test:
|
||||||
desc: Runs test suite
|
desc: Runs test suite
|
||||||
deps: [install]
|
deps: [install]
|
||||||
cmds:
|
cmds:
|
||||||
- go test {{.GO_PACKAGES}}
|
- go test {{catLines .GO_PACKAGES}}
|
||||||
|
|
||||||
test-release:
|
test-release:
|
||||||
desc: Tests release process without publishing
|
desc: Tests release process without publishing
|
||||||
@ -77,12 +64,6 @@ tasks:
|
|||||||
cmds:
|
cmds:
|
||||||
- godownloader --repo go-task/task -o install-task.sh
|
- godownloader --repo go-task/task -o install-task.sh
|
||||||
|
|
||||||
todo:
|
|
||||||
desc: Prints TODO comments present in the code
|
|
||||||
cmds:
|
|
||||||
- astitodo {{.GO_PACKAGES}}
|
|
||||||
silent: true
|
|
||||||
|
|
||||||
ci:
|
ci:
|
||||||
cmds:
|
cmds:
|
||||||
- task: go-get
|
- task: go-get
|
||||||
@ -93,3 +74,8 @@ tasks:
|
|||||||
go-get:
|
go-get:
|
||||||
cmds:
|
cmds:
|
||||||
- go get -u {{.REPO}}
|
- go get -u {{.REPO}}
|
||||||
|
|
||||||
|
packages:
|
||||||
|
cmds:
|
||||||
|
- echo '{{.GO_PACKAGES}}'
|
||||||
|
silent: true
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
package osext
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Expand is an improved version of os.ExpandEnv,
|
|
||||||
// that not only expand enrionment variable ($GOPATH/src/github.com/...)
|
|
||||||
// but also expands "~" as the home directory.
|
|
||||||
func Expand(s string) (string, error) {
|
|
||||||
s = os.ExpandEnv(s)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
s, err = homedir.Expand(s)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
|
@ -4,9 +4,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/go-task/task/internal/osext"
|
|
||||||
|
|
||||||
"github.com/mattn/go-zglob"
|
"github.com/mattn/go-zglob"
|
||||||
|
"mvdan.cc/sh/shell"
|
||||||
)
|
)
|
||||||
|
|
||||||
func glob(dir string, globs []string) (files []string, err error) {
|
func glob(dir string, globs []string) (files []string, err error) {
|
||||||
@ -14,7 +13,7 @@ func glob(dir string, globs []string) (files []string, err error) {
|
|||||||
if !filepath.IsAbs(g) {
|
if !filepath.IsAbs(g) {
|
||||||
g = filepath.Join(dir, g)
|
g = filepath.Join(dir, g)
|
||||||
}
|
}
|
||||||
g, err = osext.Expand(g)
|
g, err = shell.Expand(g, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
27
internal/taskfile/merge.go
Normal file
27
internal/taskfile/merge.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package taskfile
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Merge merges the second Taskfile into the first
|
||||||
|
func Merge(t1, t2 *Taskfile) error {
|
||||||
|
if t1.Version != t2.Version {
|
||||||
|
return fmt.Errorf(`Taskfiles versions should match. First is "%s" but second is "%s"`, t1.Version, t2.Version)
|
||||||
|
}
|
||||||
|
|
||||||
|
if t2.Expansions != 0 && t2.Expansions != 2 {
|
||||||
|
t1.Expansions = t2.Expansions
|
||||||
|
}
|
||||||
|
if t2.Output != "" {
|
||||||
|
t1.Output = t2.Output
|
||||||
|
}
|
||||||
|
for k, v := range t2.Vars {
|
||||||
|
t1.Vars[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range t2.Tasks {
|
||||||
|
t1.Tasks[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
47
internal/taskfile/read/taskfile.go
Normal file
47
internal/taskfile/read/taskfile.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package read
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Taskfile reads a Taskfile for a given directory
|
||||||
|
func Taskfile(dir string) (*taskfile.Taskfile, error) {
|
||||||
|
path := filepath.Join(dir, "Taskfile.yml")
|
||||||
|
t, err := readTaskfile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(dir, fmt.Sprintf("Taskfile_%s.yml", runtime.GOOS))
|
||||||
|
if _, err = os.Stat(path); err == nil {
|
||||||
|
osTaskfile, err := readTaskfile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err = taskfile.Merge(t, osTaskfile); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, task := range t.Tasks {
|
||||||
|
task.Task = name
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTaskfile(file string) (*taskfile.Taskfile, error) {
|
||||||
|
f, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var t taskfile.Taskfile
|
||||||
|
return &t, yaml.NewDecoder(f).Decode(&t)
|
||||||
|
}
|
52
internal/taskfile/read/taskvars.go
Normal file
52
internal/taskfile/read/taskvars.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package read
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Taskvars reads a Taskvars for a given directory
|
||||||
|
func Taskvars(dir string) (taskfile.Vars, error) {
|
||||||
|
vars := make(taskfile.Vars)
|
||||||
|
|
||||||
|
path := filepath.Join(dir, "Taskvars.yml")
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
vars, err = readTaskvars(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
path = filepath.Join(dir, fmt.Sprintf("Taskvars_%s.yml", runtime.GOOS))
|
||||||
|
if _, err := os.Stat(path); err == nil {
|
||||||
|
osVars, err := readTaskvars(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if vars == nil {
|
||||||
|
vars = osVars
|
||||||
|
} else {
|
||||||
|
for k, v := range osVars {
|
||||||
|
vars[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vars, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func readTaskvars(file string) (taskfile.Vars, error) {
|
||||||
|
f, err := os.Open(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var vars taskfile.Vars
|
||||||
|
return vars, yaml.NewDecoder(f).Decode(&vars)
|
||||||
|
}
|
11
task.go
11
task.go
@ -14,6 +14,7 @@ import (
|
|||||||
"github.com/go-task/task/internal/logger"
|
"github.com/go-task/task/internal/logger"
|
||||||
"github.com/go-task/task/internal/output"
|
"github.com/go-task/task/internal/output"
|
||||||
"github.com/go-task/task/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
"github.com/go-task/task/internal/taskfile/read"
|
||||||
"github.com/go-task/task/internal/taskfile/version"
|
"github.com/go-task/task/internal/taskfile/version"
|
||||||
|
|
||||||
"github.com/Masterminds/semver"
|
"github.com/Masterminds/semver"
|
||||||
@ -21,8 +22,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// TaskFilePath is the default Taskfile
|
|
||||||
TaskFilePath = "Taskfile"
|
|
||||||
// MaximumTaskCall is the max number of times a task can be called.
|
// MaximumTaskCall is the max number of times a task can be called.
|
||||||
// This exists to prevent infinite loops on cyclic dependencies
|
// This exists to prevent infinite loops on cyclic dependencies
|
||||||
MaximumTaskCall = 100
|
MaximumTaskCall = 100
|
||||||
@ -77,7 +76,13 @@ func (e *Executor) Run(calls ...taskfile.Call) error {
|
|||||||
|
|
||||||
// Setup setups Executor's internal state
|
// Setup setups Executor's internal state
|
||||||
func (e *Executor) Setup() error {
|
func (e *Executor) Setup() error {
|
||||||
if err := e.readTaskfile(); err != nil {
|
var err error
|
||||||
|
e.Taskfile, err = read.Taskfile(e.Dir)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
e.taskvars, err = read.Taskvars(e.Dir)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
task_test.go
20
task_test.go
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/go-task/task"
|
"github.com/go-task/task"
|
||||||
"github.com/go-task/task/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
|
|
||||||
|
"github.com/mitchellh/go-homedir"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -435,3 +436,22 @@ func TestTaskIgnoreErrors(t *testing.T) {
|
|||||||
assert.Error(t, e.Run(taskfile.Call{Task: "cmd-should-fail"}))
|
assert.Error(t, e.Run(taskfile.Call{Task: "cmd-should-fail"}))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestExpand(t *testing.T) {
|
||||||
|
const dir = "testdata/expand"
|
||||||
|
|
||||||
|
home, err := homedir.Dir()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Couldn't get $HOME: %v", err)
|
||||||
|
}
|
||||||
|
var buff bytes.Buffer
|
||||||
|
|
||||||
|
e := task.Executor{
|
||||||
|
Dir: dir,
|
||||||
|
Stdout: &buff,
|
||||||
|
Stderr: &buff,
|
||||||
|
}
|
||||||
|
assert.NoError(t, e.Setup())
|
||||||
|
assert.NoError(t, e.Run(taskfile.Call{Task: "pwd"}))
|
||||||
|
assert.Equal(t, home, strings.TrimSpace(buff.String()))
|
||||||
|
}
|
||||||
|
74
taskfile.go
74
taskfile.go
@ -1,74 +0,0 @@
|
|||||||
package task
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/go-task/task/internal/taskfile"
|
|
||||||
|
|
||||||
"github.com/imdario/mergo"
|
|
||||||
"gopkg.in/yaml.v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// readTaskfile parses Taskfile from the disk
|
|
||||||
func (e *Executor) readTaskfile() error {
|
|
||||||
path := filepath.Join(e.Dir, TaskFilePath)
|
|
||||||
|
|
||||||
var err error
|
|
||||||
e.Taskfile, err = e.readTaskfileData(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
osTasks, err := e.readTaskfileData(fmt.Sprintf("%s_%s", path, runtime.GOOS))
|
|
||||||
if err != nil {
|
|
||||||
switch err.(type) {
|
|
||||||
case taskFileNotFound:
|
|
||||||
default:
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := mergo.MapWithOverwrite(&e.Taskfile.Tasks, osTasks.Tasks); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for name, task := range e.Taskfile.Tasks {
|
|
||||||
task.Task = name
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.readTaskvars()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Executor) readTaskfileData(path string) (*taskfile.Taskfile, error) {
|
|
||||||
if b, err := ioutil.ReadFile(path + ".yml"); err == nil {
|
|
||||||
var taskfile taskfile.Taskfile
|
|
||||||
return &taskfile, yaml.Unmarshal(b, &taskfile)
|
|
||||||
}
|
|
||||||
return nil, taskFileNotFound{path}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *Executor) readTaskvars() error {
|
|
||||||
var (
|
|
||||||
file = filepath.Join(e.Dir, TaskvarsFilePath)
|
|
||||||
osSpecificFile = fmt.Sprintf("%s_%s", file, runtime.GOOS)
|
|
||||||
)
|
|
||||||
|
|
||||||
if b, err := ioutil.ReadFile(file + ".yml"); err == nil {
|
|
||||||
if err := yaml.Unmarshal(b, &e.taskvars); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if b, err := ioutil.ReadFile(osSpecificFile + ".yml"); err == nil {
|
|
||||||
osTaskvars := make(taskfile.Vars, 10)
|
|
||||||
if err := yaml.Unmarshal(b, &osTaskvars); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for k, v := range osTaskvars {
|
|
||||||
e.taskvars[k] = v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
8
testdata/expand/Taskfile.yml
vendored
Normal file
8
testdata/expand/Taskfile.yml
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
version: '2'
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
pwd:
|
||||||
|
cmds:
|
||||||
|
- pwd
|
||||||
|
dir: '~'
|
||||||
|
silent: true
|
@ -3,14 +3,10 @@ package task
|
|||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/go-task/task/internal/osext"
|
|
||||||
"github.com/go-task/task/internal/taskfile"
|
"github.com/go-task/task/internal/taskfile"
|
||||||
"github.com/go-task/task/internal/templater"
|
"github.com/go-task/task/internal/templater"
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
"mvdan.cc/sh/shell"
|
||||||
// TaskvarsFilePath file containing additional variables.
|
|
||||||
TaskvarsFilePath = "Taskvars"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// CompiledTask returns a copy of a task, but replacing variables in almost all
|
// CompiledTask returns a copy of a task, but replacing variables in almost all
|
||||||
@ -40,7 +36,7 @@ func (e *Executor) CompiledTask(call taskfile.Call) (*taskfile.Task, error) {
|
|||||||
Method: r.Replace(origTask.Method),
|
Method: r.Replace(origTask.Method),
|
||||||
Prefix: r.Replace(origTask.Prefix),
|
Prefix: r.Replace(origTask.Prefix),
|
||||||
}
|
}
|
||||||
new.Dir, err = osext.Expand(new.Dir)
|
new.Dir, err = shell.Expand(new.Dir, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/Masterminds/semver/doc.go
generated
vendored
2
vendor/github.com/Masterminds/semver/doc.go
generated
vendored
@ -47,7 +47,7 @@ parts of the package.
|
|||||||
// Handle constraint not being parseable.
|
// Handle constraint not being parseable.
|
||||||
}
|
}
|
||||||
|
|
||||||
v, _ := semver.NewVersion("1.3")
|
v, err := semver.NewVersion("1.3")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Handle version not being parseable.
|
// Handle version not being parseable.
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/Masterminds/semver/version.go
generated
vendored
2
vendor/github.com/Masterminds/semver/version.go
generated
vendored
@ -106,7 +106,7 @@ func MustParse(v string) *Version {
|
|||||||
// Note, if the original version contained a leading v this version will not.
|
// Note, if the original version contained a leading v this version will not.
|
||||||
// See the Original() method to retrieve the original value. Semantic Versions
|
// See the Original() method to retrieve the original value. Semantic Versions
|
||||||
// don't contain a leading v per the spec. Instead it's optional on
|
// don't contain a leading v per the spec. Instead it's optional on
|
||||||
// impelementation.
|
// implementation.
|
||||||
func (v *Version) String() string {
|
func (v *Version) String() string {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
15
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk.go
generated
vendored
15
vendor/github.com/mattn/go-zglob/fastwalk/fastwalk.go
generated
vendored
@ -19,6 +19,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TraverseLink is a sentinel error for fastWalk, similar to filepath.SkipDir.
|
// TraverseLink is a sentinel error for fastWalk, similar to filepath.SkipDir.
|
||||||
@ -67,11 +68,18 @@ func FastWalk(root string, walkFn func(path string, typ os.FileMode) error) erro
|
|||||||
// buffered for correctness & not leaking goroutines:
|
// buffered for correctness & not leaking goroutines:
|
||||||
resc: make(chan error, numWorkers),
|
resc: make(chan error, numWorkers),
|
||||||
}
|
}
|
||||||
defer close(w.donec)
|
|
||||||
// TODO(bradfitz): start the workers as needed? maybe not worth it.
|
// TODO(bradfitz): start the workers as needed? maybe not worth it.
|
||||||
|
var wg sync.WaitGroup
|
||||||
for i := 0; i < numWorkers; i++ {
|
for i := 0; i < numWorkers; i++ {
|
||||||
go w.doWork()
|
wg.Add(1)
|
||||||
|
go w.doWork(&wg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure we wait for goroutines we started to finish before we return.
|
||||||
|
defer wg.Wait()
|
||||||
|
defer close(w.donec)
|
||||||
|
|
||||||
todo := []walkItem{{dir: root}}
|
todo := []walkItem{{dir: root}}
|
||||||
out := 0
|
out := 0
|
||||||
for {
|
for {
|
||||||
@ -113,10 +121,11 @@ func FastWalk(root string, walkFn func(path string, typ os.FileMode) error) erro
|
|||||||
|
|
||||||
// doWork reads directories as instructed (via workc) and runs the
|
// doWork reads directories as instructed (via workc) and runs the
|
||||||
// user's callback function.
|
// user's callback function.
|
||||||
func (w *walker) doWork() {
|
func (w *walker) doWork(wg *sync.WaitGroup) {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-w.donec:
|
case <-w.donec:
|
||||||
|
wg.Done()
|
||||||
return
|
return
|
||||||
case it := <-w.workc:
|
case it := <-w.workc:
|
||||||
w.resc <- w.walk(it.dir, !it.callbackDone)
|
w.resc <- w.walk(it.dir, !it.callbackDone)
|
||||||
|
21
vendor/github.com/mitchellh/go-homedir/LICENSE
generated
vendored
Normal file
21
vendor/github.com/mitchellh/go-homedir/LICENSE
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2013 Mitchell Hashimoto
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
155
vendor/github.com/mitchellh/go-homedir/homedir.go
generated
vendored
Normal file
155
vendor/github.com/mitchellh/go-homedir/homedir.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
package homedir
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DisableCache will disable caching of the home directory. Caching is enabled
|
||||||
|
// by default.
|
||||||
|
var DisableCache bool
|
||||||
|
|
||||||
|
var homedirCache string
|
||||||
|
var cacheLock sync.RWMutex
|
||||||
|
|
||||||
|
// Dir returns the home directory for the executing user.
|
||||||
|
//
|
||||||
|
// This uses an OS-specific method for discovering the home directory.
|
||||||
|
// An error is returned if a home directory cannot be detected.
|
||||||
|
func Dir() (string, error) {
|
||||||
|
if !DisableCache {
|
||||||
|
cacheLock.RLock()
|
||||||
|
cached := homedirCache
|
||||||
|
cacheLock.RUnlock()
|
||||||
|
if cached != "" {
|
||||||
|
return cached, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheLock.Lock()
|
||||||
|
defer cacheLock.Unlock()
|
||||||
|
|
||||||
|
var result string
|
||||||
|
var err error
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
result, err = dirWindows()
|
||||||
|
} else {
|
||||||
|
// Unix-like system, so just assume Unix
|
||||||
|
result, err = dirUnix()
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
homedirCache = result
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expand expands the path to include the home directory if the path
|
||||||
|
// is prefixed with `~`. If it isn't prefixed with `~`, the path is
|
||||||
|
// returned as-is.
|
||||||
|
func Expand(path string) (string, error) {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if path[0] != '~' {
|
||||||
|
return path, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(path) > 1 && path[1] != '/' && path[1] != '\\' {
|
||||||
|
return "", errors.New("cannot expand user-specific home dir")
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, err := Dir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return filepath.Join(dir, path[1:]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dirUnix() (string, error) {
|
||||||
|
homeEnv := "HOME"
|
||||||
|
if runtime.GOOS == "plan9" {
|
||||||
|
// On plan9, env vars are lowercase.
|
||||||
|
homeEnv = "home"
|
||||||
|
}
|
||||||
|
|
||||||
|
// First prefer the HOME environmental variable
|
||||||
|
if home := os.Getenv(homeEnv); home != "" {
|
||||||
|
return home, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var stdout bytes.Buffer
|
||||||
|
|
||||||
|
// If that fails, try OS specific commands
|
||||||
|
if runtime.GOOS == "darwin" {
|
||||||
|
cmd := exec.Command("sh", "-c", `dscl -q . -read /Users/"$(whoami)" NFSHomeDirectory | sed 's/^[^ ]*: //'`)
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
result := strings.TrimSpace(stdout.String())
|
||||||
|
if result != "" {
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cmd := exec.Command("getent", "passwd", strconv.Itoa(os.Getuid()))
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
// If the error is ErrNotFound, we ignore it. Otherwise, return it.
|
||||||
|
if err != exec.ErrNotFound {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if passwd := strings.TrimSpace(stdout.String()); passwd != "" {
|
||||||
|
// username:password:uid:gid:gecos:home:shell
|
||||||
|
passwdParts := strings.SplitN(passwd, ":", 7)
|
||||||
|
if len(passwdParts) > 5 {
|
||||||
|
return passwdParts[5], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If all else fails, try the shell
|
||||||
|
stdout.Reset()
|
||||||
|
cmd := exec.Command("sh", "-c", "cd && pwd")
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := strings.TrimSpace(stdout.String())
|
||||||
|
if result == "" {
|
||||||
|
return "", errors.New("blank output when reading home directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func dirWindows() (string, error) {
|
||||||
|
// First prefer the HOME environmental variable
|
||||||
|
if home := os.Getenv("HOME"); home != "" {
|
||||||
|
return home, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
drive := os.Getenv("HOMEDRIVE")
|
||||||
|
path := os.Getenv("HOMEPATH")
|
||||||
|
home := drive + path
|
||||||
|
if drive == "" || path == "" {
|
||||||
|
home = os.Getenv("USERPROFILE")
|
||||||
|
}
|
||||||
|
if home == "" {
|
||||||
|
return "", errors.New("HOMEDRIVE, HOMEPATH, and USERPROFILE are blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
return home, nil
|
||||||
|
}
|
6
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
6
vendor/golang.org/x/sys/unix/fcntl.go
generated
vendored
@ -14,7 +14,11 @@ var fcntl64Syscall uintptr = SYS_FCNTL
|
|||||||
|
|
||||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||||
valptr, _, err := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
|
valptr, _, errno := Syscall(fcntl64Syscall, fd, uintptr(cmd), uintptr(arg))
|
||||||
|
var err error
|
||||||
|
if errno != 0 {
|
||||||
|
err = errno
|
||||||
|
}
|
||||||
return int(valptr), err
|
return int(valptr), err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
8
vendor/golang.org/x/sys/unix/syscall_bsd.go
generated
vendored
@ -206,7 +206,7 @@ func (sa *SockaddrDatalink) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrDatalink, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
|
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
switch rsa.Addr.Family {
|
switch rsa.Addr.Family {
|
||||||
case AF_LINK:
|
case AF_LINK:
|
||||||
pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
|
pp := (*RawSockaddrDatalink)(unsafe.Pointer(rsa))
|
||||||
@ -286,7 +286,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
|||||||
Close(nfd)
|
Close(nfd)
|
||||||
return 0, nil, ECONNABORTED
|
return 0, nil, ECONNABORTED
|
||||||
}
|
}
|
||||||
sa, err = anyToSockaddr(&rsa)
|
sa, err = anyToSockaddr(fd, &rsa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Close(nfd)
|
Close(nfd)
|
||||||
nfd = 0
|
nfd = 0
|
||||||
@ -306,7 +306,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
|
|||||||
rsa.Addr.Family = AF_UNIX
|
rsa.Addr.Family = AF_UNIX
|
||||||
rsa.Addr.Len = SizeofSockaddrUnix
|
rsa.Addr.Len = SizeofSockaddrUnix
|
||||||
}
|
}
|
||||||
return anyToSockaddr(&rsa)
|
return anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
|
|
||||||
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
//sysnb socketpair(domain int, typ int, proto int, fd *[2]int32) (err error)
|
||||||
@ -356,7 +356,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
|
|||||||
recvflags = int(msg.Flags)
|
recvflags = int(msg.Flags)
|
||||||
// source address is only specified if the socket is unconnected
|
// source address is only specified if the socket is unconnected
|
||||||
if rsa.Addr.Family != AF_UNSPEC {
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
from, err = anyToSockaddr(&rsa)
|
from, err = anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
2
vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
2
vendor/golang.org/x/sys/unix/syscall_dragonfly.go
generated
vendored
@ -87,7 +87,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
|
|||||||
if len > SizeofSockaddrAny {
|
if len > SizeofSockaddrAny {
|
||||||
panic("RawSockaddrAny too small")
|
panic("RawSockaddrAny too small")
|
||||||
}
|
}
|
||||||
sa, err = anyToSockaddr(&rsa)
|
sa, err = anyToSockaddr(fd, &rsa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Close(nfd)
|
Close(nfd)
|
||||||
nfd = 0
|
nfd = 0
|
||||||
|
2
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
2
vendor/golang.org/x/sys/unix/syscall_freebsd.go
generated
vendored
@ -89,7 +89,7 @@ func Accept4(fd, flags int) (nfd int, sa Sockaddr, err error) {
|
|||||||
if len > SizeofSockaddrAny {
|
if len > SizeofSockaddrAny {
|
||||||
panic("RawSockaddrAny too small")
|
panic("RawSockaddrAny too small")
|
||||||
}
|
}
|
||||||
sa, err = anyToSockaddr(&rsa)
|
sa, err = anyToSockaddr(fd, &rsa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Close(nfd)
|
Close(nfd)
|
||||||
nfd = 0
|
nfd = 0
|
||||||
|
75
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
75
vendor/golang.org/x/sys/unix/syscall_linux.go
generated
vendored
@ -489,6 +489,47 @@ func (sa *SockaddrL2) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrL2, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SockaddrRFCOMM implements the Sockaddr interface for AF_BLUETOOTH type sockets
|
||||||
|
// using the RFCOMM protocol.
|
||||||
|
//
|
||||||
|
// Server example:
|
||||||
|
//
|
||||||
|
// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
|
||||||
|
// _ = unix.Bind(fd, &unix.SockaddrRFCOMM{
|
||||||
|
// Channel: 1,
|
||||||
|
// Addr: [6]uint8{0, 0, 0, 0, 0, 0}, // BDADDR_ANY or 00:00:00:00:00:00
|
||||||
|
// })
|
||||||
|
// _ = Listen(fd, 1)
|
||||||
|
// nfd, sa, _ := Accept(fd)
|
||||||
|
// fmt.Printf("conn addr=%v fd=%d", sa.(*unix.SockaddrRFCOMM).Addr, nfd)
|
||||||
|
// Read(nfd, buf)
|
||||||
|
//
|
||||||
|
// Client example:
|
||||||
|
//
|
||||||
|
// fd, _ := Socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)
|
||||||
|
// _ = Connect(fd, &SockaddrRFCOMM{
|
||||||
|
// Channel: 1,
|
||||||
|
// Addr: [6]byte{0x11, 0x22, 0x33, 0xaa, 0xbb, 0xcc}, // CC:BB:AA:33:22:11
|
||||||
|
// })
|
||||||
|
// Write(fd, []byte(`hello`))
|
||||||
|
type SockaddrRFCOMM struct {
|
||||||
|
// Addr represents a bluetooth address, byte ordering is little-endian.
|
||||||
|
Addr [6]uint8
|
||||||
|
|
||||||
|
// Channel is a designated bluetooth channel, only 1-30 are available for use.
|
||||||
|
// Since Linux 2.6.7 and further zero value is the first available channel.
|
||||||
|
Channel uint8
|
||||||
|
|
||||||
|
raw RawSockaddrRFCOMM
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sa *SockaddrRFCOMM) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
||||||
|
sa.raw.Family = AF_BLUETOOTH
|
||||||
|
sa.raw.Channel = sa.Channel
|
||||||
|
sa.raw.Bdaddr = sa.Addr
|
||||||
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrRFCOMM, nil
|
||||||
|
}
|
||||||
|
|
||||||
// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
|
// SockaddrCAN implements the Sockaddr interface for AF_CAN type sockets.
|
||||||
// The RxID and TxID fields are used for transport protocol addressing in
|
// The RxID and TxID fields are used for transport protocol addressing in
|
||||||
// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
|
// (CAN_TP16, CAN_TP20, CAN_MCNET, and CAN_ISOTP), they can be left with
|
||||||
@ -651,7 +692,7 @@ func (sa *SockaddrVM) sockaddr() (unsafe.Pointer, _Socklen, error) {
|
|||||||
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
|
return unsafe.Pointer(&sa.raw), SizeofSockaddrVM, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
|
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
switch rsa.Addr.Family {
|
switch rsa.Addr.Family {
|
||||||
case AF_NETLINK:
|
case AF_NETLINK:
|
||||||
pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
|
pp := (*RawSockaddrNetlink)(unsafe.Pointer(rsa))
|
||||||
@ -728,6 +769,30 @@ func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
|
|||||||
Port: pp.Port,
|
Port: pp.Port,
|
||||||
}
|
}
|
||||||
return sa, nil
|
return sa, nil
|
||||||
|
case AF_BLUETOOTH:
|
||||||
|
proto, err := GetsockoptInt(fd, SOL_SOCKET, SO_PROTOCOL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// only BTPROTO_L2CAP and BTPROTO_RFCOMM can accept connections
|
||||||
|
switch proto {
|
||||||
|
case BTPROTO_L2CAP:
|
||||||
|
pp := (*RawSockaddrL2)(unsafe.Pointer(rsa))
|
||||||
|
sa := &SockaddrL2{
|
||||||
|
PSM: pp.Psm,
|
||||||
|
CID: pp.Cid,
|
||||||
|
Addr: pp.Bdaddr,
|
||||||
|
AddrType: pp.Bdaddr_type,
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
case BTPROTO_RFCOMM:
|
||||||
|
pp := (*RawSockaddrRFCOMM)(unsafe.Pointer(rsa))
|
||||||
|
sa := &SockaddrRFCOMM{
|
||||||
|
Channel: pp.Channel,
|
||||||
|
Addr: pp.Bdaddr,
|
||||||
|
}
|
||||||
|
return sa, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil, EAFNOSUPPORT
|
return nil, EAFNOSUPPORT
|
||||||
}
|
}
|
||||||
@ -739,7 +804,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sa, err = anyToSockaddr(&rsa)
|
sa, err = anyToSockaddr(fd, &rsa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Close(nfd)
|
Close(nfd)
|
||||||
nfd = 0
|
nfd = 0
|
||||||
@ -757,7 +822,7 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) {
|
|||||||
if len > SizeofSockaddrAny {
|
if len > SizeofSockaddrAny {
|
||||||
panic("RawSockaddrAny too small")
|
panic("RawSockaddrAny too small")
|
||||||
}
|
}
|
||||||
sa, err = anyToSockaddr(&rsa)
|
sa, err = anyToSockaddr(fd, &rsa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Close(nfd)
|
Close(nfd)
|
||||||
nfd = 0
|
nfd = 0
|
||||||
@ -771,7 +836,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
|
|||||||
if err = getsockname(fd, &rsa, &len); err != nil {
|
if err = getsockname(fd, &rsa, &len); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return anyToSockaddr(&rsa)
|
return anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
|
func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
|
||||||
@ -960,7 +1025,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
|
|||||||
recvflags = int(msg.Flags)
|
recvflags = int(msg.Flags)
|
||||||
// source address is only specified if the socket is unconnected
|
// source address is only specified if the socket is unconnected
|
||||||
if rsa.Addr.Family != AF_UNSPEC {
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
from, err = anyToSockaddr(&rsa)
|
from, err = anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
14
vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
14
vendor/golang.org/x/sys/unix/syscall_solaris.go
generated
vendored
@ -112,7 +112,7 @@ func Getsockname(fd int) (sa Sockaddr, err error) {
|
|||||||
if err = getsockname(fd, &rsa, &len); err != nil {
|
if err = getsockname(fd, &rsa, &len); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return anyToSockaddr(&rsa)
|
return anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetsockoptString returns the string value of the socket option opt for the
|
// GetsockoptString returns the string value of the socket option opt for the
|
||||||
@ -314,7 +314,11 @@ func UtimesNanoAt(dirfd int, path string, ts []Timespec, flags int) error {
|
|||||||
|
|
||||||
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
// FcntlInt performs a fcntl syscall on fd with the provided command and argument.
|
||||||
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
func FcntlInt(fd uintptr, cmd, arg int) (int, error) {
|
||||||
valptr, _, err := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
|
valptr, _, errno := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0)
|
||||||
|
var err error
|
||||||
|
if errno != 0 {
|
||||||
|
err = errno
|
||||||
|
}
|
||||||
return int(valptr), err
|
return int(valptr), err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +360,7 @@ func Futimes(fd int, tv []Timeval) error {
|
|||||||
return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
return futimesat(fd, nil, (*[2]Timeval)(unsafe.Pointer(&tv[0])))
|
||||||
}
|
}
|
||||||
|
|
||||||
func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
|
func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) {
|
||||||
switch rsa.Addr.Family {
|
switch rsa.Addr.Family {
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
|
pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
|
||||||
@ -407,7 +411,7 @@ func Accept(fd int) (nfd int, sa Sockaddr, err error) {
|
|||||||
if nfd == -1 {
|
if nfd == -1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sa, err = anyToSockaddr(&rsa)
|
sa, err = anyToSockaddr(fd, &rsa)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Close(nfd)
|
Close(nfd)
|
||||||
nfd = 0
|
nfd = 0
|
||||||
@ -444,7 +448,7 @@ func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from
|
|||||||
oobn = int(msg.Accrightslen)
|
oobn = int(msg.Accrightslen)
|
||||||
// source address is only specified if the socket is unconnected
|
// source address is only specified if the socket is unconnected
|
||||||
if rsa.Addr.Family != AF_UNSPEC {
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
from, err = anyToSockaddr(&rsa)
|
from, err = anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
4
vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
4
vendor/golang.org/x/sys/unix/syscall_unix.go
generated
vendored
@ -219,7 +219,7 @@ func Getpeername(fd int) (sa Sockaddr, err error) {
|
|||||||
if err = getpeername(fd, &rsa, &len); err != nil {
|
if err = getpeername(fd, &rsa, &len); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return anyToSockaddr(&rsa)
|
return anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
|
func GetsockoptByte(fd, level, opt int) (value byte, err error) {
|
||||||
@ -291,7 +291,7 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if rsa.Addr.Family != AF_UNSPEC {
|
if rsa.Addr.Family != AF_UNSPEC {
|
||||||
from, err = anyToSockaddr(&rsa)
|
from, err = anyToSockaddr(fd, &rsa)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
30
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
generated
vendored
30
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
generated
vendored
@ -1474,6 +1474,21 @@ func Munlockall() (err error) {
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func faccessat(dirfd int, path string, mode uint32) (err error) {
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Dup2(oldfd int, newfd int) (err error) {
|
func Dup2(oldfd int, newfd int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
|
_, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
@ -1495,21 +1510,6 @@ func EpollCreate(size int) (fd int, err error) {
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func faccessat(dirfd int, path string, mode uint32) (err error) {
|
|
||||||
var _p0 *byte
|
|
||||||
_p0, err = BytePtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(events) > 0 {
|
if len(events) > 0 {
|
||||||
|
30
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
generated
vendored
30
vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
generated
vendored
@ -1474,6 +1474,21 @@ func Munlockall() (err error) {
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
|
func faccessat(dirfd int, path string, mode uint32) (err error) {
|
||||||
|
var _p0 *byte
|
||||||
|
_p0, err = BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func Dup2(oldfd int, newfd int) (err error) {
|
func Dup2(oldfd int, newfd int) (err error) {
|
||||||
_, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
|
_, _, e1 := Syscall(SYS_DUP2, uintptr(oldfd), uintptr(newfd), 0)
|
||||||
if e1 != 0 {
|
if e1 != 0 {
|
||||||
@ -1495,21 +1510,6 @@ func EpollCreate(size int) (fd int, err error) {
|
|||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||||
|
|
||||||
func faccessat(dirfd int, path string, mode uint32) (err error) {
|
|
||||||
var _p0 *byte
|
|
||||||
_p0, err = BytePtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
_, _, e1 := Syscall(SYS_FACCESSAT, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode))
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
|
||||||
|
|
||||||
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
func EpollWait(epfd int, events []EpollEvent, msec int) (n int, err error) {
|
||||||
var _p0 unsafe.Pointer
|
var _p0 unsafe.Pointer
|
||||||
if len(events) > 0 {
|
if len(events) > 0 {
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_386.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_386.go
generated
vendored
@ -248,6 +248,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -401,6 +408,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_amd64.go
generated
vendored
@ -250,6 +250,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -405,6 +412,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_arm.go
generated
vendored
@ -251,6 +251,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -404,6 +411,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_arm64.go
generated
vendored
@ -251,6 +251,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -406,6 +413,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_mips.go
generated
vendored
@ -249,6 +249,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -402,6 +409,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_mips64.go
generated
vendored
@ -251,6 +251,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -406,6 +413,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_mips64le.go
generated
vendored
@ -251,6 +251,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -406,6 +413,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_mipsle.go
generated
vendored
@ -249,6 +249,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -402,6 +409,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64.go
generated
vendored
@ -252,6 +252,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -407,6 +414,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_ppc64le.go
generated
vendored
@ -252,6 +252,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -407,6 +414,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
8
vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
generated
vendored
8
vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
generated
vendored
@ -250,6 +250,13 @@ type RawSockaddrL2 struct {
|
|||||||
_ [1]byte
|
_ [1]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RawSockaddrRFCOMM struct {
|
||||||
|
Family uint16
|
||||||
|
Bdaddr [6]uint8
|
||||||
|
Channel uint8
|
||||||
|
_ [1]byte
|
||||||
|
}
|
||||||
|
|
||||||
type RawSockaddrCAN struct {
|
type RawSockaddrCAN struct {
|
||||||
Family uint16
|
Family uint16
|
||||||
_ [2]byte
|
_ [2]byte
|
||||||
@ -405,6 +412,7 @@ const (
|
|||||||
SizeofSockaddrNetlink = 0xc
|
SizeofSockaddrNetlink = 0xc
|
||||||
SizeofSockaddrHCI = 0x6
|
SizeofSockaddrHCI = 0x6
|
||||||
SizeofSockaddrL2 = 0xe
|
SizeofSockaddrL2 = 0xe
|
||||||
|
SizeofSockaddrRFCOMM = 0xa
|
||||||
SizeofSockaddrCAN = 0x10
|
SizeofSockaddrCAN = 0x10
|
||||||
SizeofSockaddrALG = 0x58
|
SizeofSockaddrALG = 0x58
|
||||||
SizeofSockaddrVM = 0x10
|
SizeofSockaddrVM = 0x10
|
||||||
|
18
vendor/golang.org/x/sys/windows/service.go
generated
vendored
18
vendor/golang.org/x/sys/windows/service.go
generated
vendored
@ -43,6 +43,11 @@ const (
|
|||||||
|
|
||||||
SC_STATUS_PROCESS_INFO = 0
|
SC_STATUS_PROCESS_INFO = 0
|
||||||
|
|
||||||
|
SC_ACTION_NONE = 0
|
||||||
|
SC_ACTION_RESTART = 1
|
||||||
|
SC_ACTION_REBOOT = 2
|
||||||
|
SC_ACTION_RUN_COMMAND = 3
|
||||||
|
|
||||||
SERVICE_STOPPED = 1
|
SERVICE_STOPPED = 1
|
||||||
SERVICE_START_PENDING = 2
|
SERVICE_START_PENDING = 2
|
||||||
SERVICE_STOP_PENDING = 3
|
SERVICE_STOP_PENDING = 3
|
||||||
@ -148,6 +153,19 @@ type ENUM_SERVICE_STATUS_PROCESS struct {
|
|||||||
ServiceStatusProcess SERVICE_STATUS_PROCESS
|
ServiceStatusProcess SERVICE_STATUS_PROCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SERVICE_FAILURE_ACTIONS struct {
|
||||||
|
ResetPeriod uint32
|
||||||
|
RebootMsg *uint16
|
||||||
|
Command *uint16
|
||||||
|
ActionsCount uint32
|
||||||
|
Actions *SC_ACTION
|
||||||
|
}
|
||||||
|
|
||||||
|
type SC_ACTION struct {
|
||||||
|
Type uint32
|
||||||
|
Delay uint32
|
||||||
|
}
|
||||||
|
|
||||||
//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle
|
//sys CloseServiceHandle(handle Handle) (err error) = advapi32.CloseServiceHandle
|
||||||
//sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW
|
//sys CreateService(mgr Handle, serviceName *uint16, displayName *uint16, access uint32, srvType uint32, startType uint32, errCtl uint32, pathName *uint16, loadOrderGroup *uint16, tagId *uint32, dependencies *uint16, serviceStartName *uint16, password *uint16) (handle Handle, err error) [failretval==0] = advapi32.CreateServiceW
|
||||||
//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW
|
//sys OpenService(mgr Handle, serviceName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenServiceW
|
||||||
|
33
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
33
vendor/golang.org/x/sys/windows/types_windows.go
generated
vendored
@ -94,16 +94,29 @@ const (
|
|||||||
FILE_APPEND_DATA = 0x00000004
|
FILE_APPEND_DATA = 0x00000004
|
||||||
FILE_WRITE_ATTRIBUTES = 0x00000100
|
FILE_WRITE_ATTRIBUTES = 0x00000100
|
||||||
|
|
||||||
FILE_SHARE_READ = 0x00000001
|
FILE_SHARE_READ = 0x00000001
|
||||||
FILE_SHARE_WRITE = 0x00000002
|
FILE_SHARE_WRITE = 0x00000002
|
||||||
FILE_SHARE_DELETE = 0x00000004
|
FILE_SHARE_DELETE = 0x00000004
|
||||||
FILE_ATTRIBUTE_READONLY = 0x00000001
|
|
||||||
FILE_ATTRIBUTE_HIDDEN = 0x00000002
|
FILE_ATTRIBUTE_READONLY = 0x00000001
|
||||||
FILE_ATTRIBUTE_SYSTEM = 0x00000004
|
FILE_ATTRIBUTE_HIDDEN = 0x00000002
|
||||||
FILE_ATTRIBUTE_DIRECTORY = 0x00000010
|
FILE_ATTRIBUTE_SYSTEM = 0x00000004
|
||||||
FILE_ATTRIBUTE_ARCHIVE = 0x00000020
|
FILE_ATTRIBUTE_DIRECTORY = 0x00000010
|
||||||
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
FILE_ATTRIBUTE_ARCHIVE = 0x00000020
|
||||||
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
|
FILE_ATTRIBUTE_DEVICE = 0x00000040
|
||||||
|
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
||||||
|
FILE_ATTRIBUTE_TEMPORARY = 0x00000100
|
||||||
|
FILE_ATTRIBUTE_SPARSE_FILE = 0x00000200
|
||||||
|
FILE_ATTRIBUTE_REPARSE_POINT = 0x00000400
|
||||||
|
FILE_ATTRIBUTE_COMPRESSED = 0x00000800
|
||||||
|
FILE_ATTRIBUTE_OFFLINE = 0x00001000
|
||||||
|
FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x00002000
|
||||||
|
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
|
||||||
|
FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x00008000
|
||||||
|
FILE_ATTRIBUTE_VIRTUAL = 0x00010000
|
||||||
|
FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x00020000
|
||||||
|
FILE_ATTRIBUTE_RECALL_ON_OPEN = 0x00040000
|
||||||
|
FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS = 0x00400000
|
||||||
|
|
||||||
INVALID_FILE_ATTRIBUTES = 0xffffffff
|
INVALID_FILE_ATTRIBUTES = 0xffffffff
|
||||||
|
|
||||||
|
2
vendor/mvdan.cc/sh/interp/builtin.go
vendored
2
vendor/mvdan.cc/sh/interp/builtin.go
vendored
@ -290,7 +290,7 @@ func (r *Runner) builtinCode(pos syntax.Pos, name string, args []string) int {
|
|||||||
if parseErr {
|
if parseErr {
|
||||||
return 2
|
return 2
|
||||||
}
|
}
|
||||||
return oneIf(r.bashTest(expr) == "")
|
return oneIf(r.bashTest(expr, true) == "")
|
||||||
case "exec":
|
case "exec":
|
||||||
// TODO: Consider syscall.Exec, i.e. actually replacing
|
// TODO: Consider syscall.Exec, i.e. actually replacing
|
||||||
// the process. It's in theory what a shell should do,
|
// the process. It's in theory what a shell should do,
|
||||||
|
2
vendor/mvdan.cc/sh/interp/doc.go
vendored
2
vendor/mvdan.cc/sh/interp/doc.go
vendored
@ -7,4 +7,4 @@
|
|||||||
//
|
//
|
||||||
// This package is a work in progress and EXPERIMENTAL; its API is not
|
// This package is a work in progress and EXPERIMENTAL; its API is not
|
||||||
// subject to the 1.x backwards compatibility guarantee.
|
// subject to the 1.x backwards compatibility guarantee.
|
||||||
package interp // import "mvdan.cc/sh/interp"
|
package interp
|
||||||
|
2
vendor/mvdan.cc/sh/interp/expand.go
vendored
2
vendor/mvdan.cc/sh/interp/expand.go
vendored
@ -247,7 +247,7 @@ func (r *Runner) wordField(wps []syntax.WordPart, ql quoteLevel) []fieldPart {
|
|||||||
case '\n': // remove \\\n
|
case '\n': // remove \\\n
|
||||||
i++
|
i++
|
||||||
continue
|
continue
|
||||||
case '\\', '$', '`': // special chars
|
case '"', '\\', '$', '`': // special chars
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
vendor/mvdan.cc/sh/interp/interp.go
vendored
2
vendor/mvdan.cc/sh/interp/interp.go
vendored
@ -602,7 +602,7 @@ func (r *Runner) cmd(cm syntax.Command) {
|
|||||||
}
|
}
|
||||||
case *syntax.TestClause:
|
case *syntax.TestClause:
|
||||||
r.exit = 0
|
r.exit = 0
|
||||||
if r.bashTest(x.X) == "" && r.exit == 0 {
|
if r.bashTest(x.X, false) == "" && r.exit == 0 {
|
||||||
// to preserve exit code 2 for regex
|
// to preserve exit code 2 for regex
|
||||||
// errors, etc
|
// errors, etc
|
||||||
r.exit = 1
|
r.exit = 1
|
||||||
|
21
vendor/mvdan.cc/sh/interp/test.go
vendored
21
vendor/mvdan.cc/sh/interp/test.go
vendored
@ -15,29 +15,36 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// non-empty string is true, empty string is false
|
// non-empty string is true, empty string is false
|
||||||
func (r *Runner) bashTest(expr syntax.TestExpr) string {
|
func (r *Runner) bashTest(expr syntax.TestExpr, classic bool) string {
|
||||||
switch x := expr.(type) {
|
switch x := expr.(type) {
|
||||||
case *syntax.Word:
|
case *syntax.Word:
|
||||||
return r.loneWord(x)
|
return r.loneWord(x)
|
||||||
case *syntax.ParenTest:
|
case *syntax.ParenTest:
|
||||||
return r.bashTest(x.X)
|
return r.bashTest(x.X, classic)
|
||||||
case *syntax.BinaryTest:
|
case *syntax.BinaryTest:
|
||||||
switch x.Op {
|
switch x.Op {
|
||||||
case syntax.TsMatch, syntax.TsNoMatch:
|
case syntax.TsMatch, syntax.TsNoMatch:
|
||||||
str := r.loneWord(x.X.(*syntax.Word))
|
str := r.loneWord(x.X.(*syntax.Word))
|
||||||
yw := x.Y.(*syntax.Word)
|
yw := x.Y.(*syntax.Word)
|
||||||
pat := r.lonePattern(yw)
|
if classic { // test, [
|
||||||
if match(pat, str) == (x.Op == syntax.TsMatch) {
|
lit := r.loneWord(yw)
|
||||||
return "1"
|
if (str == lit) == (x.Op == syntax.TsMatch) {
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
|
} else { // [[
|
||||||
|
pat := r.lonePattern(yw)
|
||||||
|
if match(pat, str) == (x.Op == syntax.TsMatch) {
|
||||||
|
return "1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
if r.binTest(x.Op, r.bashTest(x.X), r.bashTest(x.Y)) {
|
if r.binTest(x.Op, r.bashTest(x.X, classic), r.bashTest(x.Y, classic)) {
|
||||||
return "1"
|
return "1"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
case *syntax.UnaryTest:
|
case *syntax.UnaryTest:
|
||||||
if r.unTest(x.Op, r.bashTest(x.X)) {
|
if r.unTest(x.Op, r.bashTest(x.X, classic)) {
|
||||||
return "1"
|
return "1"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
2
vendor/mvdan.cc/sh/shell/doc.go
vendored
2
vendor/mvdan.cc/sh/shell/doc.go
vendored
@ -6,4 +6,4 @@
|
|||||||
//
|
//
|
||||||
// This package is a work in progress and EXPERIMENTAL; its API is not
|
// This package is a work in progress and EXPERIMENTAL; its API is not
|
||||||
// subject to the 1.x backwards compatibility guarantee.
|
// subject to the 1.x backwards compatibility guarantee.
|
||||||
package shell // import "mvdan.cc/sh/shell"
|
package shell
|
||||||
|
16
vendor/mvdan.cc/sh/shell/expand.go
vendored
16
vendor/mvdan.cc/sh/shell/expand.go
vendored
@ -4,6 +4,7 @@
|
|||||||
package shell
|
package shell
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"mvdan.cc/sh/interp"
|
"mvdan.cc/sh/interp"
|
||||||
@ -19,23 +20,28 @@ import (
|
|||||||
//
|
//
|
||||||
// Any side effects or modifications to the system are forbidden when
|
// Any side effects or modifications to the system are forbidden when
|
||||||
// interpreting the program. This is enforced via whitelists when
|
// interpreting the program. This is enforced via whitelists when
|
||||||
// executing programs and opening paths.
|
// executing programs and opening paths. The interpreter also has a timeout of
|
||||||
|
// two seconds.
|
||||||
func Expand(s string, env func(string) string) (string, error) {
|
func Expand(s string, env func(string) string) (string, error) {
|
||||||
p := syntax.NewParser()
|
p := syntax.NewParser()
|
||||||
src := "<<EOF\n" + s + "\nEOF"
|
src := "<<EXPAND_EOF\n" + s + "\nEXPAND_EOF"
|
||||||
f, err := p.Parse(strings.NewReader(src), "")
|
f, err := p.Parse(strings.NewReader(src), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
word := f.Stmts[0].Redirs[0].Hdoc
|
word := f.Stmts[0].Redirs[0].Hdoc
|
||||||
|
last := word.Parts[len(word.Parts)-1].(*syntax.Lit)
|
||||||
|
// since the heredoc implies a trailing newline
|
||||||
|
last.Value = strings.TrimSuffix(last.Value, "\n")
|
||||||
r := pureRunner()
|
r := pureRunner()
|
||||||
if env != nil {
|
if env != nil {
|
||||||
r.Env = interp.FuncEnviron(env)
|
r.Env = interp.FuncEnviron(env)
|
||||||
}
|
}
|
||||||
r.Reset()
|
r.Reset()
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), pureRunnerTimeout)
|
||||||
|
defer cancel()
|
||||||
|
r.Context = ctx
|
||||||
fields := r.Fields(word)
|
fields := r.Fields(word)
|
||||||
// TODO: runner error
|
// TODO: runner error
|
||||||
join := strings.Join(fields, "")
|
return strings.Join(fields, ""), nil
|
||||||
// since the heredoc implies a trailing newline
|
|
||||||
return strings.TrimSuffix(join, "\n"), nil
|
|
||||||
}
|
}
|
||||||
|
10
vendor/mvdan.cc/sh/shell/source.go
vendored
10
vendor/mvdan.cc/sh/shell/source.go
vendored
@ -4,9 +4,11 @@
|
|||||||
package shell
|
package shell
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"mvdan.cc/sh/interp"
|
"mvdan.cc/sh/interp"
|
||||||
"mvdan.cc/sh/syntax"
|
"mvdan.cc/sh/syntax"
|
||||||
@ -44,6 +46,8 @@ var purePrograms = []string{
|
|||||||
"env", "sleep", "uniq", "sort",
|
"env", "sleep", "uniq", "sort",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pureRunnerTimeout = 2 * time.Second
|
||||||
|
|
||||||
func pureRunner() *interp.Runner {
|
func pureRunner() *interp.Runner {
|
||||||
r := &interp.Runner{}
|
r := &interp.Runner{}
|
||||||
// forbid executing programs that might cause trouble
|
// forbid executing programs that might cause trouble
|
||||||
@ -67,10 +71,14 @@ func pureRunner() *interp.Runner {
|
|||||||
//
|
//
|
||||||
// Any side effects or modifications to the system are forbidden when
|
// Any side effects or modifications to the system are forbidden when
|
||||||
// interpreting the program. This is enforced via whitelists when
|
// interpreting the program. This is enforced via whitelists when
|
||||||
// executing programs and opening paths.
|
// executing programs and opening paths. The interpreter also has a timeout of
|
||||||
|
// two seconds.
|
||||||
func SourceNode(node syntax.Node) (map[string]interp.Variable, error) {
|
func SourceNode(node syntax.Node) (map[string]interp.Variable, error) {
|
||||||
r := pureRunner()
|
r := pureRunner()
|
||||||
r.Reset()
|
r.Reset()
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), pureRunnerTimeout)
|
||||||
|
defer cancel()
|
||||||
|
r.Context = ctx
|
||||||
if err := r.Run(node); err != nil {
|
if err := r.Run(node); err != nil {
|
||||||
return nil, fmt.Errorf("could not run: %v", err)
|
return nil, fmt.Errorf("could not run: %v", err)
|
||||||
}
|
}
|
||||||
|
2
vendor/mvdan.cc/sh/syntax/doc.go
vendored
2
vendor/mvdan.cc/sh/syntax/doc.go
vendored
@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Package syntax implements parsing and formatting of shell programs.
|
// Package syntax implements parsing and formatting of shell programs.
|
||||||
// It supports both POSIX Shell and Bash.
|
// It supports both POSIX Shell and Bash.
|
||||||
package syntax // import "mvdan.cc/sh/syntax"
|
package syntax
|
||||||
|
15
vendor/mvdan.cc/sh/syntax/lexer.go
vendored
15
vendor/mvdan.cc/sh/syntax/lexer.go
vendored
@ -107,6 +107,7 @@ retry:
|
|||||||
} else if p.fill(); p.bs == nil {
|
} else if p.fill(); p.bs == nil {
|
||||||
p.bsp++
|
p.bsp++
|
||||||
p.r = utf8.RuneSelf
|
p.r = utf8.RuneSelf
|
||||||
|
p.w = 1
|
||||||
} else {
|
} else {
|
||||||
goto retry
|
goto retry
|
||||||
}
|
}
|
||||||
@ -232,6 +233,7 @@ skipSpace:
|
|||||||
w := utf8.RuneLen(r)
|
w := utf8.RuneLen(r)
|
||||||
if bytes.HasPrefix(p.bs[p.bsp-w:], p.stopAt) {
|
if bytes.HasPrefix(p.bs[p.bsp-w:], p.stopAt) {
|
||||||
p.r = utf8.RuneSelf
|
p.r = utf8.RuneSelf
|
||||||
|
p.w = 1
|
||||||
p.tok = _EOF
|
p.tok = _EOF
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -748,10 +750,13 @@ func (p *Parser) endLit() (s string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Parser) numLit() bool {
|
func (p *Parser) isLitRedir() bool {
|
||||||
for _, b := range p.litBs {
|
lit := p.litBs[:len(p.litBs)-1]
|
||||||
|
if lit[0] == '{' && lit[len(lit)-1] == '}' {
|
||||||
|
return ValidName(string(lit[1 : len(lit)-1]))
|
||||||
|
}
|
||||||
|
for _, b := range lit {
|
||||||
switch b {
|
switch b {
|
||||||
case '>', '<':
|
|
||||||
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
@ -800,7 +805,7 @@ loop:
|
|||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
case '/':
|
case '/':
|
||||||
if p.quote&allParamExp != 0 && p.quote != paramExpExp {
|
if p.quote != paramExpExp {
|
||||||
break loop
|
break loop
|
||||||
}
|
}
|
||||||
case ':', '=', '%', '^', ',', '?', '!', '*':
|
case ':', '=', '%', '^', ',', '?', '!', '*':
|
||||||
@ -838,7 +843,7 @@ loop:
|
|||||||
p.discardLit(2)
|
p.discardLit(2)
|
||||||
}
|
}
|
||||||
case '>', '<':
|
case '>', '<':
|
||||||
if p.peekByte('(') || !p.numLit() {
|
if p.peekByte('(') || !p.isLitRedir() {
|
||||||
tok = _Lit
|
tok = _Lit
|
||||||
} else {
|
} else {
|
||||||
tok = _LitRedir
|
tok = _LitRedir
|
||||||
|
2
vendor/mvdan.cc/sh/syntax/nodes.go
vendored
2
vendor/mvdan.cc/sh/syntax/nodes.go
vendored
@ -232,7 +232,7 @@ func (a *Assign) End() Pos {
|
|||||||
type Redirect struct {
|
type Redirect struct {
|
||||||
OpPos Pos
|
OpPos Pos
|
||||||
Op RedirOperator
|
Op RedirOperator
|
||||||
N *Lit // N>, must be a number
|
N *Lit // fd>, or {varname}> in Bash
|
||||||
Word *Word // >word
|
Word *Word // >word
|
||||||
Hdoc *Word // here-document body
|
Hdoc *Word // here-document body
|
||||||
}
|
}
|
||||||
|
111
vendor/mvdan.cc/sh/syntax/parser.go
vendored
111
vendor/mvdan.cc/sh/syntax/parser.go
vendored
@ -30,6 +30,18 @@ func Variant(l LangVariant) func(*Parser) {
|
|||||||
return func(p *Parser) { p.lang = l }
|
return func(p *Parser) { p.lang = l }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l LangVariant) String() string {
|
||||||
|
switch l {
|
||||||
|
case LangBash:
|
||||||
|
return "bash"
|
||||||
|
case LangPOSIX:
|
||||||
|
return "posix"
|
||||||
|
case LangMirBSDKorn:
|
||||||
|
return "mksh"
|
||||||
|
}
|
||||||
|
return "unknown shell language variant"
|
||||||
|
}
|
||||||
|
|
||||||
// StopAt configures the lexer to stop at an arbitrary word, treating it
|
// StopAt configures the lexer to stop at an arbitrary word, treating it
|
||||||
// as if it were the end of the input. It can contain any characters
|
// as if it were the end of the input. It can contain any characters
|
||||||
// except whitespace, and cannot be over four bytes in size.
|
// except whitespace, and cannot be over four bytes in size.
|
||||||
@ -480,26 +492,60 @@ func (p *Parser) errPass(err error) {
|
|||||||
p.err = err
|
p.err = err
|
||||||
p.bsp = len(p.bs) + 1
|
p.bsp = len(p.bs) + 1
|
||||||
p.r = utf8.RuneSelf
|
p.r = utf8.RuneSelf
|
||||||
|
p.w = 1
|
||||||
p.tok = _EOF
|
p.tok = _EOF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseError represents an error found when parsing a source file.
|
// ParseError represents an error found when parsing a source file, from which
|
||||||
|
// the parser cannot recover.
|
||||||
type ParseError struct {
|
type ParseError struct {
|
||||||
Filename string
|
Filename string
|
||||||
Pos
|
Pos
|
||||||
Text string
|
Text string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ParseError) Error() string {
|
func (e ParseError) Error() string {
|
||||||
if e.Filename == "" {
|
if e.Filename == "" {
|
||||||
return fmt.Sprintf("%s: %s", e.Pos.String(), e.Text)
|
return fmt.Sprintf("%s: %s", e.Pos.String(), e.Text)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s:%s: %s", e.Filename, e.Pos.String(), e.Text)
|
return fmt.Sprintf("%s:%s: %s", e.Filename, e.Pos.String(), e.Text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LangError is returned when the parser encounters code that is only valid in
|
||||||
|
// other shell language variants. The error includes what feature is not present
|
||||||
|
// in the current language variant, and what languages support it.
|
||||||
|
type LangError struct {
|
||||||
|
Filename string
|
||||||
|
Pos
|
||||||
|
Feature string
|
||||||
|
Langs []LangVariant
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e LangError) Error() string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
if e.Filename != "" {
|
||||||
|
buf.WriteString(e.Filename + ":")
|
||||||
|
}
|
||||||
|
buf.WriteString(e.Pos.String() + ": ")
|
||||||
|
buf.WriteString(e.Feature)
|
||||||
|
if strings.HasSuffix(e.Feature, "s") {
|
||||||
|
buf.WriteString(" are a ")
|
||||||
|
} else {
|
||||||
|
buf.WriteString(" is a ")
|
||||||
|
}
|
||||||
|
for i, lang := range e.Langs {
|
||||||
|
if i > 0 {
|
||||||
|
buf.WriteString("/")
|
||||||
|
}
|
||||||
|
buf.WriteString(lang.String())
|
||||||
|
}
|
||||||
|
buf.WriteString(" feature")
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Parser) posErr(pos Pos, format string, a ...interface{}) {
|
func (p *Parser) posErr(pos Pos, format string, a ...interface{}) {
|
||||||
p.errPass(&ParseError{
|
p.errPass(ParseError{
|
||||||
Filename: p.f.Name,
|
Filename: p.f.Name,
|
||||||
Pos: pos,
|
Pos: pos,
|
||||||
Text: fmt.Sprintf(format, a...),
|
Text: fmt.Sprintf(format, a...),
|
||||||
@ -510,6 +556,15 @@ func (p *Parser) curErr(format string, a ...interface{}) {
|
|||||||
p.posErr(p.pos, format, a...)
|
p.posErr(p.pos, format, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Parser) langErr(pos Pos, feature string, langs ...LangVariant) {
|
||||||
|
p.errPass(LangError{
|
||||||
|
Filename: p.f.Name,
|
||||||
|
Pos: pos,
|
||||||
|
Feature: feature,
|
||||||
|
Langs: langs,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Parser) stmts(fn func(*Stmt) bool, stops ...string) {
|
func (p *Parser) stmts(fn func(*Stmt) bool, stops ...string) {
|
||||||
gotEnd := true
|
gotEnd := true
|
||||||
loop:
|
loop:
|
||||||
@ -668,7 +723,7 @@ func (p *Parser) wordPart() WordPart {
|
|||||||
p.next()
|
p.next()
|
||||||
if p.got(hash) {
|
if p.got(hash) {
|
||||||
if p.lang != LangMirBSDKorn {
|
if p.lang != LangMirBSDKorn {
|
||||||
p.posErr(ar.Pos(), "unsigned expressions are a mksh feature")
|
p.langErr(ar.Pos(), "unsigned expressions", LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
ar.Unsigned = true
|
ar.Unsigned = true
|
||||||
}
|
}
|
||||||
@ -712,9 +767,16 @@ func (p *Parser) wordPart() WordPart {
|
|||||||
p.pos = posAddCol(p.pos, 1)
|
p.pos = posAddCol(p.pos, 1)
|
||||||
pe.Param = p.getLit()
|
pe.Param = p.getLit()
|
||||||
if pe.Param != nil && pe.Param.Value == "" {
|
if pe.Param != nil && pe.Param.Value == "" {
|
||||||
// e.g. "$\\\n", which we can't detect above
|
|
||||||
l := p.lit(pe.Dollar, "$")
|
l := p.lit(pe.Dollar, "$")
|
||||||
p.next()
|
if p.val == "" {
|
||||||
|
// e.g. "$\\\n" followed by a closing double
|
||||||
|
// quote, so we need the next token.
|
||||||
|
p.next()
|
||||||
|
} else {
|
||||||
|
// e.g. "$\\\"" within double quotes, so we must
|
||||||
|
// keep the rest of the literal characters.
|
||||||
|
l.ValueEnd = posAddCol(l.ValuePos, 1)
|
||||||
|
}
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
return pe
|
return pe
|
||||||
@ -777,7 +839,7 @@ func (p *Parser) wordPart() WordPart {
|
|||||||
return cs
|
return cs
|
||||||
case globQuest, globStar, globPlus, globAt, globExcl:
|
case globQuest, globStar, globPlus, globAt, globExcl:
|
||||||
if p.lang == LangPOSIX {
|
if p.lang == LangPOSIX {
|
||||||
p.curErr("extended globs are a bash feature")
|
p.langErr(p.pos, "extended globs", LangBash, LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
eg := &ExtGlob{Op: GlobOperator(p.tok), OpPos: p.pos}
|
eg := &ExtGlob{Op: GlobOperator(p.tok), OpPos: p.pos}
|
||||||
lparens := 1
|
lparens := 1
|
||||||
@ -1058,7 +1120,7 @@ func (p *Parser) paramExp() *ParamExp {
|
|||||||
case exclMark:
|
case exclMark:
|
||||||
if paramNameOp(p.r) {
|
if paramNameOp(p.r) {
|
||||||
if p.lang == LangPOSIX {
|
if p.lang == LangPOSIX {
|
||||||
p.curErr("${!foo} is a bash feature")
|
p.langErr(p.pos, "${!foo}", LangBash, LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
pe.Excl = true
|
pe.Excl = true
|
||||||
p.next()
|
p.next()
|
||||||
@ -1067,6 +1129,9 @@ func (p *Parser) paramExp() *ParamExp {
|
|||||||
op := p.tok
|
op := p.tok
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case _Lit, _LitWord:
|
case _Lit, _LitWord:
|
||||||
|
if !numberLiteral(p.val) && !ValidName(p.val) {
|
||||||
|
p.curErr("invalid parameter name")
|
||||||
|
}
|
||||||
pe.Param = p.lit(p.pos, p.val)
|
pe.Param = p.lit(p.pos, p.val)
|
||||||
p.next()
|
p.next()
|
||||||
case quest, minus:
|
case quest, minus:
|
||||||
@ -1093,7 +1158,7 @@ func (p *Parser) paramExp() *ParamExp {
|
|||||||
return pe
|
return pe
|
||||||
case leftBrack:
|
case leftBrack:
|
||||||
if p.lang == LangPOSIX {
|
if p.lang == LangPOSIX {
|
||||||
p.curErr("arrays are a bash feature")
|
p.langErr(p.pos, "arrays", LangBash, LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
if !ValidName(pe.Param.Value) {
|
if !ValidName(pe.Param.Value) {
|
||||||
p.curErr("cannot index a special parameter name")
|
p.curErr("cannot index a special parameter name")
|
||||||
@ -1113,7 +1178,7 @@ func (p *Parser) paramExp() *ParamExp {
|
|||||||
case slash, dblSlash:
|
case slash, dblSlash:
|
||||||
// pattern search and replace
|
// pattern search and replace
|
||||||
if p.lang == LangPOSIX {
|
if p.lang == LangPOSIX {
|
||||||
p.curErr("search and replace is a bash feature")
|
p.langErr(p.pos, "search and replace", LangBash, LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
pe.Repl = &Replace{All: p.tok == dblSlash}
|
pe.Repl = &Replace{All: p.tok == dblSlash}
|
||||||
p.quote = paramExpRepl
|
p.quote = paramExpRepl
|
||||||
@ -1126,7 +1191,7 @@ func (p *Parser) paramExp() *ParamExp {
|
|||||||
case colon:
|
case colon:
|
||||||
// slicing
|
// slicing
|
||||||
if p.lang == LangPOSIX {
|
if p.lang == LangPOSIX {
|
||||||
p.curErr("slicing is a bash feature")
|
p.langErr(p.pos, "slicing", LangBash, LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
pe.Slice = &Slice{}
|
pe.Slice = &Slice{}
|
||||||
colonPos := p.pos
|
colonPos := p.pos
|
||||||
@ -1141,13 +1206,13 @@ func (p *Parser) paramExp() *ParamExp {
|
|||||||
case caret, dblCaret, comma, dblComma:
|
case caret, dblCaret, comma, dblComma:
|
||||||
// upper/lower case
|
// upper/lower case
|
||||||
if p.lang != LangBash {
|
if p.lang != LangBash {
|
||||||
p.curErr("this expansion operator is a bash feature")
|
p.langErr(p.pos, "this expansion operator", LangBash)
|
||||||
}
|
}
|
||||||
pe.Exp = p.paramExpExp()
|
pe.Exp = p.paramExpExp()
|
||||||
case at, star:
|
case at, star:
|
||||||
switch {
|
switch {
|
||||||
case p.tok == at && p.lang == LangPOSIX:
|
case p.tok == at && p.lang == LangPOSIX:
|
||||||
p.curErr("this expansion operator is a bash feature")
|
p.langErr(p.pos, "this expansion operator", LangBash, LangMirBSDKorn)
|
||||||
case p.tok == star && !pe.Excl:
|
case p.tok == star && !pe.Excl:
|
||||||
p.curErr("not a valid parameter expansion operator: %v", p.tok)
|
p.curErr("not a valid parameter expansion operator: %v", p.tok)
|
||||||
case pe.Excl:
|
case pe.Excl:
|
||||||
@ -1252,6 +1317,15 @@ func ValidName(val string) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func numberLiteral(val string) bool {
|
||||||
|
for _, r := range val {
|
||||||
|
if '0' > r || r > '9' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Parser) hasValidIdent() bool {
|
func (p *Parser) hasValidIdent() bool {
|
||||||
if p.tok != _Lit && p.tok != _LitWord {
|
if p.tok != _Lit && p.tok != _LitWord {
|
||||||
return false
|
return false
|
||||||
@ -1319,7 +1393,7 @@ func (p *Parser) getAssign(needEqual bool) *Assign {
|
|||||||
}
|
}
|
||||||
if as.Value == nil && p.tok == leftParen {
|
if as.Value == nil && p.tok == leftParen {
|
||||||
if p.lang == LangPOSIX {
|
if p.lang == LangPOSIX {
|
||||||
p.curErr("arrays are a bash feature")
|
p.langErr(p.pos, "arrays", LangBash, LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
if as.Index != nil {
|
if as.Index != nil {
|
||||||
p.curErr("arrays cannot be nested")
|
p.curErr("arrays cannot be nested")
|
||||||
@ -1394,6 +1468,9 @@ func (p *Parser) doRedirect(s *Stmt) {
|
|||||||
s.Redirs = append(s.Redirs, r)
|
s.Redirs = append(s.Redirs, r)
|
||||||
}
|
}
|
||||||
r.N = p.getLit()
|
r.N = p.getLit()
|
||||||
|
if p.lang != LangBash && r.N != nil && r.N.Value[0] == '{' {
|
||||||
|
p.langErr(r.N.Pos(), "{varname} redirects", LangBash)
|
||||||
|
}
|
||||||
r.Op, r.OpPos = RedirOperator(p.tok), p.pos
|
r.Op, r.OpPos = RedirOperator(p.tok), p.pos
|
||||||
p.next()
|
p.next()
|
||||||
switch r.Op {
|
switch r.Op {
|
||||||
@ -1643,7 +1720,7 @@ func (p *Parser) arithmExpCmd(s *Stmt) {
|
|||||||
p.next()
|
p.next()
|
||||||
if p.got(hash) {
|
if p.got(hash) {
|
||||||
if p.lang != LangMirBSDKorn {
|
if p.lang != LangMirBSDKorn {
|
||||||
p.posErr(ar.Pos(), "unsigned expressions are a mksh feature")
|
p.langErr(ar.Pos(), "unsigned expressions", LangMirBSDKorn)
|
||||||
}
|
}
|
||||||
ar.Unsigned = true
|
ar.Unsigned = true
|
||||||
}
|
}
|
||||||
@ -1725,7 +1802,7 @@ func (p *Parser) loop(fpos Pos) Loop {
|
|||||||
if p.lang != LangBash {
|
if p.lang != LangBash {
|
||||||
switch p.tok {
|
switch p.tok {
|
||||||
case leftParen, dblLeftParen:
|
case leftParen, dblLeftParen:
|
||||||
p.curErr("c-style fors are a bash feature")
|
p.langErr(p.pos, "c-style fors", LangBash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if p.tok == dblLeftParen {
|
if p.tok == dblLeftParen {
|
||||||
@ -1909,7 +1986,7 @@ func (p *Parser) testExpr(ftok token, fpos Pos, pastAndOr bool) TestExpr {
|
|||||||
}
|
}
|
||||||
case TsReMatch:
|
case TsReMatch:
|
||||||
if p.lang != LangBash {
|
if p.lang != LangBash {
|
||||||
p.curErr("regex tests are a bash feature")
|
p.langErr(p.pos, "regex tests", LangBash)
|
||||||
}
|
}
|
||||||
oldReOpenParens := p.reOpenParens
|
oldReOpenParens := p.reOpenParens
|
||||||
old := p.preNested(testRegexp)
|
old := p.preNested(testRegexp)
|
||||||
|
77
vendor/mvdan.cc/sh/syntax/printer.go
vendored
77
vendor/mvdan.cc/sh/syntax/printer.go
vendored
@ -68,17 +68,12 @@ func NewPrinter(options ...func(*Printer)) *Printer {
|
|||||||
func (p *Printer) Print(w io.Writer, node Node) error {
|
func (p *Printer) Print(w io.Writer, node Node) error {
|
||||||
p.reset()
|
p.reset()
|
||||||
p.bufWriter.Reset(w)
|
p.bufWriter.Reset(w)
|
||||||
p.line = node.Pos().Line()
|
|
||||||
switch x := node.(type) {
|
switch x := node.(type) {
|
||||||
case *File:
|
case *File:
|
||||||
p.stmts(x.StmtList)
|
p.stmtList(x.StmtList)
|
||||||
p.newline(x.End())
|
p.newline(x.End())
|
||||||
case *Stmt:
|
case *Stmt:
|
||||||
sl := StmtList{Stmts: []*Stmt{x}}
|
p.stmtList(StmtList{Stmts: []*Stmt{x}})
|
||||||
// StmtList.pos is better than Stmt.Pos, since it also takes
|
|
||||||
// comments into account.
|
|
||||||
p.line = sl.pos().Line()
|
|
||||||
p.stmts(sl)
|
|
||||||
case *Word:
|
case *Word:
|
||||||
p.word(x)
|
p.word(x)
|
||||||
case Command:
|
case Command:
|
||||||
@ -152,6 +147,8 @@ type Printer struct {
|
|||||||
// comment in the same line, breaking programs.
|
// comment in the same line, breaking programs.
|
||||||
pendingComments []Comment
|
pendingComments []Comment
|
||||||
|
|
||||||
|
// firstLine means we are still writing the first line
|
||||||
|
firstLine bool
|
||||||
// line is the current line number
|
// line is the current line number
|
||||||
line uint
|
line uint
|
||||||
|
|
||||||
@ -180,7 +177,11 @@ func (p *Printer) reset() {
|
|||||||
p.wantSpace, p.wantNewline = false, false
|
p.wantSpace, p.wantNewline = false, false
|
||||||
p.commentPadding = 0
|
p.commentPadding = 0
|
||||||
p.pendingComments = p.pendingComments[:0]
|
p.pendingComments = p.pendingComments[:0]
|
||||||
|
|
||||||
|
// minification uses its own newline logic
|
||||||
|
p.firstLine = !p.minify
|
||||||
p.line = 0
|
p.line = 0
|
||||||
|
|
||||||
p.lastLevel, p.level = 0, 0
|
p.lastLevel, p.level = 0, 0
|
||||||
p.levelIncs = p.levelIncs[:0]
|
p.levelIncs = p.levelIncs[:0]
|
||||||
p.nestedBinary = false
|
p.nestedBinary = false
|
||||||
@ -354,7 +355,8 @@ func (p *Printer) flushHeredocs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Printer) newlines(pos Pos) {
|
func (p *Printer) newlines(pos Pos) {
|
||||||
if !p.wantNewline && p.line == 0 && len(p.pendingComments) == 0 {
|
if p.firstLine && len(p.pendingComments) == 0 {
|
||||||
|
p.firstLine = false
|
||||||
return // no empty lines at the top
|
return // no empty lines at the top
|
||||||
}
|
}
|
||||||
if !p.wantNewline && pos.Line() <= p.line {
|
if !p.wantNewline && pos.Line() <= p.line {
|
||||||
@ -379,11 +381,11 @@ func (p *Printer) rightParen(pos Pos) {
|
|||||||
p.wantSpace = true
|
p.wantSpace = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Printer) semiRsrv(s string, pos Pos, fallback bool) {
|
func (p *Printer) semiRsrv(s string, pos Pos) {
|
||||||
if p.wantNewline || pos.Line() > p.line {
|
if p.wantNewline || pos.Line() > p.line {
|
||||||
p.newlines(pos)
|
p.newlines(pos)
|
||||||
} else {
|
} else {
|
||||||
if fallback && !p.wroteSemi {
|
if !p.wroteSemi {
|
||||||
p.WriteByte(';')
|
p.WriteByte(';')
|
||||||
}
|
}
|
||||||
if !p.minify {
|
if !p.minify {
|
||||||
@ -403,6 +405,9 @@ func (p *Printer) comment(c Comment) {
|
|||||||
|
|
||||||
func (p *Printer) flushComments() {
|
func (p *Printer) flushComments() {
|
||||||
for i, c := range p.pendingComments {
|
for i, c := range p.pendingComments {
|
||||||
|
p.firstLine = false
|
||||||
|
// We can't call any of the newline methods, as they call this
|
||||||
|
// function and we'd recurse forever.
|
||||||
cline := c.Hash.Line()
|
cline := c.Hash.Line()
|
||||||
switch {
|
switch {
|
||||||
case i > 0, cline > p.line && p.line > 0:
|
case i > 0, cline > p.line && p.line > 0:
|
||||||
@ -430,6 +435,9 @@ func (p *Printer) flushComments() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Printer) comments(cs []Comment) {
|
func (p *Printer) comments(cs []Comment) {
|
||||||
|
if p.minify {
|
||||||
|
return
|
||||||
|
}
|
||||||
p.pendingComments = append(p.pendingComments, cs...)
|
p.pendingComments = append(p.pendingComments, cs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,12 +473,12 @@ func (p *Printer) wordPart(wp, next WordPart) {
|
|||||||
p.wantSpace = true
|
p.wantSpace = true
|
||||||
p.nestedStmts(x.StmtList, x.Right)
|
p.nestedStmts(x.StmtList, x.Right)
|
||||||
p.wantSpace = false
|
p.wantSpace = false
|
||||||
p.semiRsrv("}", x.Right, true)
|
p.semiRsrv("}", x.Right)
|
||||||
case x.ReplyVar:
|
case x.ReplyVar:
|
||||||
p.WriteString("${|")
|
p.WriteString("${|")
|
||||||
p.nestedStmts(x.StmtList, x.Right)
|
p.nestedStmts(x.StmtList, x.Right)
|
||||||
p.wantSpace = false
|
p.wantSpace = false
|
||||||
p.semiRsrv("}", x.Right, true)
|
p.semiRsrv("}", x.Right)
|
||||||
default:
|
default:
|
||||||
p.WriteString("$(")
|
p.WriteString("$(")
|
||||||
p.wantSpace = len(x.Stmts) > 0 && startsWithLparen(x.Stmts[0])
|
p.wantSpace = len(x.Stmts) > 0 && startsWithLparen(x.Stmts[0])
|
||||||
@ -478,14 +486,19 @@ func (p *Printer) wordPart(wp, next WordPart) {
|
|||||||
p.rightParen(x.Right)
|
p.rightParen(x.Right)
|
||||||
}
|
}
|
||||||
case *ParamExp:
|
case *ParamExp:
|
||||||
nextLit, ok := next.(*Lit)
|
|
||||||
litCont := ";"
|
litCont := ";"
|
||||||
if ok {
|
if nextLit, ok := next.(*Lit); ok {
|
||||||
litCont = nextLit.Value[:1]
|
litCont = nextLit.Value[:1]
|
||||||
}
|
}
|
||||||
if p.minify && !x.Excl && !x.Length && !x.Width &&
|
name := x.Param.Value
|
||||||
x.Index == nil && x.Slice == nil && x.Repl == nil &&
|
switch {
|
||||||
x.Exp == nil && !ValidName(x.Param.Value+litCont) {
|
case !p.minify:
|
||||||
|
case x.Excl, x.Length, x.Width:
|
||||||
|
case x.Index != nil, x.Slice != nil:
|
||||||
|
case x.Repl != nil, x.Exp != nil:
|
||||||
|
case len(name) > 1 && !ValidName(name): // ${10}
|
||||||
|
case ValidName(name + litCont): // ${var}cont
|
||||||
|
default:
|
||||||
x2 := *x
|
x2 := *x
|
||||||
x2.Short = true
|
x2.Short = true
|
||||||
p.paramExp(&x2)
|
p.paramExp(&x2)
|
||||||
@ -510,7 +523,7 @@ func (p *Printer) wordPart(wp, next WordPart) {
|
|||||||
}
|
}
|
||||||
p.WriteString(x.Op.String())
|
p.WriteString(x.Op.String())
|
||||||
p.nestedStmts(x.StmtList, x.Rparen)
|
p.nestedStmts(x.StmtList, x.Rparen)
|
||||||
p.WriteByte(')')
|
p.rightParen(x.Rparen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,6 +788,7 @@ func (p *Printer) elemJoin(elems []*ArrayElem, last []Comment) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Printer) stmt(s *Stmt) {
|
func (p *Printer) stmt(s *Stmt) {
|
||||||
|
p.wroteSemi = false
|
||||||
if s.Negated {
|
if s.Negated {
|
||||||
p.spacedString("!", s.Pos())
|
p.spacedString("!", s.Pos())
|
||||||
}
|
}
|
||||||
@ -787,8 +801,7 @@ func (p *Printer) stmt(s *Stmt) {
|
|||||||
if r.OpPos.Line() > p.line {
|
if r.OpPos.Line() > p.line {
|
||||||
p.bslashNewl()
|
p.bslashNewl()
|
||||||
}
|
}
|
||||||
if p.minify && r.N == nil {
|
if p.wantSpace {
|
||||||
} else if p.wantSpace {
|
|
||||||
p.spacePad(r.Pos())
|
p.spacePad(r.Pos())
|
||||||
}
|
}
|
||||||
if r.N != nil {
|
if r.N != nil {
|
||||||
@ -805,7 +818,6 @@ func (p *Printer) stmt(s *Stmt) {
|
|||||||
p.pendingHdocs = append(p.pendingHdocs, r)
|
p.pendingHdocs = append(p.pendingHdocs, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.wroteSemi = false
|
|
||||||
switch {
|
switch {
|
||||||
case s.Semicolon.IsValid() && s.Semicolon.Line() > p.line:
|
case s.Semicolon.IsValid() && s.Semicolon.Line() > p.line:
|
||||||
p.bslashNewl()
|
p.bslashNewl()
|
||||||
@ -839,8 +851,7 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
|||||||
if r.Pos().After(x.Args[1].Pos()) || r.Op == Hdoc || r.Op == DashHdoc {
|
if r.Pos().After(x.Args[1].Pos()) || r.Op == Hdoc || r.Op == DashHdoc {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if p.minify && r.N == nil {
|
if p.wantSpace {
|
||||||
} else if p.wantSpace {
|
|
||||||
p.spacePad(r.Pos())
|
p.spacePad(r.Pos())
|
||||||
}
|
}
|
||||||
if r.N != nil {
|
if r.N != nil {
|
||||||
@ -860,7 +871,7 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
|||||||
p.WriteByte('{')
|
p.WriteByte('{')
|
||||||
p.wantSpace = true
|
p.wantSpace = true
|
||||||
p.nestedStmts(x.StmtList, x.Rbrace)
|
p.nestedStmts(x.StmtList, x.Rbrace)
|
||||||
p.semiRsrv("}", x.Rbrace, true)
|
p.semiRsrv("}", x.Rbrace)
|
||||||
case *IfClause:
|
case *IfClause:
|
||||||
p.ifClause(x, false)
|
p.ifClause(x, false)
|
||||||
case *Subshell:
|
case *Subshell:
|
||||||
@ -880,7 +891,7 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
|||||||
p.nestedStmts(x.Cond, Pos{})
|
p.nestedStmts(x.Cond, Pos{})
|
||||||
p.semiOrNewl("do", x.DoPos)
|
p.semiOrNewl("do", x.DoPos)
|
||||||
p.nestedStmts(x.Do, x.DonePos)
|
p.nestedStmts(x.Do, x.DonePos)
|
||||||
p.semiRsrv("done", x.DonePos, true)
|
p.semiRsrv("done", x.DonePos)
|
||||||
case *ForClause:
|
case *ForClause:
|
||||||
if x.Select {
|
if x.Select {
|
||||||
p.WriteString("select ")
|
p.WriteString("select ")
|
||||||
@ -890,7 +901,7 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
|||||||
p.loop(x.Loop)
|
p.loop(x.Loop)
|
||||||
p.semiOrNewl("do", x.DoPos)
|
p.semiOrNewl("do", x.DoPos)
|
||||||
p.nestedStmts(x.Do, x.DonePos)
|
p.nestedStmts(x.Do, x.DonePos)
|
||||||
p.semiRsrv("done", x.DonePos, true)
|
p.semiRsrv("done", x.DonePos)
|
||||||
case *BinaryCmd:
|
case *BinaryCmd:
|
||||||
p.stmt(x.X)
|
p.stmt(x.X)
|
||||||
if p.minify || x.Y.Pos().Line() <= p.line {
|
if p.minify || x.Y.Pos().Line() <= p.line {
|
||||||
@ -973,6 +984,8 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
|||||||
p.wantNewline = true
|
p.wantNewline = true
|
||||||
}
|
}
|
||||||
p.spacedToken(ci.Op.String(), ci.OpPos)
|
p.spacedToken(ci.Op.String(), ci.OpPos)
|
||||||
|
// avoid ; directly after tokens like ;;
|
||||||
|
p.wroteSemi = true
|
||||||
if inlineCom != nil {
|
if inlineCom != nil {
|
||||||
p.comment(*inlineCom)
|
p.comment(*inlineCom)
|
||||||
}
|
}
|
||||||
@ -984,7 +997,7 @@ func (p *Printer) command(cmd Command, redirs []*Redirect) (startRedirs int) {
|
|||||||
p.flushComments()
|
p.flushComments()
|
||||||
p.decLevel()
|
p.decLevel()
|
||||||
}
|
}
|
||||||
p.semiRsrv("esac", x.Esac, len(x.Items) == 0)
|
p.semiRsrv("esac", x.Esac)
|
||||||
case *ArithmCmd:
|
case *ArithmCmd:
|
||||||
p.WriteString("((")
|
p.WriteString("((")
|
||||||
if x.Unsigned {
|
if x.Unsigned {
|
||||||
@ -1037,17 +1050,17 @@ func (p *Printer) ifClause(ic *IfClause, elif bool) {
|
|||||||
p.semiOrNewl("then", ic.ThenPos)
|
p.semiOrNewl("then", ic.ThenPos)
|
||||||
p.nestedStmts(ic.Then, ic.bodyEndPos())
|
p.nestedStmts(ic.Then, ic.bodyEndPos())
|
||||||
if ic.FollowedByElif() {
|
if ic.FollowedByElif() {
|
||||||
p.semiRsrv("elif", ic.ElsePos, true)
|
p.semiRsrv("elif", ic.ElsePos)
|
||||||
p.ifClause(ic.Else.Stmts[0].Cmd.(*IfClause), true)
|
p.ifClause(ic.Else.Stmts[0].Cmd.(*IfClause), true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !ic.Else.empty() {
|
if !ic.Else.empty() {
|
||||||
p.semiRsrv("else", ic.ElsePos, true)
|
p.semiRsrv("else", ic.ElsePos)
|
||||||
p.nestedStmts(ic.Else, ic.FiPos)
|
p.nestedStmts(ic.Else, ic.FiPos)
|
||||||
} else if ic.ElsePos.IsValid() {
|
} else if ic.ElsePos.IsValid() {
|
||||||
p.line = ic.ElsePos.Line()
|
p.line = ic.ElsePos.Line()
|
||||||
}
|
}
|
||||||
p.semiRsrv("fi", ic.FiPos, true)
|
p.semiRsrv("fi", ic.FiPos)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startsWithLparen(s *Stmt) bool {
|
func startsWithLparen(s *Stmt) bool {
|
||||||
@ -1069,7 +1082,7 @@ func (p *Printer) hasInline(s *Stmt) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Printer) stmts(sl StmtList) {
|
func (p *Printer) stmtList(sl StmtList) {
|
||||||
sep := p.wantNewline ||
|
sep := p.wantNewline ||
|
||||||
(len(sl.Stmts) > 0 && sl.Stmts[0].Pos().Line() > p.line)
|
(len(sl.Stmts) > 0 && sl.Stmts[0].Pos().Line() > p.line)
|
||||||
inlineIndent := 0
|
inlineIndent := 0
|
||||||
@ -1216,7 +1229,7 @@ func (p *Printer) nestedStmts(sl StmtList, closing Pos) {
|
|||||||
// do foo; done
|
// do foo; done
|
||||||
p.wantNewline = true
|
p.wantNewline = true
|
||||||
}
|
}
|
||||||
p.stmts(sl)
|
p.stmtList(sl)
|
||||||
if closing.IsValid() {
|
if closing.IsValid() {
|
||||||
p.flushComments()
|
p.flushComments()
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user