Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
songlinfeng
container-toolkit
Commits
d7e13eb9
Commit
d7e13eb9
authored
Oct 22, 2025
by
songlinfeng
Browse files
add dtk-container-toolkit
parent
fcdba4f3
Changes
345
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2904 additions
and
0 deletions
+2904
-0
vendor/github.com/sirupsen/logrus/writer.go
vendor/github.com/sirupsen/logrus/writer.go
+102
-0
vendor/github.com/syndtr/gocapability/LICENSE
vendor/github.com/syndtr/gocapability/LICENSE
+24
-0
vendor/github.com/syndtr/gocapability/capability/capability.go
...r/github.com/syndtr/gocapability/capability/capability.go
+133
-0
vendor/github.com/syndtr/gocapability/capability/capability_linux.go
...ub.com/syndtr/gocapability/capability/capability_linux.go
+642
-0
vendor/github.com/syndtr/gocapability/capability/capability_noop.go
...hub.com/syndtr/gocapability/capability/capability_noop.go
+19
-0
vendor/github.com/syndtr/gocapability/capability/enum.go
vendor/github.com/syndtr/gocapability/capability/enum.go
+309
-0
vendor/github.com/syndtr/gocapability/capability/enum_gen.go
vendor/github.com/syndtr/gocapability/capability/enum_gen.go
+138
-0
vendor/github.com/syndtr/gocapability/capability/syscall_linux.go
...ithub.com/syndtr/gocapability/capability/syscall_linux.go
+154
-0
vendor/github.com/urfave/cli/v2/.flake8
vendor/github.com/urfave/cli/v2/.flake8
+2
-0
vendor/github.com/urfave/cli/v2/.gitignore
vendor/github.com/urfave/cli/v2/.gitignore
+14
-0
vendor/github.com/urfave/cli/v2/.golangci.yaml
vendor/github.com/urfave/cli/v2/.golangci.yaml
+4
-0
vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md
vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md
+75
-0
vendor/github.com/urfave/cli/v2/LICENSE
vendor/github.com/urfave/cli/v2/LICENSE
+21
-0
vendor/github.com/urfave/cli/v2/Makefile
vendor/github.com/urfave/cli/v2/Makefile
+26
-0
vendor/github.com/urfave/cli/v2/README.md
vendor/github.com/urfave/cli/v2/README.md
+19
-0
vendor/github.com/urfave/cli/v2/app.go
vendor/github.com/urfave/cli/v2/app.go
+536
-0
vendor/github.com/urfave/cli/v2/args.go
vendor/github.com/urfave/cli/v2/args.go
+54
-0
vendor/github.com/urfave/cli/v2/category.go
vendor/github.com/urfave/cli/v2/category.go
+186
-0
vendor/github.com/urfave/cli/v2/cli.go
vendor/github.com/urfave/cli/v2/cli.go
+25
-0
vendor/github.com/urfave/cli/v2/command.go
vendor/github.com/urfave/cli/v2/command.go
+421
-0
No files found.
Too many changes to show.
To preserve performance only
345 of 345+
files are displayed.
Plain diff
Email patch
vendor/github.com/sirupsen/logrus/writer.go
0 → 100644
View file @
d7e13eb9
package
logrus
import
(
"bufio"
"io"
"runtime"
"strings"
)
// Writer at INFO level. See WriterLevel for details.
func
(
logger
*
Logger
)
Writer
()
*
io
.
PipeWriter
{
return
logger
.
WriterLevel
(
InfoLevel
)
}
// WriterLevel returns an io.Writer that can be used to write arbitrary text to
// the logger at the given log level. Each line written to the writer will be
// printed in the usual way using formatters and hooks. The writer is part of an
// io.Pipe and it is the callers responsibility to close the writer when done.
// This can be used to override the standard library logger easily.
func
(
logger
*
Logger
)
WriterLevel
(
level
Level
)
*
io
.
PipeWriter
{
return
NewEntry
(
logger
)
.
WriterLevel
(
level
)
}
// Writer returns an io.Writer that writes to the logger at the info log level
func
(
entry
*
Entry
)
Writer
()
*
io
.
PipeWriter
{
return
entry
.
WriterLevel
(
InfoLevel
)
}
// WriterLevel returns an io.Writer that writes to the logger at the given log level
func
(
entry
*
Entry
)
WriterLevel
(
level
Level
)
*
io
.
PipeWriter
{
reader
,
writer
:=
io
.
Pipe
()
var
printFunc
func
(
args
...
interface
{})
// Determine which log function to use based on the specified log level
switch
level
{
case
TraceLevel
:
printFunc
=
entry
.
Trace
case
DebugLevel
:
printFunc
=
entry
.
Debug
case
InfoLevel
:
printFunc
=
entry
.
Info
case
WarnLevel
:
printFunc
=
entry
.
Warn
case
ErrorLevel
:
printFunc
=
entry
.
Error
case
FatalLevel
:
printFunc
=
entry
.
Fatal
case
PanicLevel
:
printFunc
=
entry
.
Panic
default
:
printFunc
=
entry
.
Print
}
// Start a new goroutine to scan the input and write it to the logger using the specified print function.
// It splits the input into chunks of up to 64KB to avoid buffer overflows.
go
entry
.
writerScanner
(
reader
,
printFunc
)
// Set a finalizer function to close the writer when it is garbage collected
runtime
.
SetFinalizer
(
writer
,
writerFinalizer
)
return
writer
}
// writerScanner scans the input from the reader and writes it to the logger
func
(
entry
*
Entry
)
writerScanner
(
reader
*
io
.
PipeReader
,
printFunc
func
(
args
...
interface
{}))
{
scanner
:=
bufio
.
NewScanner
(
reader
)
// Set the buffer size to the maximum token size to avoid buffer overflows
scanner
.
Buffer
(
make
([]
byte
,
bufio
.
MaxScanTokenSize
),
bufio
.
MaxScanTokenSize
)
// Define a split function to split the input into chunks of up to 64KB
chunkSize
:=
bufio
.
MaxScanTokenSize
// 64KB
splitFunc
:=
func
(
data
[]
byte
,
atEOF
bool
)
(
int
,
[]
byte
,
error
)
{
if
len
(
data
)
>=
chunkSize
{
return
chunkSize
,
data
[
:
chunkSize
],
nil
}
return
bufio
.
ScanLines
(
data
,
atEOF
)
}
// Use the custom split function to split the input
scanner
.
Split
(
splitFunc
)
// Scan the input and write it to the logger using the specified print function
for
scanner
.
Scan
()
{
printFunc
(
strings
.
TrimRight
(
scanner
.
Text
(),
"
\r\n
"
))
}
// If there was an error while scanning the input, log an error
if
err
:=
scanner
.
Err
();
err
!=
nil
{
entry
.
Errorf
(
"Error while reading from Writer: %s"
,
err
)
}
// Close the reader when we are done
reader
.
Close
()
}
// WriterFinalizer is a finalizer function that closes then given writer when it is garbage collected
func
writerFinalizer
(
writer
*
io
.
PipeWriter
)
{
writer
.
Close
()
}
vendor/github.com/syndtr/gocapability/LICENSE
0 → 100644
View file @
d7e13eb9
Copyright 2013 Suryandaru Triandana <syndtr@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
vendor/github.com/syndtr/gocapability/capability/capability.go
0 → 100644
View file @
d7e13eb9
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Package capability provides utilities for manipulating POSIX capabilities.
package
capability
type
Capabilities
interface
{
// Get check whether a capability present in the given
// capabilities set. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Get
(
which
CapType
,
what
Cap
)
bool
// Empty check whether all capability bits of the given capabilities
// set are zero. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Empty
(
which
CapType
)
bool
// Full check whether all capability bits of the given capabilities
// set are one. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Full
(
which
CapType
)
bool
// Set sets capabilities of the given capabilities sets. The
// 'which' value should be one or combination (OR'ed) of EFFECTIVE,
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Set
(
which
CapType
,
caps
...
Cap
)
// Unset unsets capabilities of the given capabilities sets. The
// 'which' value should be one or combination (OR'ed) of EFFECTIVE,
// PERMITTED, INHERITABLE, BOUNDING or AMBIENT.
Unset
(
which
CapType
,
caps
...
Cap
)
// Fill sets all bits of the given capabilities kind to one. The
// 'kind' value should be one or combination (OR'ed) of CAPS,
// BOUNDS or AMBS.
Fill
(
kind
CapType
)
// Clear sets all bits of the given capabilities kind to zero. The
// 'kind' value should be one or combination (OR'ed) of CAPS,
// BOUNDS or AMBS.
Clear
(
kind
CapType
)
// String return current capabilities state of the given capabilities
// set as string. The 'which' value should be one of EFFECTIVE,
// PERMITTED, INHERITABLE BOUNDING or AMBIENT
StringCap
(
which
CapType
)
string
// String return current capabilities state as string.
String
()
string
// Load load actual capabilities value. This will overwrite all
// outstanding changes.
Load
()
error
// Apply apply the capabilities settings, so all changes will take
// effect.
Apply
(
kind
CapType
)
error
}
// NewPid initializes a new Capabilities object for given pid when
// it is nonzero, or for the current process if pid is 0.
//
// Deprecated: Replace with NewPid2. For example, replace:
//
// c, err := NewPid(0)
// if err != nil {
// return err
// }
//
// with:
//
// c, err := NewPid2(0)
// if err != nil {
// return err
// }
// err = c.Load()
// if err != nil {
// return err
// }
func
NewPid
(
pid
int
)
(
Capabilities
,
error
)
{
c
,
err
:=
newPid
(
pid
)
if
err
!=
nil
{
return
c
,
err
}
err
=
c
.
Load
()
return
c
,
err
}
// NewPid2 initializes a new Capabilities object for given pid when
// it is nonzero, or for the current process if pid is 0. This
// does not load the process's current capabilities; to do that you
// must call Load explicitly.
func
NewPid2
(
pid
int
)
(
Capabilities
,
error
)
{
return
newPid
(
pid
)
}
// NewFile initializes a new Capabilities object for given file path.
//
// Deprecated: Replace with NewFile2. For example, replace:
//
// c, err := NewFile(path)
// if err != nil {
// return err
// }
//
// with:
//
// c, err := NewFile2(path)
// if err != nil {
// return err
// }
// err = c.Load()
// if err != nil {
// return err
// }
func
NewFile
(
path
string
)
(
Capabilities
,
error
)
{
c
,
err
:=
newFile
(
path
)
if
err
!=
nil
{
return
c
,
err
}
err
=
c
.
Load
()
return
c
,
err
}
// NewFile2 creates a new initialized Capabilities object for given
// file path. This does not load the process's current capabilities;
// to do that you must call Load explicitly.
func
NewFile2
(
path
string
)
(
Capabilities
,
error
)
{
return
newFile
(
path
)
}
vendor/github.com/syndtr/gocapability/capability/capability_linux.go
0 → 100644
View file @
d7e13eb9
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package
capability
import
(
"bufio"
"errors"
"fmt"
"io"
"os"
"strings"
"syscall"
)
var
errUnknownVers
=
errors
.
New
(
"unknown capability version"
)
const
(
linuxCapVer1
=
0x19980330
linuxCapVer2
=
0x20071026
linuxCapVer3
=
0x20080522
)
var
(
capVers
uint32
capLastCap
Cap
)
func
init
()
{
var
hdr
capHeader
capget
(
&
hdr
,
nil
)
capVers
=
hdr
.
version
if
initLastCap
()
==
nil
{
CAP_LAST_CAP
=
capLastCap
if
capLastCap
>
31
{
capUpperMask
=
(
uint32
(
1
)
<<
(
uint
(
capLastCap
)
-
31
))
-
1
}
else
{
capUpperMask
=
0
}
}
}
func
initLastCap
()
error
{
if
capLastCap
!=
0
{
return
nil
}
f
,
err
:=
os
.
Open
(
"/proc/sys/kernel/cap_last_cap"
)
if
err
!=
nil
{
return
err
}
defer
f
.
Close
()
var
b
[]
byte
=
make
([]
byte
,
11
)
_
,
err
=
f
.
Read
(
b
)
if
err
!=
nil
{
return
err
}
fmt
.
Sscanf
(
string
(
b
),
"%d"
,
&
capLastCap
)
return
nil
}
func
mkStringCap
(
c
Capabilities
,
which
CapType
)
(
ret
string
)
{
for
i
,
first
:=
Cap
(
0
),
true
;
i
<=
CAP_LAST_CAP
;
i
++
{
if
!
c
.
Get
(
which
,
i
)
{
continue
}
if
first
{
first
=
false
}
else
{
ret
+=
", "
}
ret
+=
i
.
String
()
}
return
}
func
mkString
(
c
Capabilities
,
max
CapType
)
(
ret
string
)
{
ret
=
"{"
for
i
:=
CapType
(
1
);
i
<=
max
;
i
<<=
1
{
ret
+=
" "
+
i
.
String
()
+
"=
\"
"
if
c
.
Empty
(
i
)
{
ret
+=
"empty"
}
else
if
c
.
Full
(
i
)
{
ret
+=
"full"
}
else
{
ret
+=
c
.
StringCap
(
i
)
}
ret
+=
"
\"
"
}
ret
+=
" }"
return
}
func
newPid
(
pid
int
)
(
c
Capabilities
,
err
error
)
{
switch
capVers
{
case
linuxCapVer1
:
p
:=
new
(
capsV1
)
p
.
hdr
.
version
=
capVers
p
.
hdr
.
pid
=
int32
(
pid
)
c
=
p
case
linuxCapVer2
,
linuxCapVer3
:
p
:=
new
(
capsV3
)
p
.
hdr
.
version
=
capVers
p
.
hdr
.
pid
=
int32
(
pid
)
c
=
p
default
:
err
=
errUnknownVers
return
}
return
}
type
capsV1
struct
{
hdr
capHeader
data
capData
}
func
(
c
*
capsV1
)
Get
(
which
CapType
,
what
Cap
)
bool
{
if
what
>
32
{
return
false
}
switch
which
{
case
EFFECTIVE
:
return
(
1
<<
uint
(
what
))
&
c
.
data
.
effective
!=
0
case
PERMITTED
:
return
(
1
<<
uint
(
what
))
&
c
.
data
.
permitted
!=
0
case
INHERITABLE
:
return
(
1
<<
uint
(
what
))
&
c
.
data
.
inheritable
!=
0
}
return
false
}
func
(
c
*
capsV1
)
getData
(
which
CapType
)
(
ret
uint32
)
{
switch
which
{
case
EFFECTIVE
:
ret
=
c
.
data
.
effective
case
PERMITTED
:
ret
=
c
.
data
.
permitted
case
INHERITABLE
:
ret
=
c
.
data
.
inheritable
}
return
}
func
(
c
*
capsV1
)
Empty
(
which
CapType
)
bool
{
return
c
.
getData
(
which
)
==
0
}
func
(
c
*
capsV1
)
Full
(
which
CapType
)
bool
{
return
(
c
.
getData
(
which
)
&
0x7fffffff
)
==
0x7fffffff
}
func
(
c
*
capsV1
)
Set
(
which
CapType
,
caps
...
Cap
)
{
for
_
,
what
:=
range
caps
{
if
what
>
32
{
continue
}
if
which
&
EFFECTIVE
!=
0
{
c
.
data
.
effective
|=
1
<<
uint
(
what
)
}
if
which
&
PERMITTED
!=
0
{
c
.
data
.
permitted
|=
1
<<
uint
(
what
)
}
if
which
&
INHERITABLE
!=
0
{
c
.
data
.
inheritable
|=
1
<<
uint
(
what
)
}
}
}
func
(
c
*
capsV1
)
Unset
(
which
CapType
,
caps
...
Cap
)
{
for
_
,
what
:=
range
caps
{
if
what
>
32
{
continue
}
if
which
&
EFFECTIVE
!=
0
{
c
.
data
.
effective
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
PERMITTED
!=
0
{
c
.
data
.
permitted
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
INHERITABLE
!=
0
{
c
.
data
.
inheritable
&=
^
(
1
<<
uint
(
what
))
}
}
}
func
(
c
*
capsV1
)
Fill
(
kind
CapType
)
{
if
kind
&
CAPS
==
CAPS
{
c
.
data
.
effective
=
0x7fffffff
c
.
data
.
permitted
=
0x7fffffff
c
.
data
.
inheritable
=
0
}
}
func
(
c
*
capsV1
)
Clear
(
kind
CapType
)
{
if
kind
&
CAPS
==
CAPS
{
c
.
data
.
effective
=
0
c
.
data
.
permitted
=
0
c
.
data
.
inheritable
=
0
}
}
func
(
c
*
capsV1
)
StringCap
(
which
CapType
)
(
ret
string
)
{
return
mkStringCap
(
c
,
which
)
}
func
(
c
*
capsV1
)
String
()
(
ret
string
)
{
return
mkString
(
c
,
BOUNDING
)
}
func
(
c
*
capsV1
)
Load
()
(
err
error
)
{
return
capget
(
&
c
.
hdr
,
&
c
.
data
)
}
func
(
c
*
capsV1
)
Apply
(
kind
CapType
)
error
{
if
kind
&
CAPS
==
CAPS
{
return
capset
(
&
c
.
hdr
,
&
c
.
data
)
}
return
nil
}
type
capsV3
struct
{
hdr
capHeader
data
[
2
]
capData
bounds
[
2
]
uint32
ambient
[
2
]
uint32
}
func
(
c
*
capsV3
)
Get
(
which
CapType
,
what
Cap
)
bool
{
var
i
uint
if
what
>
31
{
i
=
uint
(
what
)
>>
5
what
%=
32
}
switch
which
{
case
EFFECTIVE
:
return
(
1
<<
uint
(
what
))
&
c
.
data
[
i
]
.
effective
!=
0
case
PERMITTED
:
return
(
1
<<
uint
(
what
))
&
c
.
data
[
i
]
.
permitted
!=
0
case
INHERITABLE
:
return
(
1
<<
uint
(
what
))
&
c
.
data
[
i
]
.
inheritable
!=
0
case
BOUNDING
:
return
(
1
<<
uint
(
what
))
&
c
.
bounds
[
i
]
!=
0
case
AMBIENT
:
return
(
1
<<
uint
(
what
))
&
c
.
ambient
[
i
]
!=
0
}
return
false
}
func
(
c
*
capsV3
)
getData
(
which
CapType
,
dest
[]
uint32
)
{
switch
which
{
case
EFFECTIVE
:
dest
[
0
]
=
c
.
data
[
0
]
.
effective
dest
[
1
]
=
c
.
data
[
1
]
.
effective
case
PERMITTED
:
dest
[
0
]
=
c
.
data
[
0
]
.
permitted
dest
[
1
]
=
c
.
data
[
1
]
.
permitted
case
INHERITABLE
:
dest
[
0
]
=
c
.
data
[
0
]
.
inheritable
dest
[
1
]
=
c
.
data
[
1
]
.
inheritable
case
BOUNDING
:
dest
[
0
]
=
c
.
bounds
[
0
]
dest
[
1
]
=
c
.
bounds
[
1
]
case
AMBIENT
:
dest
[
0
]
=
c
.
ambient
[
0
]
dest
[
1
]
=
c
.
ambient
[
1
]
}
}
func
(
c
*
capsV3
)
Empty
(
which
CapType
)
bool
{
var
data
[
2
]
uint32
c
.
getData
(
which
,
data
[
:
])
return
data
[
0
]
==
0
&&
data
[
1
]
==
0
}
func
(
c
*
capsV3
)
Full
(
which
CapType
)
bool
{
var
data
[
2
]
uint32
c
.
getData
(
which
,
data
[
:
])
if
(
data
[
0
]
&
0xffffffff
)
!=
0xffffffff
{
return
false
}
return
(
data
[
1
]
&
capUpperMask
)
==
capUpperMask
}
func
(
c
*
capsV3
)
Set
(
which
CapType
,
caps
...
Cap
)
{
for
_
,
what
:=
range
caps
{
var
i
uint
if
what
>
31
{
i
=
uint
(
what
)
>>
5
what
%=
32
}
if
which
&
EFFECTIVE
!=
0
{
c
.
data
[
i
]
.
effective
|=
1
<<
uint
(
what
)
}
if
which
&
PERMITTED
!=
0
{
c
.
data
[
i
]
.
permitted
|=
1
<<
uint
(
what
)
}
if
which
&
INHERITABLE
!=
0
{
c
.
data
[
i
]
.
inheritable
|=
1
<<
uint
(
what
)
}
if
which
&
BOUNDING
!=
0
{
c
.
bounds
[
i
]
|=
1
<<
uint
(
what
)
}
if
which
&
AMBIENT
!=
0
{
c
.
ambient
[
i
]
|=
1
<<
uint
(
what
)
}
}
}
func
(
c
*
capsV3
)
Unset
(
which
CapType
,
caps
...
Cap
)
{
for
_
,
what
:=
range
caps
{
var
i
uint
if
what
>
31
{
i
=
uint
(
what
)
>>
5
what
%=
32
}
if
which
&
EFFECTIVE
!=
0
{
c
.
data
[
i
]
.
effective
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
PERMITTED
!=
0
{
c
.
data
[
i
]
.
permitted
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
INHERITABLE
!=
0
{
c
.
data
[
i
]
.
inheritable
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
BOUNDING
!=
0
{
c
.
bounds
[
i
]
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
AMBIENT
!=
0
{
c
.
ambient
[
i
]
&=
^
(
1
<<
uint
(
what
))
}
}
}
func
(
c
*
capsV3
)
Fill
(
kind
CapType
)
{
if
kind
&
CAPS
==
CAPS
{
c
.
data
[
0
]
.
effective
=
0xffffffff
c
.
data
[
0
]
.
permitted
=
0xffffffff
c
.
data
[
0
]
.
inheritable
=
0
c
.
data
[
1
]
.
effective
=
0xffffffff
c
.
data
[
1
]
.
permitted
=
0xffffffff
c
.
data
[
1
]
.
inheritable
=
0
}
if
kind
&
BOUNDS
==
BOUNDS
{
c
.
bounds
[
0
]
=
0xffffffff
c
.
bounds
[
1
]
=
0xffffffff
}
if
kind
&
AMBS
==
AMBS
{
c
.
ambient
[
0
]
=
0xffffffff
c
.
ambient
[
1
]
=
0xffffffff
}
}
func
(
c
*
capsV3
)
Clear
(
kind
CapType
)
{
if
kind
&
CAPS
==
CAPS
{
c
.
data
[
0
]
.
effective
=
0
c
.
data
[
0
]
.
permitted
=
0
c
.
data
[
0
]
.
inheritable
=
0
c
.
data
[
1
]
.
effective
=
0
c
.
data
[
1
]
.
permitted
=
0
c
.
data
[
1
]
.
inheritable
=
0
}
if
kind
&
BOUNDS
==
BOUNDS
{
c
.
bounds
[
0
]
=
0
c
.
bounds
[
1
]
=
0
}
if
kind
&
AMBS
==
AMBS
{
c
.
ambient
[
0
]
=
0
c
.
ambient
[
1
]
=
0
}
}
func
(
c
*
capsV3
)
StringCap
(
which
CapType
)
(
ret
string
)
{
return
mkStringCap
(
c
,
which
)
}
func
(
c
*
capsV3
)
String
()
(
ret
string
)
{
return
mkString
(
c
,
BOUNDING
)
}
func
(
c
*
capsV3
)
Load
()
(
err
error
)
{
err
=
capget
(
&
c
.
hdr
,
&
c
.
data
[
0
])
if
err
!=
nil
{
return
}
var
status_path
string
if
c
.
hdr
.
pid
==
0
{
status_path
=
fmt
.
Sprintf
(
"/proc/self/status"
)
}
else
{
status_path
=
fmt
.
Sprintf
(
"/proc/%d/status"
,
c
.
hdr
.
pid
)
}
f
,
err
:=
os
.
Open
(
status_path
)
if
err
!=
nil
{
return
}
b
:=
bufio
.
NewReader
(
f
)
for
{
line
,
e
:=
b
.
ReadString
(
'\n'
)
if
e
!=
nil
{
if
e
!=
io
.
EOF
{
err
=
e
}
break
}
if
strings
.
HasPrefix
(
line
,
"CapB"
)
{
fmt
.
Sscanf
(
line
[
4
:
],
"nd: %08x%08x"
,
&
c
.
bounds
[
1
],
&
c
.
bounds
[
0
])
continue
}
if
strings
.
HasPrefix
(
line
,
"CapA"
)
{
fmt
.
Sscanf
(
line
[
4
:
],
"mb: %08x%08x"
,
&
c
.
ambient
[
1
],
&
c
.
ambient
[
0
])
continue
}
}
f
.
Close
()
return
}
func
(
c
*
capsV3
)
Apply
(
kind
CapType
)
(
err
error
)
{
if
kind
&
BOUNDS
==
BOUNDS
{
var
data
[
2
]
capData
err
=
capget
(
&
c
.
hdr
,
&
data
[
0
])
if
err
!=
nil
{
return
}
if
(
1
<<
uint
(
CAP_SETPCAP
))
&
data
[
0
]
.
effective
!=
0
{
for
i
:=
Cap
(
0
);
i
<=
CAP_LAST_CAP
;
i
++
{
if
c
.
Get
(
BOUNDING
,
i
)
{
continue
}
err
=
prctl
(
syscall
.
PR_CAPBSET_DROP
,
uintptr
(
i
),
0
,
0
,
0
)
if
err
!=
nil
{
// Ignore EINVAL since the capability may not be supported in this system.
if
errno
,
ok
:=
err
.
(
syscall
.
Errno
);
ok
&&
errno
==
syscall
.
EINVAL
{
err
=
nil
continue
}
return
}
}
}
}
if
kind
&
CAPS
==
CAPS
{
err
=
capset
(
&
c
.
hdr
,
&
c
.
data
[
0
])
if
err
!=
nil
{
return
}
}
if
kind
&
AMBS
==
AMBS
{
for
i
:=
Cap
(
0
);
i
<=
CAP_LAST_CAP
;
i
++
{
action
:=
pr_CAP_AMBIENT_LOWER
if
c
.
Get
(
AMBIENT
,
i
)
{
action
=
pr_CAP_AMBIENT_RAISE
}
err
:=
prctl
(
pr_CAP_AMBIENT
,
action
,
uintptr
(
i
),
0
,
0
)
// Ignore EINVAL as not supported on kernels before 4.3
if
errno
,
ok
:=
err
.
(
syscall
.
Errno
);
ok
&&
errno
==
syscall
.
EINVAL
{
err
=
nil
continue
}
}
}
return
}
func
newFile
(
path
string
)
(
c
Capabilities
,
err
error
)
{
c
=
&
capsFile
{
path
:
path
}
return
}
type
capsFile
struct
{
path
string
data
vfscapData
}
func
(
c
*
capsFile
)
Get
(
which
CapType
,
what
Cap
)
bool
{
var
i
uint
if
what
>
31
{
if
c
.
data
.
version
==
1
{
return
false
}
i
=
uint
(
what
)
>>
5
what
%=
32
}
switch
which
{
case
EFFECTIVE
:
return
(
1
<<
uint
(
what
))
&
c
.
data
.
effective
[
i
]
!=
0
case
PERMITTED
:
return
(
1
<<
uint
(
what
))
&
c
.
data
.
data
[
i
]
.
permitted
!=
0
case
INHERITABLE
:
return
(
1
<<
uint
(
what
))
&
c
.
data
.
data
[
i
]
.
inheritable
!=
0
}
return
false
}
func
(
c
*
capsFile
)
getData
(
which
CapType
,
dest
[]
uint32
)
{
switch
which
{
case
EFFECTIVE
:
dest
[
0
]
=
c
.
data
.
effective
[
0
]
dest
[
1
]
=
c
.
data
.
effective
[
1
]
case
PERMITTED
:
dest
[
0
]
=
c
.
data
.
data
[
0
]
.
permitted
dest
[
1
]
=
c
.
data
.
data
[
1
]
.
permitted
case
INHERITABLE
:
dest
[
0
]
=
c
.
data
.
data
[
0
]
.
inheritable
dest
[
1
]
=
c
.
data
.
data
[
1
]
.
inheritable
}
}
func
(
c
*
capsFile
)
Empty
(
which
CapType
)
bool
{
var
data
[
2
]
uint32
c
.
getData
(
which
,
data
[
:
])
return
data
[
0
]
==
0
&&
data
[
1
]
==
0
}
func
(
c
*
capsFile
)
Full
(
which
CapType
)
bool
{
var
data
[
2
]
uint32
c
.
getData
(
which
,
data
[
:
])
if
c
.
data
.
version
==
0
{
return
(
data
[
0
]
&
0x7fffffff
)
==
0x7fffffff
}
if
(
data
[
0
]
&
0xffffffff
)
!=
0xffffffff
{
return
false
}
return
(
data
[
1
]
&
capUpperMask
)
==
capUpperMask
}
func
(
c
*
capsFile
)
Set
(
which
CapType
,
caps
...
Cap
)
{
for
_
,
what
:=
range
caps
{
var
i
uint
if
what
>
31
{
if
c
.
data
.
version
==
1
{
continue
}
i
=
uint
(
what
)
>>
5
what
%=
32
}
if
which
&
EFFECTIVE
!=
0
{
c
.
data
.
effective
[
i
]
|=
1
<<
uint
(
what
)
}
if
which
&
PERMITTED
!=
0
{
c
.
data
.
data
[
i
]
.
permitted
|=
1
<<
uint
(
what
)
}
if
which
&
INHERITABLE
!=
0
{
c
.
data
.
data
[
i
]
.
inheritable
|=
1
<<
uint
(
what
)
}
}
}
func
(
c
*
capsFile
)
Unset
(
which
CapType
,
caps
...
Cap
)
{
for
_
,
what
:=
range
caps
{
var
i
uint
if
what
>
31
{
if
c
.
data
.
version
==
1
{
continue
}
i
=
uint
(
what
)
>>
5
what
%=
32
}
if
which
&
EFFECTIVE
!=
0
{
c
.
data
.
effective
[
i
]
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
PERMITTED
!=
0
{
c
.
data
.
data
[
i
]
.
permitted
&=
^
(
1
<<
uint
(
what
))
}
if
which
&
INHERITABLE
!=
0
{
c
.
data
.
data
[
i
]
.
inheritable
&=
^
(
1
<<
uint
(
what
))
}
}
}
func
(
c
*
capsFile
)
Fill
(
kind
CapType
)
{
if
kind
&
CAPS
==
CAPS
{
c
.
data
.
effective
[
0
]
=
0xffffffff
c
.
data
.
data
[
0
]
.
permitted
=
0xffffffff
c
.
data
.
data
[
0
]
.
inheritable
=
0
if
c
.
data
.
version
==
2
{
c
.
data
.
effective
[
1
]
=
0xffffffff
c
.
data
.
data
[
1
]
.
permitted
=
0xffffffff
c
.
data
.
data
[
1
]
.
inheritable
=
0
}
}
}
func
(
c
*
capsFile
)
Clear
(
kind
CapType
)
{
if
kind
&
CAPS
==
CAPS
{
c
.
data
.
effective
[
0
]
=
0
c
.
data
.
data
[
0
]
.
permitted
=
0
c
.
data
.
data
[
0
]
.
inheritable
=
0
if
c
.
data
.
version
==
2
{
c
.
data
.
effective
[
1
]
=
0
c
.
data
.
data
[
1
]
.
permitted
=
0
c
.
data
.
data
[
1
]
.
inheritable
=
0
}
}
}
func
(
c
*
capsFile
)
StringCap
(
which
CapType
)
(
ret
string
)
{
return
mkStringCap
(
c
,
which
)
}
func
(
c
*
capsFile
)
String
()
(
ret
string
)
{
return
mkString
(
c
,
INHERITABLE
)
}
func
(
c
*
capsFile
)
Load
()
(
err
error
)
{
return
getVfsCap
(
c
.
path
,
&
c
.
data
)
}
func
(
c
*
capsFile
)
Apply
(
kind
CapType
)
(
err
error
)
{
if
kind
&
CAPS
==
CAPS
{
return
setVfsCap
(
c
.
path
,
&
c
.
data
)
}
return
}
vendor/github.com/syndtr/gocapability/capability/capability_noop.go
0 → 100644
View file @
d7e13eb9
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// +build !linux
package
capability
import
"errors"
func
newPid
(
pid
int
)
(
Capabilities
,
error
)
{
return
nil
,
errors
.
New
(
"not supported"
)
}
func
newFile
(
path
string
)
(
Capabilities
,
error
)
{
return
nil
,
errors
.
New
(
"not supported"
)
}
vendor/github.com/syndtr/gocapability/capability/enum.go
0 → 100644
View file @
d7e13eb9
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package
capability
type
CapType
uint
func
(
c
CapType
)
String
()
string
{
switch
c
{
case
EFFECTIVE
:
return
"effective"
case
PERMITTED
:
return
"permitted"
case
INHERITABLE
:
return
"inheritable"
case
BOUNDING
:
return
"bounding"
case
CAPS
:
return
"caps"
case
AMBIENT
:
return
"ambient"
}
return
"unknown"
}
const
(
EFFECTIVE
CapType
=
1
<<
iota
PERMITTED
INHERITABLE
BOUNDING
AMBIENT
CAPS
=
EFFECTIVE
|
PERMITTED
|
INHERITABLE
BOUNDS
=
BOUNDING
AMBS
=
AMBIENT
)
//go:generate go run enumgen/gen.go
type
Cap
int
// POSIX-draft defined capabilities and Linux extensions.
//
// Defined in https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h
const
(
// In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this
// overrides the restriction of changing file ownership and group
// ownership.
CAP_CHOWN
=
Cap
(
0
)
// Override all DAC access, including ACL execute access if
// [_POSIX_ACL] is defined. Excluding DAC access covered by
// CAP_LINUX_IMMUTABLE.
CAP_DAC_OVERRIDE
=
Cap
(
1
)
// Overrides all DAC restrictions regarding read and search on files
// and directories, including ACL restrictions if [_POSIX_ACL] is
// defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE.
CAP_DAC_READ_SEARCH
=
Cap
(
2
)
// Overrides all restrictions about allowed operations on files, where
// file owner ID must be equal to the user ID, except where CAP_FSETID
// is applicable. It doesn't override MAC and DAC restrictions.
CAP_FOWNER
=
Cap
(
3
)
// Overrides the following restrictions that the effective user ID
// shall match the file owner ID when setting the S_ISUID and S_ISGID
// bits on that file; that the effective group ID (or one of the
// supplementary group IDs) shall match the file owner ID when setting
// the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are
// cleared on successful return from chown(2) (not implemented).
CAP_FSETID
=
Cap
(
4
)
// Overrides the restriction that the real or effective user ID of a
// process sending a signal must match the real or effective user ID
// of the process receiving the signal.
CAP_KILL
=
Cap
(
5
)
// Allows setgid(2) manipulation
// Allows setgroups(2)
// Allows forged gids on socket credentials passing.
CAP_SETGID
=
Cap
(
6
)
// Allows set*uid(2) manipulation (including fsuid).
// Allows forged pids on socket credentials passing.
CAP_SETUID
=
Cap
(
7
)
// Linux-specific capabilities
// Without VFS support for capabilities:
// Transfer any capability in your permitted set to any pid,
// remove any capability in your permitted set from any pid
// With VFS support for capabilities (neither of above, but)
// Add any capability from current's capability bounding set
// to the current process' inheritable set
// Allow taking bits out of capability bounding set
// Allow modification of the securebits for a process
CAP_SETPCAP
=
Cap
(
8
)
// Allow modification of S_IMMUTABLE and S_APPEND file attributes
CAP_LINUX_IMMUTABLE
=
Cap
(
9
)
// Allows binding to TCP/UDP sockets below 1024
// Allows binding to ATM VCIs below 32
CAP_NET_BIND_SERVICE
=
Cap
(
10
)
// Allow broadcasting, listen to multicast
CAP_NET_BROADCAST
=
Cap
(
11
)
// Allow interface configuration
// Allow administration of IP firewall, masquerading and accounting
// Allow setting debug option on sockets
// Allow modification of routing tables
// Allow setting arbitrary process / process group ownership on
// sockets
// Allow binding to any address for transparent proxying (also via NET_RAW)
// Allow setting TOS (type of service)
// Allow setting promiscuous mode
// Allow clearing driver statistics
// Allow multicasting
// Allow read/write of device-specific registers
// Allow activation of ATM control sockets
CAP_NET_ADMIN
=
Cap
(
12
)
// Allow use of RAW sockets
// Allow use of PACKET sockets
// Allow binding to any address for transparent proxying (also via NET_ADMIN)
CAP_NET_RAW
=
Cap
(
13
)
// Allow locking of shared memory segments
// Allow mlock and mlockall (which doesn't really have anything to do
// with IPC)
CAP_IPC_LOCK
=
Cap
(
14
)
// Override IPC ownership checks
CAP_IPC_OWNER
=
Cap
(
15
)
// Insert and remove kernel modules - modify kernel without limit
CAP_SYS_MODULE
=
Cap
(
16
)
// Allow ioperm/iopl access
// Allow sending USB messages to any device via /proc/bus/usb
CAP_SYS_RAWIO
=
Cap
(
17
)
// Allow use of chroot()
CAP_SYS_CHROOT
=
Cap
(
18
)
// Allow ptrace() of any process
CAP_SYS_PTRACE
=
Cap
(
19
)
// Allow configuration of process accounting
CAP_SYS_PACCT
=
Cap
(
20
)
// Allow configuration of the secure attention key
// Allow administration of the random device
// Allow examination and configuration of disk quotas
// Allow setting the domainname
// Allow setting the hostname
// Allow calling bdflush()
// Allow mount() and umount(), setting up new smb connection
// Allow some autofs root ioctls
// Allow nfsservctl
// Allow VM86_REQUEST_IRQ
// Allow to read/write pci config on alpha
// Allow irix_prctl on mips (setstacksize)
// Allow flushing all cache on m68k (sys_cacheflush)
// Allow removing semaphores
// Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores
// and shared memory
// Allow locking/unlocking of shared memory segment
// Allow turning swap on/off
// Allow forged pids on socket credentials passing
// Allow setting readahead and flushing buffers on block devices
// Allow setting geometry in floppy driver
// Allow turning DMA on/off in xd driver
// Allow administration of md devices (mostly the above, but some
// extra ioctls)
// Allow tuning the ide driver
// Allow access to the nvram device
// Allow administration of apm_bios, serial and bttv (TV) device
// Allow manufacturer commands in isdn CAPI support driver
// Allow reading non-standardized portions of pci configuration space
// Allow DDI debug ioctl on sbpcd driver
// Allow setting up serial ports
// Allow sending raw qic-117 commands
// Allow enabling/disabling tagged queuing on SCSI controllers and sending
// arbitrary SCSI commands
// Allow setting encryption key on loopback filesystem
// Allow setting zone reclaim policy
// Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility
CAP_SYS_ADMIN
=
Cap
(
21
)
// Allow use of reboot()
CAP_SYS_BOOT
=
Cap
(
22
)
// Allow raising priority and setting priority on other (different
// UID) processes
// Allow use of FIFO and round-robin (realtime) scheduling on own
// processes and setting the scheduling algorithm used by another
// process.
// Allow setting cpu affinity on other processes
CAP_SYS_NICE
=
Cap
(
23
)
// Override resource limits. Set resource limits.
// Override quota limits.
// Override reserved space on ext2 filesystem
// Modify data journaling mode on ext3 filesystem (uses journaling
// resources)
// NOTE: ext2 honors fsuid when checking for resource overrides, so
// you can override using fsuid too
// Override size restrictions on IPC message queues
// Allow more than 64hz interrupts from the real-time clock
// Override max number of consoles on console allocation
// Override max number of keymaps
// Control memory reclaim behavior
CAP_SYS_RESOURCE
=
Cap
(
24
)
// Allow manipulation of system clock
// Allow irix_stime on mips
// Allow setting the real-time clock
CAP_SYS_TIME
=
Cap
(
25
)
// Allow configuration of tty devices
// Allow vhangup() of tty
CAP_SYS_TTY_CONFIG
=
Cap
(
26
)
// Allow the privileged aspects of mknod()
CAP_MKNOD
=
Cap
(
27
)
// Allow taking of leases on files
CAP_LEASE
=
Cap
(
28
)
CAP_AUDIT_WRITE
=
Cap
(
29
)
CAP_AUDIT_CONTROL
=
Cap
(
30
)
CAP_SETFCAP
=
Cap
(
31
)
// Override MAC access.
// The base kernel enforces no MAC policy.
// An LSM may enforce a MAC policy, and if it does and it chooses
// to implement capability based overrides of that policy, this is
// the capability it should use to do so.
CAP_MAC_OVERRIDE
=
Cap
(
32
)
// Allow MAC configuration or state changes.
// The base kernel requires no MAC configuration.
// An LSM may enforce a MAC policy, and if it does and it chooses
// to implement capability based checks on modifications to that
// policy or the data required to maintain it, this is the
// capability it should use to do so.
CAP_MAC_ADMIN
=
Cap
(
33
)
// Allow configuring the kernel's syslog (printk behaviour)
CAP_SYSLOG
=
Cap
(
34
)
// Allow triggering something that will wake the system
CAP_WAKE_ALARM
=
Cap
(
35
)
// Allow preventing system suspends
CAP_BLOCK_SUSPEND
=
Cap
(
36
)
// Allow reading the audit log via multicast netlink socket
CAP_AUDIT_READ
=
Cap
(
37
)
// Allow system performance and observability privileged operations
// using perf_events, i915_perf and other kernel subsystems
CAP_PERFMON
=
Cap
(
38
)
// CAP_BPF allows the following BPF operations:
// - Creating all types of BPF maps
// - Advanced verifier features
// - Indirect variable access
// - Bounded loops
// - BPF to BPF function calls
// - Scalar precision tracking
// - Larger complexity limits
// - Dead code elimination
// - And potentially other features
// - Loading BPF Type Format (BTF) data
// - Retrieve xlated and JITed code of BPF programs
// - Use bpf_spin_lock() helper
//
// CAP_PERFMON relaxes the verifier checks further:
// - BPF progs can use of pointer-to-integer conversions
// - speculation attack hardening measures are bypassed
// - bpf_probe_read to read arbitrary kernel memory is allowed
// - bpf_trace_printk to print kernel memory is allowed
//
// CAP_SYS_ADMIN is required to use bpf_probe_write_user.
//
// CAP_SYS_ADMIN is required to iterate system wide loaded
// programs, maps, links, BTFs and convert their IDs to file descriptors.
//
// CAP_PERFMON and CAP_BPF are required to load tracing programs.
// CAP_NET_ADMIN and CAP_BPF are required to load networking programs.
CAP_BPF
=
Cap
(
39
)
// Allow checkpoint/restore related operations.
// Introduced in kernel 5.9
CAP_CHECKPOINT_RESTORE
=
Cap
(
40
)
)
var
(
// Highest valid capability of the running kernel.
CAP_LAST_CAP
=
Cap
(
63
)
capUpperMask
=
^
uint32
(
0
)
)
vendor/github.com/syndtr/gocapability/capability/enum_gen.go
0 → 100644
View file @
d7e13eb9
// generated file; DO NOT EDIT - use go generate in directory with source
package
capability
func
(
c
Cap
)
String
()
string
{
switch
c
{
case
CAP_CHOWN
:
return
"chown"
case
CAP_DAC_OVERRIDE
:
return
"dac_override"
case
CAP_DAC_READ_SEARCH
:
return
"dac_read_search"
case
CAP_FOWNER
:
return
"fowner"
case
CAP_FSETID
:
return
"fsetid"
case
CAP_KILL
:
return
"kill"
case
CAP_SETGID
:
return
"setgid"
case
CAP_SETUID
:
return
"setuid"
case
CAP_SETPCAP
:
return
"setpcap"
case
CAP_LINUX_IMMUTABLE
:
return
"linux_immutable"
case
CAP_NET_BIND_SERVICE
:
return
"net_bind_service"
case
CAP_NET_BROADCAST
:
return
"net_broadcast"
case
CAP_NET_ADMIN
:
return
"net_admin"
case
CAP_NET_RAW
:
return
"net_raw"
case
CAP_IPC_LOCK
:
return
"ipc_lock"
case
CAP_IPC_OWNER
:
return
"ipc_owner"
case
CAP_SYS_MODULE
:
return
"sys_module"
case
CAP_SYS_RAWIO
:
return
"sys_rawio"
case
CAP_SYS_CHROOT
:
return
"sys_chroot"
case
CAP_SYS_PTRACE
:
return
"sys_ptrace"
case
CAP_SYS_PACCT
:
return
"sys_pacct"
case
CAP_SYS_ADMIN
:
return
"sys_admin"
case
CAP_SYS_BOOT
:
return
"sys_boot"
case
CAP_SYS_NICE
:
return
"sys_nice"
case
CAP_SYS_RESOURCE
:
return
"sys_resource"
case
CAP_SYS_TIME
:
return
"sys_time"
case
CAP_SYS_TTY_CONFIG
:
return
"sys_tty_config"
case
CAP_MKNOD
:
return
"mknod"
case
CAP_LEASE
:
return
"lease"
case
CAP_AUDIT_WRITE
:
return
"audit_write"
case
CAP_AUDIT_CONTROL
:
return
"audit_control"
case
CAP_SETFCAP
:
return
"setfcap"
case
CAP_MAC_OVERRIDE
:
return
"mac_override"
case
CAP_MAC_ADMIN
:
return
"mac_admin"
case
CAP_SYSLOG
:
return
"syslog"
case
CAP_WAKE_ALARM
:
return
"wake_alarm"
case
CAP_BLOCK_SUSPEND
:
return
"block_suspend"
case
CAP_AUDIT_READ
:
return
"audit_read"
case
CAP_PERFMON
:
return
"perfmon"
case
CAP_BPF
:
return
"bpf"
case
CAP_CHECKPOINT_RESTORE
:
return
"checkpoint_restore"
}
return
"unknown"
}
// List returns list of all supported capabilities
func
List
()
[]
Cap
{
return
[]
Cap
{
CAP_CHOWN
,
CAP_DAC_OVERRIDE
,
CAP_DAC_READ_SEARCH
,
CAP_FOWNER
,
CAP_FSETID
,
CAP_KILL
,
CAP_SETGID
,
CAP_SETUID
,
CAP_SETPCAP
,
CAP_LINUX_IMMUTABLE
,
CAP_NET_BIND_SERVICE
,
CAP_NET_BROADCAST
,
CAP_NET_ADMIN
,
CAP_NET_RAW
,
CAP_IPC_LOCK
,
CAP_IPC_OWNER
,
CAP_SYS_MODULE
,
CAP_SYS_RAWIO
,
CAP_SYS_CHROOT
,
CAP_SYS_PTRACE
,
CAP_SYS_PACCT
,
CAP_SYS_ADMIN
,
CAP_SYS_BOOT
,
CAP_SYS_NICE
,
CAP_SYS_RESOURCE
,
CAP_SYS_TIME
,
CAP_SYS_TTY_CONFIG
,
CAP_MKNOD
,
CAP_LEASE
,
CAP_AUDIT_WRITE
,
CAP_AUDIT_CONTROL
,
CAP_SETFCAP
,
CAP_MAC_OVERRIDE
,
CAP_MAC_ADMIN
,
CAP_SYSLOG
,
CAP_WAKE_ALARM
,
CAP_BLOCK_SUSPEND
,
CAP_AUDIT_READ
,
CAP_PERFMON
,
CAP_BPF
,
CAP_CHECKPOINT_RESTORE
,
}
}
vendor/github.com/syndtr/gocapability/capability/syscall_linux.go
0 → 100644
View file @
d7e13eb9
// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package
capability
import
(
"syscall"
"unsafe"
)
type
capHeader
struct
{
version
uint32
pid
int32
}
type
capData
struct
{
effective
uint32
permitted
uint32
inheritable
uint32
}
func
capget
(
hdr
*
capHeader
,
data
*
capData
)
(
err
error
)
{
_
,
_
,
e1
:=
syscall
.
Syscall
(
syscall
.
SYS_CAPGET
,
uintptr
(
unsafe
.
Pointer
(
hdr
)),
uintptr
(
unsafe
.
Pointer
(
data
)),
0
)
if
e1
!=
0
{
err
=
e1
}
return
}
func
capset
(
hdr
*
capHeader
,
data
*
capData
)
(
err
error
)
{
_
,
_
,
e1
:=
syscall
.
Syscall
(
syscall
.
SYS_CAPSET
,
uintptr
(
unsafe
.
Pointer
(
hdr
)),
uintptr
(
unsafe
.
Pointer
(
data
)),
0
)
if
e1
!=
0
{
err
=
e1
}
return
}
// not yet in syscall
const
(
pr_CAP_AMBIENT
=
47
pr_CAP_AMBIENT_IS_SET
=
uintptr
(
1
)
pr_CAP_AMBIENT_RAISE
=
uintptr
(
2
)
pr_CAP_AMBIENT_LOWER
=
uintptr
(
3
)
pr_CAP_AMBIENT_CLEAR_ALL
=
uintptr
(
4
)
)
func
prctl
(
option
int
,
arg2
,
arg3
,
arg4
,
arg5
uintptr
)
(
err
error
)
{
_
,
_
,
e1
:=
syscall
.
Syscall6
(
syscall
.
SYS_PRCTL
,
uintptr
(
option
),
arg2
,
arg3
,
arg4
,
arg5
,
0
)
if
e1
!=
0
{
err
=
e1
}
return
}
const
(
vfsXattrName
=
"security.capability"
vfsCapVerMask
=
0xff000000
vfsCapVer1
=
0x01000000
vfsCapVer2
=
0x02000000
vfsCapFlagMask
=
^
vfsCapVerMask
vfsCapFlageffective
=
0x000001
vfscapDataSizeV1
=
4
*
(
1
+
2
*
1
)
vfscapDataSizeV2
=
4
*
(
1
+
2
*
2
)
)
type
vfscapData
struct
{
magic
uint32
data
[
2
]
struct
{
permitted
uint32
inheritable
uint32
}
effective
[
2
]
uint32
version
int8
}
var
(
_vfsXattrName
*
byte
)
func
init
()
{
_vfsXattrName
,
_
=
syscall
.
BytePtrFromString
(
vfsXattrName
)
}
func
getVfsCap
(
path
string
,
dest
*
vfscapData
)
(
err
error
)
{
var
_p0
*
byte
_p0
,
err
=
syscall
.
BytePtrFromString
(
path
)
if
err
!=
nil
{
return
}
r0
,
_
,
e1
:=
syscall
.
Syscall6
(
syscall
.
SYS_GETXATTR
,
uintptr
(
unsafe
.
Pointer
(
_p0
)),
uintptr
(
unsafe
.
Pointer
(
_vfsXattrName
)),
uintptr
(
unsafe
.
Pointer
(
dest
)),
vfscapDataSizeV2
,
0
,
0
)
if
e1
!=
0
{
if
e1
==
syscall
.
ENODATA
{
dest
.
version
=
2
return
}
err
=
e1
}
switch
dest
.
magic
&
vfsCapVerMask
{
case
vfsCapVer1
:
dest
.
version
=
1
if
r0
!=
vfscapDataSizeV1
{
return
syscall
.
EINVAL
}
dest
.
data
[
1
]
.
permitted
=
0
dest
.
data
[
1
]
.
inheritable
=
0
case
vfsCapVer2
:
dest
.
version
=
2
if
r0
!=
vfscapDataSizeV2
{
return
syscall
.
EINVAL
}
default
:
return
syscall
.
EINVAL
}
if
dest
.
magic
&
vfsCapFlageffective
!=
0
{
dest
.
effective
[
0
]
=
dest
.
data
[
0
]
.
permitted
|
dest
.
data
[
0
]
.
inheritable
dest
.
effective
[
1
]
=
dest
.
data
[
1
]
.
permitted
|
dest
.
data
[
1
]
.
inheritable
}
else
{
dest
.
effective
[
0
]
=
0
dest
.
effective
[
1
]
=
0
}
return
}
func
setVfsCap
(
path
string
,
data
*
vfscapData
)
(
err
error
)
{
var
_p0
*
byte
_p0
,
err
=
syscall
.
BytePtrFromString
(
path
)
if
err
!=
nil
{
return
}
var
size
uintptr
if
data
.
version
==
1
{
data
.
magic
=
vfsCapVer1
size
=
vfscapDataSizeV1
}
else
if
data
.
version
==
2
{
data
.
magic
=
vfsCapVer2
if
data
.
effective
[
0
]
!=
0
||
data
.
effective
[
1
]
!=
0
{
data
.
magic
|=
vfsCapFlageffective
}
size
=
vfscapDataSizeV2
}
else
{
return
syscall
.
EINVAL
}
_
,
_
,
e1
:=
syscall
.
Syscall6
(
syscall
.
SYS_SETXATTR
,
uintptr
(
unsafe
.
Pointer
(
_p0
)),
uintptr
(
unsafe
.
Pointer
(
_vfsXattrName
)),
uintptr
(
unsafe
.
Pointer
(
data
)),
size
,
0
,
0
)
if
e1
!=
0
{
err
=
e1
}
return
}
vendor/github.com/urfave/cli/v2/.flake8
0 → 100644
View file @
d7e13eb9
[flake8]
max-line-length = 120
vendor/github.com/urfave/cli/v2/.gitignore
0 → 100644
View file @
d7e13eb9
*.coverprofile
*.exe
*.orig
.*envrc
.envrc
.idea
# goimports is installed here if not available
/.local/
/site/
coverage.txt
internal/*/built-example
vendor
/cmd/urfave-cli-genflags/urfave-cli-genflags
*.exe
vendor/github.com/urfave/cli/v2/.golangci.yaml
0 → 100644
View file @
d7e13eb9
# https://golangci-lint.run/usage/configuration/
linters
:
enable
:
-
misspell
vendor/github.com/urfave/cli/v2/CODE_OF_CONDUCT.md
0 → 100644
View file @
d7e13eb9
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance, race,
religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
*
Using welcoming and inclusive language
*
Being respectful of differing viewpoints and experiences
*
Gracefully accepting constructive criticism
*
Focusing on what is best for the community
*
Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
*
The use of sexualized language or imagery and unwelcome sexual attention or
advances
*
Trolling, insulting/derogatory comments, and personal or political attacks
*
Public or private harassment
*
Publishing others' private information, such as a physical or electronic
address, without explicit permission
*
Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting urfave-governance@googlegroups.com, a members-only group
that is world-postable. All complaints will be reviewed and investigated and
will result in a response that is deemed necessary and appropriate to the
circumstances. The project team is obligated to maintain confidentiality with
regard to the reporter of an incident. Further details of specific enforcement
policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the
[
Contributor Covenant
][
homepage
]
, version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[
homepage
]:
https://www.contributor-covenant.org
vendor/github.com/urfave/cli/v2/LICENSE
0 → 100644
View file @
d7e13eb9
MIT License
Copyright (c) 2022 urfave/cli maintainers
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.
vendor/github.com/urfave/cli/v2/Makefile
0 → 100644
View file @
d7e13eb9
# NOTE: this Makefile is meant to provide a simplified entry point for humans to
# run all of the critical steps to verify one's changes are harmonious in
# nature. Keeping target bodies to one line each and abstaining from make magic
# are very important so that maintainers and contributors can focus their
# attention on files that are primarily Go.
GO_RUN_BUILD
:=
go run internal/build/build.go
.PHONY
:
all
all
:
generate vet test check-binary-size gfmrun yamlfmt v2diff
# NOTE: this is a special catch-all rule to run any of the commands
# defined in internal/build/build.go with optional arguments passed
# via GFLAGS (global flags) and FLAGS (command-specific flags), e.g.:
#
# $ make test GFLAGS='--packages cli'
%
:
$(GO_RUN_BUILD)
$(GFLAGS)
$*
$(FLAGS)
.PHONY
:
docs
docs
:
mkdocs build
.PHONY
:
serve-docs
serve-docs
:
mkdocs serve
vendor/github.com/urfave/cli/v2/README.md
0 → 100644
View file @
d7e13eb9
# cli
[

](https://github.com/urfave/cli/actions/workflows/cli.yml)
[

](https://pkg.go.dev/github.com/urfave/cli/v2)
[

](https://goreportcard.com/report/github.com/urfave/cli/v2)
[

](https://app.codecov.io/gh/urfave/cli/tree/v2-maint)
cli is a simple, fast, and fun package for building command line apps in Go. The
goal is to enable developers to write fast and distributable command line
applications in an expressive way.
## Documentation
More documentation is available in
[
`./docs`
](
./docs
)
or the hosted
documentation site at
<https://cli.urfave.org>
.
## License
See
[
`LICENSE`
](
./LICENSE
)
vendor/github.com/urfave/cli/v2/app.go
0 → 100644
View file @
d7e13eb9
package
cli
import
(
"context"
"flag"
"fmt"
"io"
"os"
"path/filepath"
"sort"
"strings"
"time"
)
const
suggestDidYouMeanTemplate
=
"Did you mean %q?"
var
(
changeLogURL
=
"https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md"
appActionDeprecationURL
=
fmt
.
Sprintf
(
"%s#deprecated-cli-app-action-signature"
,
changeLogURL
)
contactSysadmin
=
"This is an error in the application. Please contact the distributor of this application if this is not you."
errInvalidActionType
=
NewExitError
(
"ERROR invalid Action type. "
+
fmt
.
Sprintf
(
"Must be `func(*Context`)` or `func(*Context) error). %s"
,
contactSysadmin
)
+
fmt
.
Sprintf
(
"See %s"
,
appActionDeprecationURL
),
2
)
ignoreFlagPrefix
=
"test."
// this is to ignore test flags when adding flags from other packages
SuggestFlag
SuggestFlagFunc
=
nil
// initialized in suggestions.go unless built with urfave_cli_no_suggest
SuggestCommand
SuggestCommandFunc
=
nil
// initialized in suggestions.go unless built with urfave_cli_no_suggest
SuggestDidYouMeanTemplate
string
=
suggestDidYouMeanTemplate
)
// App is the main structure of a cli application. It is recommended that
// an app be created with the cli.NewApp() function
type
App
struct
{
// The name of the program. Defaults to path.Base(os.Args[0])
Name
string
// Full name of command for help, defaults to Name
HelpName
string
// Description of the program.
Usage
string
// Text to override the USAGE section of help
UsageText
string
// Whether this command supports arguments
Args
bool
// Description of the program argument format.
ArgsUsage
string
// Version of the program
Version
string
// Description of the program
Description
string
// DefaultCommand is the (optional) name of a command
// to run if no command names are passed as CLI arguments.
DefaultCommand
string
// List of commands to execute
Commands
[]
*
Command
// List of flags to parse
Flags
[]
Flag
// Boolean to enable bash completion commands
EnableBashCompletion
bool
// Boolean to hide built-in help command and help flag
HideHelp
bool
// Boolean to hide built-in help command but keep help flag.
// Ignored if HideHelp is true.
HideHelpCommand
bool
// Boolean to hide built-in version flag and the VERSION section of help
HideVersion
bool
// categories contains the categorized commands and is populated on app startup
categories
CommandCategories
// flagCategories contains the categorized flags and is populated on app startup
flagCategories
FlagCategories
// An action to execute when the shell completion flag is set
BashComplete
BashCompleteFunc
// An action to execute before any subcommands are run, but after the context is ready
// If a non-nil error is returned, no subcommands are run
Before
BeforeFunc
// An action to execute after any subcommands are run, but after the subcommand has finished
// It is run even if Action() panics
After
AfterFunc
// The action to execute when no subcommands are specified
Action
ActionFunc
// Execute this function if the proper command cannot be found
CommandNotFound
CommandNotFoundFunc
// Execute this function if a usage error occurs
OnUsageError
OnUsageErrorFunc
// Execute this function when an invalid flag is accessed from the context
InvalidFlagAccessHandler
InvalidFlagAccessFunc
// Compilation date
Compiled
time
.
Time
// List of all authors who contributed
Authors
[]
*
Author
// Copyright of the binary if any
Copyright
string
// Reader reader to write input to (useful for tests)
Reader
io
.
Reader
// Writer writer to write output to
Writer
io
.
Writer
// ErrWriter writes error output
ErrWriter
io
.
Writer
// ExitErrHandler processes any error encountered while running an App before
// it is returned to the caller. If no function is provided, HandleExitCoder
// is used as the default behavior.
ExitErrHandler
ExitErrHandlerFunc
// Other custom info
Metadata
map
[
string
]
interface
{}
// Carries a function which returns app specific info.
ExtraInfo
func
()
map
[
string
]
string
// CustomAppHelpTemplate the text template for app help topic.
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
CustomAppHelpTemplate
string
// SliceFlagSeparator is used to customize the separator for SliceFlag, the default is ","
SliceFlagSeparator
string
// DisableSliceFlagSeparator is used to disable SliceFlagSeparator, the default is false
DisableSliceFlagSeparator
bool
// Boolean to enable short-option handling so user can combine several
// single-character bool arguments into one
// i.e. foobar -o -v -> foobar -ov
UseShortOptionHandling
bool
// Enable suggestions for commands and flags
Suggest
bool
// Allows global flags set by libraries which use flag.XXXVar(...) directly
// to be parsed through this library
AllowExtFlags
bool
// Treat all flags as normal arguments if true
SkipFlagParsing
bool
didSetup
bool
separator
separatorSpec
rootCommand
*
Command
}
type
SuggestFlagFunc
func
(
flags
[]
Flag
,
provided
string
,
hideHelp
bool
)
string
type
SuggestCommandFunc
func
(
commands
[]
*
Command
,
provided
string
)
string
// Tries to find out when this binary was compiled.
// Returns the current time if it fails to find it.
func
compileTime
()
time
.
Time
{
info
,
err
:=
os
.
Stat
(
os
.
Args
[
0
])
if
err
!=
nil
{
return
time
.
Now
()
}
return
info
.
ModTime
()
}
// NewApp creates a new cli Application with some reasonable defaults for Name,
// Usage, Version and Action.
func
NewApp
()
*
App
{
return
&
App
{
Name
:
filepath
.
Base
(
os
.
Args
[
0
]),
Usage
:
"A new cli application"
,
UsageText
:
""
,
BashComplete
:
DefaultAppComplete
,
Action
:
helpCommand
.
Action
,
Compiled
:
compileTime
(),
Reader
:
os
.
Stdin
,
Writer
:
os
.
Stdout
,
ErrWriter
:
os
.
Stderr
,
}
}
// Setup runs initialization code to ensure all data structures are ready for
// `Run` or inspection prior to `Run`. It is internally called by `Run`, but
// will return early if setup has already happened.
func
(
a
*
App
)
Setup
()
{
if
a
.
didSetup
{
return
}
a
.
didSetup
=
true
if
a
.
Name
==
""
{
a
.
Name
=
filepath
.
Base
(
os
.
Args
[
0
])
}
if
a
.
HelpName
==
""
{
a
.
HelpName
=
a
.
Name
}
if
a
.
Usage
==
""
{
a
.
Usage
=
"A new cli application"
}
if
a
.
Version
==
""
{
a
.
HideVersion
=
true
}
if
a
.
BashComplete
==
nil
{
a
.
BashComplete
=
DefaultAppComplete
}
if
a
.
Action
==
nil
{
a
.
Action
=
helpCommand
.
Action
}
if
a
.
Compiled
==
(
time
.
Time
{})
{
a
.
Compiled
=
compileTime
()
}
if
a
.
Reader
==
nil
{
a
.
Reader
=
os
.
Stdin
}
if
a
.
Writer
==
nil
{
a
.
Writer
=
os
.
Stdout
}
if
a
.
ErrWriter
==
nil
{
a
.
ErrWriter
=
os
.
Stderr
}
if
a
.
AllowExtFlags
{
// add global flags added by other packages
flag
.
VisitAll
(
func
(
f
*
flag
.
Flag
)
{
// skip test flags
if
!
strings
.
HasPrefix
(
f
.
Name
,
ignoreFlagPrefix
)
{
a
.
Flags
=
append
(
a
.
Flags
,
&
extFlag
{
f
})
}
})
}
if
len
(
a
.
SliceFlagSeparator
)
!=
0
{
a
.
separator
.
customized
=
true
a
.
separator
.
sep
=
a
.
SliceFlagSeparator
}
if
a
.
DisableSliceFlagSeparator
{
a
.
separator
.
customized
=
true
a
.
separator
.
disabled
=
true
}
for
_
,
c
:=
range
a
.
Commands
{
cname
:=
c
.
Name
if
c
.
HelpName
!=
""
{
cname
=
c
.
HelpName
}
c
.
separator
=
a
.
separator
c
.
HelpName
=
fmt
.
Sprintf
(
"%s %s"
,
a
.
HelpName
,
cname
)
c
.
flagCategories
=
newFlagCategoriesFromFlags
(
c
.
Flags
)
}
if
a
.
Command
(
helpCommand
.
Name
)
==
nil
&&
!
a
.
HideHelp
{
if
!
a
.
HideHelpCommand
{
a
.
appendCommand
(
helpCommand
)
}
if
HelpFlag
!=
nil
{
a
.
appendFlag
(
HelpFlag
)
}
}
if
!
a
.
HideVersion
{
a
.
appendFlag
(
VersionFlag
)
}
a
.
categories
=
newCommandCategories
()
for
_
,
command
:=
range
a
.
Commands
{
a
.
categories
.
AddCommand
(
command
.
Category
,
command
)
}
sort
.
Sort
(
a
.
categories
.
(
*
commandCategories
))
a
.
flagCategories
=
newFlagCategoriesFromFlags
(
a
.
Flags
)
if
a
.
Metadata
==
nil
{
a
.
Metadata
=
make
(
map
[
string
]
interface
{})
}
}
func
(
a
*
App
)
newRootCommand
()
*
Command
{
return
&
Command
{
Name
:
a
.
Name
,
Usage
:
a
.
Usage
,
UsageText
:
a
.
UsageText
,
Description
:
a
.
Description
,
ArgsUsage
:
a
.
ArgsUsage
,
BashComplete
:
a
.
BashComplete
,
Before
:
a
.
Before
,
After
:
a
.
After
,
Action
:
a
.
Action
,
OnUsageError
:
a
.
OnUsageError
,
Subcommands
:
a
.
Commands
,
Flags
:
a
.
Flags
,
flagCategories
:
a
.
flagCategories
,
HideHelp
:
a
.
HideHelp
,
HideHelpCommand
:
a
.
HideHelpCommand
,
UseShortOptionHandling
:
a
.
UseShortOptionHandling
,
HelpName
:
a
.
HelpName
,
CustomHelpTemplate
:
a
.
CustomAppHelpTemplate
,
categories
:
a
.
categories
,
SkipFlagParsing
:
a
.
SkipFlagParsing
,
isRoot
:
true
,
separator
:
a
.
separator
,
}
}
func
(
a
*
App
)
newFlagSet
()
(
*
flag
.
FlagSet
,
error
)
{
return
flagSet
(
a
.
Name
,
a
.
Flags
,
a
.
separator
)
}
func
(
a
*
App
)
useShortOptionHandling
()
bool
{
return
a
.
UseShortOptionHandling
}
// Run is the entry point to the cli app. Parses the arguments slice and routes
// to the proper flag/args combination
func
(
a
*
App
)
Run
(
arguments
[]
string
)
(
err
error
)
{
return
a
.
RunContext
(
context
.
Background
(),
arguments
)
}
// RunContext is like Run except it takes a Context that will be
// passed to its commands and sub-commands. Through this, you can
// propagate timeouts and cancellation requests
func
(
a
*
App
)
RunContext
(
ctx
context
.
Context
,
arguments
[]
string
)
(
err
error
)
{
a
.
Setup
()
// handle the completion flag separately from the flagset since
// completion could be attempted after a flag, but before its value was put
// on the command line. this causes the flagset to interpret the completion
// flag name as the value of the flag before it which is undesirable
// note that we can only do this because the shell autocomplete function
// always appends the completion flag at the end of the command
shellComplete
,
arguments
:=
checkShellCompleteFlag
(
a
,
arguments
)
cCtx
:=
NewContext
(
a
,
nil
,
&
Context
{
Context
:
ctx
})
cCtx
.
shellComplete
=
shellComplete
a
.
rootCommand
=
a
.
newRootCommand
()
cCtx
.
Command
=
a
.
rootCommand
if
err
:=
checkDuplicatedCmds
(
a
.
rootCommand
);
err
!=
nil
{
return
err
}
return
a
.
rootCommand
.
Run
(
cCtx
,
arguments
...
)
}
// RunAsSubcommand is for legacy/compatibility purposes only. New code should only
// use App.RunContext. This function is slated to be removed in v3.
func
(
a
*
App
)
RunAsSubcommand
(
ctx
*
Context
)
(
err
error
)
{
a
.
Setup
()
cCtx
:=
NewContext
(
a
,
nil
,
ctx
)
cCtx
.
shellComplete
=
ctx
.
shellComplete
a
.
rootCommand
=
a
.
newRootCommand
()
cCtx
.
Command
=
a
.
rootCommand
return
a
.
rootCommand
.
Run
(
cCtx
,
ctx
.
Args
()
.
Slice
()
...
)
}
func
(
a
*
App
)
suggestFlagFromError
(
err
error
,
command
string
)
(
string
,
error
)
{
flag
,
parseErr
:=
flagFromError
(
err
)
if
parseErr
!=
nil
{
return
""
,
err
}
flags
:=
a
.
Flags
hideHelp
:=
a
.
HideHelp
if
command
!=
""
{
cmd
:=
a
.
Command
(
command
)
if
cmd
==
nil
{
return
""
,
err
}
flags
=
cmd
.
Flags
hideHelp
=
hideHelp
||
cmd
.
HideHelp
}
if
SuggestFlag
==
nil
{
return
""
,
err
}
suggestion
:=
SuggestFlag
(
flags
,
flag
,
hideHelp
)
if
len
(
suggestion
)
==
0
{
return
""
,
err
}
return
fmt
.
Sprintf
(
SuggestDidYouMeanTemplate
+
"
\n\n
"
,
suggestion
),
nil
}
// RunAndExitOnError calls .Run() and exits non-zero if an error was returned
//
// Deprecated: instead you should return an error that fulfills cli.ExitCoder
// to cli.App.Run. This will cause the application to exit with the given error
// code in the cli.ExitCoder
func
(
a
*
App
)
RunAndExitOnError
()
{
if
err
:=
a
.
Run
(
os
.
Args
);
err
!=
nil
{
_
,
_
=
fmt
.
Fprintln
(
a
.
ErrWriter
,
err
)
OsExiter
(
1
)
}
}
// Command returns the named command on App. Returns nil if the command does not exist
func
(
a
*
App
)
Command
(
name
string
)
*
Command
{
for
_
,
c
:=
range
a
.
Commands
{
if
c
.
HasName
(
name
)
{
return
c
}
}
return
nil
}
// VisibleCategories returns a slice of categories and commands that are
// Hidden=false
func
(
a
*
App
)
VisibleCategories
()
[]
CommandCategory
{
ret
:=
[]
CommandCategory
{}
for
_
,
category
:=
range
a
.
categories
.
Categories
()
{
if
visible
:=
func
()
CommandCategory
{
if
len
(
category
.
VisibleCommands
())
>
0
{
return
category
}
return
nil
}();
visible
!=
nil
{
ret
=
append
(
ret
,
visible
)
}
}
return
ret
}
// VisibleCommands returns a slice of the Commands with Hidden=false
func
(
a
*
App
)
VisibleCommands
()
[]
*
Command
{
var
ret
[]
*
Command
for
_
,
command
:=
range
a
.
Commands
{
if
!
command
.
Hidden
{
ret
=
append
(
ret
,
command
)
}
}
return
ret
}
// VisibleFlagCategories returns a slice containing all the categories with the flags they contain
func
(
a
*
App
)
VisibleFlagCategories
()
[]
VisibleFlagCategory
{
if
a
.
flagCategories
==
nil
{
return
[]
VisibleFlagCategory
{}
}
return
a
.
flagCategories
.
VisibleCategories
()
}
// VisibleFlags returns a slice of the Flags with Hidden=false
func
(
a
*
App
)
VisibleFlags
()
[]
Flag
{
return
visibleFlags
(
a
.
Flags
)
}
func
(
a
*
App
)
appendFlag
(
fl
Flag
)
{
if
!
hasFlag
(
a
.
Flags
,
fl
)
{
a
.
Flags
=
append
(
a
.
Flags
,
fl
)
}
}
func
(
a
*
App
)
appendCommand
(
c
*
Command
)
{
if
!
hasCommand
(
a
.
Commands
,
c
)
{
a
.
Commands
=
append
(
a
.
Commands
,
c
)
}
}
func
(
a
*
App
)
handleExitCoder
(
cCtx
*
Context
,
err
error
)
{
if
a
.
ExitErrHandler
!=
nil
{
a
.
ExitErrHandler
(
cCtx
,
err
)
}
else
{
HandleExitCoder
(
err
)
}
}
func
(
a
*
App
)
argsWithDefaultCommand
(
oldArgs
Args
)
Args
{
if
a
.
DefaultCommand
!=
""
{
rawArgs
:=
append
([]
string
{
a
.
DefaultCommand
},
oldArgs
.
Slice
()
...
)
newArgs
:=
args
(
rawArgs
)
return
&
newArgs
}
return
oldArgs
}
func
runFlagActions
(
c
*
Context
,
fs
[]
Flag
)
error
{
for
_
,
f
:=
range
fs
{
isSet
:=
false
for
_
,
name
:=
range
f
.
Names
()
{
if
c
.
IsSet
(
name
)
{
isSet
=
true
break
}
}
if
isSet
{
if
af
,
ok
:=
f
.
(
ActionableFlag
);
ok
{
if
err
:=
af
.
RunAction
(
c
);
err
!=
nil
{
return
err
}
}
}
}
return
nil
}
// Author represents someone who has contributed to a cli project.
type
Author
struct
{
Name
string
// The Authors name
Email
string
// The Authors email
}
// String makes Author comply to the Stringer interface, to allow an easy print in the templating process
func
(
a
*
Author
)
String
()
string
{
e
:=
""
if
a
.
Email
!=
""
{
e
=
" <"
+
a
.
Email
+
">"
}
return
fmt
.
Sprintf
(
"%v%v"
,
a
.
Name
,
e
)
}
// HandleAction attempts to figure out which Action signature was used. If
// it's an ActionFunc or a func with the legacy signature for Action, the func
// is run!
func
HandleAction
(
action
interface
{},
cCtx
*
Context
)
(
err
error
)
{
switch
a
:=
action
.
(
type
)
{
case
ActionFunc
:
return
a
(
cCtx
)
case
func
(
*
Context
)
error
:
return
a
(
cCtx
)
case
func
(
*
Context
)
:
// deprecated function signature
a
(
cCtx
)
return
nil
}
return
errInvalidActionType
}
func
checkStringSliceIncludes
(
want
string
,
sSlice
[]
string
)
bool
{
found
:=
false
for
_
,
s
:=
range
sSlice
{
if
want
==
s
{
found
=
true
break
}
}
return
found
}
vendor/github.com/urfave/cli/v2/args.go
0 → 100644
View file @
d7e13eb9
package
cli
type
Args
interface
{
// Get returns the nth argument, or else a blank string
Get
(
n
int
)
string
// First returns the first argument, or else a blank string
First
()
string
// Tail returns the rest of the arguments (not the first one)
// or else an empty string slice
Tail
()
[]
string
// Len returns the length of the wrapped slice
Len
()
int
// Present checks if there are any arguments present
Present
()
bool
// Slice returns a copy of the internal slice
Slice
()
[]
string
}
type
args
[]
string
func
(
a
*
args
)
Get
(
n
int
)
string
{
if
len
(
*
a
)
>
n
{
return
(
*
a
)[
n
]
}
return
""
}
func
(
a
*
args
)
First
()
string
{
return
a
.
Get
(
0
)
}
func
(
a
*
args
)
Tail
()
[]
string
{
if
a
.
Len
()
>=
2
{
tail
:=
[]
string
((
*
a
)[
1
:
])
ret
:=
make
([]
string
,
len
(
tail
))
copy
(
ret
,
tail
)
return
ret
}
return
[]
string
{}
}
func
(
a
*
args
)
Len
()
int
{
return
len
(
*
a
)
}
func
(
a
*
args
)
Present
()
bool
{
return
a
.
Len
()
!=
0
}
func
(
a
*
args
)
Slice
()
[]
string
{
ret
:=
make
([]
string
,
len
(
*
a
))
copy
(
ret
,
*
a
)
return
ret
}
vendor/github.com/urfave/cli/v2/category.go
0 → 100644
View file @
d7e13eb9
package
cli
import
"sort"
// CommandCategories interface allows for category manipulation
type
CommandCategories
interface
{
// AddCommand adds a command to a category, creating a new category if necessary.
AddCommand
(
category
string
,
command
*
Command
)
// Categories returns a slice of categories sorted by name
Categories
()
[]
CommandCategory
}
type
commandCategories
[]
*
commandCategory
func
newCommandCategories
()
CommandCategories
{
ret
:=
commandCategories
([]
*
commandCategory
{})
return
&
ret
}
func
(
c
*
commandCategories
)
Less
(
i
,
j
int
)
bool
{
return
lexicographicLess
((
*
c
)[
i
]
.
Name
(),
(
*
c
)[
j
]
.
Name
())
}
func
(
c
*
commandCategories
)
Len
()
int
{
return
len
(
*
c
)
}
func
(
c
*
commandCategories
)
Swap
(
i
,
j
int
)
{
(
*
c
)[
i
],
(
*
c
)[
j
]
=
(
*
c
)[
j
],
(
*
c
)[
i
]
}
func
(
c
*
commandCategories
)
AddCommand
(
category
string
,
command
*
Command
)
{
for
_
,
commandCategory
:=
range
[]
*
commandCategory
(
*
c
)
{
if
commandCategory
.
name
==
category
{
commandCategory
.
commands
=
append
(
commandCategory
.
commands
,
command
)
return
}
}
newVal
:=
append
(
*
c
,
&
commandCategory
{
name
:
category
,
commands
:
[]
*
Command
{
command
}})
*
c
=
newVal
}
func
(
c
*
commandCategories
)
Categories
()
[]
CommandCategory
{
ret
:=
make
([]
CommandCategory
,
len
(
*
c
))
for
i
,
cat
:=
range
*
c
{
ret
[
i
]
=
cat
}
return
ret
}
// CommandCategory is a category containing commands.
type
CommandCategory
interface
{
// Name returns the category name string
Name
()
string
// VisibleCommands returns a slice of the Commands with Hidden=false
VisibleCommands
()
[]
*
Command
}
type
commandCategory
struct
{
name
string
commands
[]
*
Command
}
func
(
c
*
commandCategory
)
Name
()
string
{
return
c
.
name
}
func
(
c
*
commandCategory
)
VisibleCommands
()
[]
*
Command
{
if
c
.
commands
==
nil
{
c
.
commands
=
[]
*
Command
{}
}
var
ret
[]
*
Command
for
_
,
command
:=
range
c
.
commands
{
if
!
command
.
Hidden
{
ret
=
append
(
ret
,
command
)
}
}
return
ret
}
// FlagCategories interface allows for category manipulation
type
FlagCategories
interface
{
// AddFlags adds a flag to a category, creating a new category if necessary.
AddFlag
(
category
string
,
fl
Flag
)
// VisibleCategories returns a slice of visible flag categories sorted by name
VisibleCategories
()
[]
VisibleFlagCategory
}
type
defaultFlagCategories
struct
{
m
map
[
string
]
*
defaultVisibleFlagCategory
}
func
newFlagCategories
()
FlagCategories
{
return
&
defaultFlagCategories
{
m
:
map
[
string
]
*
defaultVisibleFlagCategory
{},
}
}
func
newFlagCategoriesFromFlags
(
fs
[]
Flag
)
FlagCategories
{
fc
:=
newFlagCategories
()
var
categorized
bool
for
_
,
fl
:=
range
fs
{
if
cf
,
ok
:=
fl
.
(
CategorizableFlag
);
ok
{
if
cat
:=
cf
.
GetCategory
();
cat
!=
""
&&
cf
.
IsVisible
()
{
fc
.
AddFlag
(
cat
,
cf
)
categorized
=
true
}
}
}
if
categorized
{
for
_
,
fl
:=
range
fs
{
if
cf
,
ok
:=
fl
.
(
CategorizableFlag
);
ok
{
if
cf
.
GetCategory
()
==
""
&&
cf
.
IsVisible
()
{
fc
.
AddFlag
(
""
,
fl
)
}
}
}
}
return
fc
}
func
(
f
*
defaultFlagCategories
)
AddFlag
(
category
string
,
fl
Flag
)
{
if
_
,
ok
:=
f
.
m
[
category
];
!
ok
{
f
.
m
[
category
]
=
&
defaultVisibleFlagCategory
{
name
:
category
,
m
:
map
[
string
]
Flag
{}}
}
f
.
m
[
category
]
.
m
[
fl
.
String
()]
=
fl
}
func
(
f
*
defaultFlagCategories
)
VisibleCategories
()
[]
VisibleFlagCategory
{
catNames
:=
[]
string
{}
for
name
:=
range
f
.
m
{
catNames
=
append
(
catNames
,
name
)
}
sort
.
Strings
(
catNames
)
ret
:=
make
([]
VisibleFlagCategory
,
len
(
catNames
))
for
i
,
name
:=
range
catNames
{
ret
[
i
]
=
f
.
m
[
name
]
}
return
ret
}
// VisibleFlagCategory is a category containing flags.
type
VisibleFlagCategory
interface
{
// Name returns the category name string
Name
()
string
// Flags returns a slice of VisibleFlag sorted by name
Flags
()
[]
VisibleFlag
}
type
defaultVisibleFlagCategory
struct
{
name
string
m
map
[
string
]
Flag
}
func
(
fc
*
defaultVisibleFlagCategory
)
Name
()
string
{
return
fc
.
name
}
func
(
fc
*
defaultVisibleFlagCategory
)
Flags
()
[]
VisibleFlag
{
vfNames
:=
[]
string
{}
for
flName
,
fl
:=
range
fc
.
m
{
if
vf
,
ok
:=
fl
.
(
VisibleFlag
);
ok
{
if
vf
.
IsVisible
()
{
vfNames
=
append
(
vfNames
,
flName
)
}
}
}
sort
.
Strings
(
vfNames
)
ret
:=
make
([]
VisibleFlag
,
len
(
vfNames
))
for
i
,
flName
:=
range
vfNames
{
ret
[
i
]
=
fc
.
m
[
flName
]
.
(
VisibleFlag
)
}
return
ret
}
vendor/github.com/urfave/cli/v2/cli.go
0 → 100644
View file @
d7e13eb9
// Package cli provides a minimal framework for creating and organizing command line
// Go applications. cli is designed to be easy to understand and write, the most simple
// cli application can be written as follows:
//
// func main() {
// (&cli.App{}).Run(os.Args)
// }
//
// Of course this application does not do much, so let's make this an actual application:
//
// func main() {
// app := &cli.App{
// Name: "greet",
// Usage: "say a greeting",
// Action: func(c *cli.Context) error {
// fmt.Println("Greetings")
// return nil
// },
// }
//
// app.Run(os.Args)
// }
package
cli
//go:generate make -C cmd/urfave-cli-genflags run
vendor/github.com/urfave/cli/v2/command.go
0 → 100644
View file @
d7e13eb9
package
cli
import
(
"flag"
"fmt"
"reflect"
"sort"
"strings"
)
// Command is a subcommand for a cli.App.
type
Command
struct
{
// The name of the command
Name
string
// A list of aliases for the command
Aliases
[]
string
// A short description of the usage of this command
Usage
string
// Custom text to show on USAGE section of help
UsageText
string
// A longer explanation of how the command works
Description
string
// Whether this command supports arguments
Args
bool
// A short description of the arguments of this command
ArgsUsage
string
// The category the command is part of
Category
string
// The function to call when checking for bash command completions
BashComplete
BashCompleteFunc
// An action to execute before any sub-subcommands are run, but after the context is ready
// If a non-nil error is returned, no sub-subcommands are run
Before
BeforeFunc
// An action to execute after any subcommands are run, but after the subcommand has finished
// It is run even if Action() panics
After
AfterFunc
// The function to call when this command is invoked
Action
ActionFunc
// Execute this function if a usage error occurs.
OnUsageError
OnUsageErrorFunc
// List of child commands
Subcommands
[]
*
Command
// List of flags to parse
Flags
[]
Flag
flagCategories
FlagCategories
// Treat all flags as normal arguments if true
SkipFlagParsing
bool
// Boolean to hide built-in help command and help flag
HideHelp
bool
// Boolean to hide built-in help command but keep help flag
// Ignored if HideHelp is true.
HideHelpCommand
bool
// Boolean to hide this command from help or completion
Hidden
bool
// Boolean to enable short-option handling so user can combine several
// single-character bool arguments into one
// i.e. foobar -o -v -> foobar -ov
UseShortOptionHandling
bool
// Full name of command for help, defaults to full command name, including parent commands.
HelpName
string
commandNamePath
[]
string
// CustomHelpTemplate the text template for the command help topic.
// cli.go uses text/template to render templates. You can
// render custom help text by setting this variable.
CustomHelpTemplate
string
// categories contains the categorized commands and is populated on app startup
categories
CommandCategories
// if this is a root "special" command
isRoot
bool
separator
separatorSpec
}
type
Commands
[]
*
Command
type
CommandsByName
[]
*
Command
func
(
c
CommandsByName
)
Len
()
int
{
return
len
(
c
)
}
func
(
c
CommandsByName
)
Less
(
i
,
j
int
)
bool
{
return
lexicographicLess
(
c
[
i
]
.
Name
,
c
[
j
]
.
Name
)
}
func
(
c
CommandsByName
)
Swap
(
i
,
j
int
)
{
c
[
i
],
c
[
j
]
=
c
[
j
],
c
[
i
]
}
// FullName returns the full name of the command.
// For subcommands this ensures that parent commands are part of the command path
func
(
c
*
Command
)
FullName
()
string
{
if
c
.
commandNamePath
==
nil
{
return
c
.
Name
}
return
strings
.
Join
(
c
.
commandNamePath
,
" "
)
}
func
(
cmd
*
Command
)
Command
(
name
string
)
*
Command
{
for
_
,
c
:=
range
cmd
.
Subcommands
{
if
c
.
HasName
(
name
)
{
return
c
}
}
return
nil
}
func
(
c
*
Command
)
setup
(
ctx
*
Context
)
{
if
c
.
Command
(
helpCommand
.
Name
)
==
nil
&&
!
c
.
HideHelp
{
if
!
c
.
HideHelpCommand
{
c
.
Subcommands
=
append
(
c
.
Subcommands
,
helpCommand
)
}
}
if
!
c
.
HideHelp
&&
HelpFlag
!=
nil
{
// append help to flags
c
.
appendFlag
(
HelpFlag
)
}
if
ctx
.
App
.
UseShortOptionHandling
{
c
.
UseShortOptionHandling
=
true
}
c
.
categories
=
newCommandCategories
()
for
_
,
command
:=
range
c
.
Subcommands
{
c
.
categories
.
AddCommand
(
command
.
Category
,
command
)
}
sort
.
Sort
(
c
.
categories
.
(
*
commandCategories
))
for
_
,
scmd
:=
range
c
.
Subcommands
{
if
scmd
.
HelpName
==
""
{
scmd
.
HelpName
=
fmt
.
Sprintf
(
"%s %s"
,
c
.
HelpName
,
scmd
.
Name
)
}
scmd
.
separator
=
c
.
separator
}
if
c
.
BashComplete
==
nil
{
c
.
BashComplete
=
DefaultCompleteWithFlags
(
c
)
}
}
func
(
c
*
Command
)
Run
(
cCtx
*
Context
,
arguments
...
string
)
(
err
error
)
{
if
!
c
.
isRoot
{
c
.
setup
(
cCtx
)
if
err
:=
checkDuplicatedCmds
(
c
);
err
!=
nil
{
return
err
}
}
a
:=
args
(
arguments
)
set
,
err
:=
c
.
parseFlags
(
&
a
,
cCtx
.
shellComplete
)
cCtx
.
flagSet
=
set
if
checkCompletions
(
cCtx
)
{
return
nil
}
if
err
!=
nil
{
if
c
.
OnUsageError
!=
nil
{
err
=
c
.
OnUsageError
(
cCtx
,
err
,
!
c
.
isRoot
)
cCtx
.
App
.
handleExitCoder
(
cCtx
,
err
)
return
err
}
_
,
_
=
fmt
.
Fprintf
(
cCtx
.
App
.
Writer
,
"%s %s
\n\n
"
,
"Incorrect Usage:"
,
err
.
Error
())
if
cCtx
.
App
.
Suggest
{
if
suggestion
,
err
:=
c
.
suggestFlagFromError
(
err
,
""
);
err
==
nil
{
fmt
.
Fprintf
(
cCtx
.
App
.
Writer
,
"%s"
,
suggestion
)
}
}
if
!
c
.
HideHelp
{
if
c
.
isRoot
{
_
=
ShowAppHelp
(
cCtx
)
}
else
{
_
=
ShowCommandHelp
(
cCtx
.
parentContext
,
c
.
Name
)
}
}
return
err
}
if
checkHelp
(
cCtx
)
{
return
helpCommand
.
Action
(
cCtx
)
}
if
c
.
isRoot
&&
!
cCtx
.
App
.
HideVersion
&&
checkVersion
(
cCtx
)
{
ShowVersion
(
cCtx
)
return
nil
}
if
c
.
After
!=
nil
&&
!
cCtx
.
shellComplete
{
defer
func
()
{
afterErr
:=
c
.
After
(
cCtx
)
if
afterErr
!=
nil
{
cCtx
.
App
.
handleExitCoder
(
cCtx
,
err
)
if
err
!=
nil
{
err
=
newMultiError
(
err
,
afterErr
)
}
else
{
err
=
afterErr
}
}
}()
}
cerr
:=
cCtx
.
checkRequiredFlags
(
c
.
Flags
)
if
cerr
!=
nil
{
_
=
helpCommand
.
Action
(
cCtx
)
return
cerr
}
if
c
.
Before
!=
nil
&&
!
cCtx
.
shellComplete
{
beforeErr
:=
c
.
Before
(
cCtx
)
if
beforeErr
!=
nil
{
cCtx
.
App
.
handleExitCoder
(
cCtx
,
beforeErr
)
err
=
beforeErr
return
err
}
}
if
err
=
runFlagActions
(
cCtx
,
c
.
Flags
);
err
!=
nil
{
return
err
}
var
cmd
*
Command
args
:=
cCtx
.
Args
()
if
args
.
Present
()
{
name
:=
args
.
First
()
cmd
=
c
.
Command
(
name
)
if
cmd
==
nil
{
hasDefault
:=
cCtx
.
App
.
DefaultCommand
!=
""
isFlagName
:=
checkStringSliceIncludes
(
name
,
cCtx
.
FlagNames
())
var
(
isDefaultSubcommand
=
false
defaultHasSubcommands
=
false
)
if
hasDefault
{
dc
:=
cCtx
.
App
.
Command
(
cCtx
.
App
.
DefaultCommand
)
defaultHasSubcommands
=
len
(
dc
.
Subcommands
)
>
0
for
_
,
dcSub
:=
range
dc
.
Subcommands
{
if
checkStringSliceIncludes
(
name
,
dcSub
.
Names
())
{
isDefaultSubcommand
=
true
break
}
}
}
if
isFlagName
||
(
hasDefault
&&
(
defaultHasSubcommands
&&
isDefaultSubcommand
))
{
argsWithDefault
:=
cCtx
.
App
.
argsWithDefaultCommand
(
args
)
if
!
reflect
.
DeepEqual
(
args
,
argsWithDefault
)
{
cmd
=
cCtx
.
App
.
rootCommand
.
Command
(
argsWithDefault
.
First
())
}
}
}
}
else
if
c
.
isRoot
&&
cCtx
.
App
.
DefaultCommand
!=
""
{
if
dc
:=
cCtx
.
App
.
Command
(
cCtx
.
App
.
DefaultCommand
);
dc
!=
c
{
cmd
=
dc
}
}
if
cmd
!=
nil
{
newcCtx
:=
NewContext
(
cCtx
.
App
,
nil
,
cCtx
)
newcCtx
.
Command
=
cmd
return
cmd
.
Run
(
newcCtx
,
cCtx
.
Args
()
.
Slice
()
...
)
}
if
c
.
Action
==
nil
{
c
.
Action
=
helpCommand
.
Action
}
err
=
c
.
Action
(
cCtx
)
cCtx
.
App
.
handleExitCoder
(
cCtx
,
err
)
return
err
}
func
(
c
*
Command
)
newFlagSet
()
(
*
flag
.
FlagSet
,
error
)
{
return
flagSet
(
c
.
Name
,
c
.
Flags
,
c
.
separator
)
}
func
(
c
*
Command
)
useShortOptionHandling
()
bool
{
return
c
.
UseShortOptionHandling
}
func
(
c
*
Command
)
suggestFlagFromError
(
err
error
,
command
string
)
(
string
,
error
)
{
flag
,
parseErr
:=
flagFromError
(
err
)
if
parseErr
!=
nil
{
return
""
,
err
}
flags
:=
c
.
Flags
hideHelp
:=
c
.
HideHelp
if
command
!=
""
{
cmd
:=
c
.
Command
(
command
)
if
cmd
==
nil
{
return
""
,
err
}
flags
=
cmd
.
Flags
hideHelp
=
hideHelp
||
cmd
.
HideHelp
}
suggestion
:=
SuggestFlag
(
flags
,
flag
,
hideHelp
)
if
len
(
suggestion
)
==
0
{
return
""
,
err
}
return
fmt
.
Sprintf
(
SuggestDidYouMeanTemplate
,
suggestion
)
+
"
\n\n
"
,
nil
}
func
(
c
*
Command
)
parseFlags
(
args
Args
,
shellComplete
bool
)
(
*
flag
.
FlagSet
,
error
)
{
set
,
err
:=
c
.
newFlagSet
()
if
err
!=
nil
{
return
nil
,
err
}
if
c
.
SkipFlagParsing
{
return
set
,
set
.
Parse
(
append
([]
string
{
"--"
},
args
.
Tail
()
...
))
}
err
=
parseIter
(
set
,
c
,
args
.
Tail
(),
shellComplete
)
if
err
!=
nil
{
return
nil
,
err
}
err
=
normalizeFlags
(
c
.
Flags
,
set
)
if
err
!=
nil
{
return
nil
,
err
}
return
set
,
nil
}
// Names returns the names including short names and aliases.
func
(
c
*
Command
)
Names
()
[]
string
{
return
append
([]
string
{
c
.
Name
},
c
.
Aliases
...
)
}
// HasName returns true if Command.Name matches given name
func
(
c
*
Command
)
HasName
(
name
string
)
bool
{
for
_
,
n
:=
range
c
.
Names
()
{
if
n
==
name
{
return
true
}
}
return
false
}
// VisibleCategories returns a slice of categories and commands that are
// Hidden=false
func
(
c
*
Command
)
VisibleCategories
()
[]
CommandCategory
{
ret
:=
[]
CommandCategory
{}
for
_
,
category
:=
range
c
.
categories
.
Categories
()
{
if
visible
:=
func
()
CommandCategory
{
if
len
(
category
.
VisibleCommands
())
>
0
{
return
category
}
return
nil
}();
visible
!=
nil
{
ret
=
append
(
ret
,
visible
)
}
}
return
ret
}
// VisibleCommands returns a slice of the Commands with Hidden=false
func
(
c
*
Command
)
VisibleCommands
()
[]
*
Command
{
var
ret
[]
*
Command
for
_
,
command
:=
range
c
.
Subcommands
{
if
!
command
.
Hidden
{
ret
=
append
(
ret
,
command
)
}
}
return
ret
}
// VisibleFlagCategories returns a slice containing all the visible flag categories with the flags they contain
func
(
c
*
Command
)
VisibleFlagCategories
()
[]
VisibleFlagCategory
{
if
c
.
flagCategories
==
nil
{
c
.
flagCategories
=
newFlagCategoriesFromFlags
(
c
.
Flags
)
}
return
c
.
flagCategories
.
VisibleCategories
()
}
// VisibleFlags returns a slice of the Flags with Hidden=false
func
(
c
*
Command
)
VisibleFlags
()
[]
Flag
{
return
visibleFlags
(
c
.
Flags
)
}
func
(
c
*
Command
)
appendFlag
(
fl
Flag
)
{
if
!
hasFlag
(
c
.
Flags
,
fl
)
{
c
.
Flags
=
append
(
c
.
Flags
,
fl
)
}
}
func
hasCommand
(
commands
[]
*
Command
,
command
*
Command
)
bool
{
for
_
,
existing
:=
range
commands
{
if
command
==
existing
{
return
true
}
}
return
false
}
func
checkDuplicatedCmds
(
parent
*
Command
)
error
{
seen
:=
make
(
map
[
string
]
struct
{})
for
_
,
c
:=
range
parent
.
Subcommands
{
for
_
,
name
:=
range
c
.
Names
()
{
if
_
,
exists
:=
seen
[
name
];
exists
{
return
fmt
.
Errorf
(
"parent command [%s] has duplicated subcommand name or alias: %s"
,
parent
.
Name
,
name
)
}
seen
[
name
]
=
struct
{}{}
}
}
return
nil
}
Prev
1
…
12
13
14
15
16
17
18
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment