Update module golang.org/x/tools to v0.18.0
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
This commit is contained in:
parent
ea3221a862
commit
53b5fc781f
|
@ -6,7 +6,7 @@ require (
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.3
|
github.com/cpuguy83/go-md2man/v2 v2.0.3
|
||||||
github.com/onsi/ginkgo/v2 v2.14.0
|
github.com/onsi/ginkgo/v2 v2.14.0
|
||||||
github.com/vbatts/git-validation v1.2.1
|
github.com/vbatts/git-validation v1.2.1
|
||||||
golang.org/x/tools v0.17.0
|
golang.org/x/tools v0.18.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
@ -19,6 +19,6 @@ require (
|
||||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
golang.org/x/mod v0.14.0 // indirect
|
golang.org/x/mod v0.15.0 // indirect
|
||||||
golang.org/x/sys v0.15.0 // indirect
|
golang.org/x/sys v0.17.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -40,18 +40,18 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
|
||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/vbatts/git-validation v1.2.1 h1:O26LKWEtBOfnxKT/SAiFCAcQglKwyuZEKSq6AevpWJ4=
|
github.com/vbatts/git-validation v1.2.1 h1:O26LKWEtBOfnxKT/SAiFCAcQglKwyuZEKSq6AevpWJ4=
|
||||||
github.com/vbatts/git-validation v1.2.1/go.mod h1:isqpXnI2IUKUhoYIsHg5tDmtiEXoA7KJRVsAc4+XoYw=
|
github.com/vbatts/git-validation v1.2.1/go.mod h1:isqpXnI2IUKUhoYIsHg5tDmtiEXoA7KJRVsAc4+XoYw=
|
||||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
||||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
@ -248,6 +248,7 @@ struct ltchars {
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mount.h>
|
#include <linux/mount.h>
|
||||||
#include <linux/netfilter/nfnetlink.h>
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
|
#include <linux/netfilter/nf_tables.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/net_namespace.h>
|
#include <linux/net_namespace.h>
|
||||||
#include <linux/nfc.h>
|
#include <linux/nfc.h>
|
||||||
|
@ -283,10 +284,6 @@ struct ltchars {
|
||||||
#include <asm/termbits.h>
|
#include <asm/termbits.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MSG_FASTOPEN
|
|
||||||
#define MSG_FASTOPEN 0x20000000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PTRACE_GETREGS
|
#ifndef PTRACE_GETREGS
|
||||||
#define PTRACE_GETREGS 0xc
|
#define PTRACE_GETREGS 0xc
|
||||||
#endif
|
#endif
|
||||||
|
@ -295,14 +292,6 @@ struct ltchars {
|
||||||
#define PTRACE_SETREGS 0xd
|
#define PTRACE_SETREGS 0xd
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SOL_NETLINK
|
|
||||||
#define SOL_NETLINK 270
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SOL_SMC
|
|
||||||
#define SOL_SMC 286
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SOL_BLUETOOTH
|
#ifdef SOL_BLUETOOTH
|
||||||
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
|
// SPARC includes this in /usr/include/sparc64-linux-gnu/bits/socket.h
|
||||||
// but it is already in bluetooth_linux.go
|
// but it is already in bluetooth_linux.go
|
||||||
|
@ -319,10 +308,23 @@ struct ltchars {
|
||||||
#undef TIPC_WAIT_FOREVER
|
#undef TIPC_WAIT_FOREVER
|
||||||
#define TIPC_WAIT_FOREVER 0xffffffff
|
#define TIPC_WAIT_FOREVER 0xffffffff
|
||||||
|
|
||||||
// Copied from linux/l2tp.h
|
// Copied from linux/netfilter/nf_nat.h
|
||||||
// Including linux/l2tp.h here causes conflicts between linux/in.h
|
// Including linux/netfilter/nf_nat.h here causes conflicts between linux/in.h
|
||||||
// and netinet/in.h included via net/route.h above.
|
// and netinet/in.h.
|
||||||
#define IPPROTO_L2TP 115
|
#define NF_NAT_RANGE_MAP_IPS (1 << 0)
|
||||||
|
#define NF_NAT_RANGE_PROTO_SPECIFIED (1 << 1)
|
||||||
|
#define NF_NAT_RANGE_PROTO_RANDOM (1 << 2)
|
||||||
|
#define NF_NAT_RANGE_PERSISTENT (1 << 3)
|
||||||
|
#define NF_NAT_RANGE_PROTO_RANDOM_FULLY (1 << 4)
|
||||||
|
#define NF_NAT_RANGE_PROTO_OFFSET (1 << 5)
|
||||||
|
#define NF_NAT_RANGE_NETMAP (1 << 6)
|
||||||
|
#define NF_NAT_RANGE_PROTO_RANDOM_ALL \
|
||||||
|
(NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PROTO_RANDOM_FULLY)
|
||||||
|
#define NF_NAT_RANGE_MASK \
|
||||||
|
(NF_NAT_RANGE_MAP_IPS | NF_NAT_RANGE_PROTO_SPECIFIED | \
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM | NF_NAT_RANGE_PERSISTENT | \
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_FULLY | NF_NAT_RANGE_PROTO_OFFSET | \
|
||||||
|
NF_NAT_RANGE_NETMAP)
|
||||||
|
|
||||||
// Copied from linux/hid.h.
|
// Copied from linux/hid.h.
|
||||||
// Keep in sync with the size of the referenced fields.
|
// Keep in sync with the size of the referenced fields.
|
||||||
|
@ -582,7 +584,7 @@ ccflags="$@"
|
||||||
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
$2 ~ /^KEY_(SPEC|REQKEY_DEFL)_/ ||
|
||||||
$2 ~ /^KEYCTL_/ ||
|
$2 ~ /^KEYCTL_/ ||
|
||||||
$2 ~ /^PERF_/ ||
|
$2 ~ /^PERF_/ ||
|
||||||
$2 ~ /^SECCOMP_MODE_/ ||
|
$2 ~ /^SECCOMP_/ ||
|
||||||
$2 ~ /^SEEK_/ ||
|
$2 ~ /^SEEK_/ ||
|
||||||
$2 ~ /^SCHED_/ ||
|
$2 ~ /^SCHED_/ ||
|
||||||
$2 ~ /^SPLICE_/ ||
|
$2 ~ /^SPLICE_/ ||
|
||||||
|
@ -603,6 +605,9 @@ ccflags="$@"
|
||||||
$2 ~ /^FSOPT_/ ||
|
$2 ~ /^FSOPT_/ ||
|
||||||
$2 ~ /^WDIO[CFS]_/ ||
|
$2 ~ /^WDIO[CFS]_/ ||
|
||||||
$2 ~ /^NFN/ ||
|
$2 ~ /^NFN/ ||
|
||||||
|
$2 !~ /^NFT_META_IIFTYPE/ &&
|
||||||
|
$2 ~ /^NFT_/ ||
|
||||||
|
$2 ~ /^NF_NAT_/ ||
|
||||||
$2 ~ /^XDP_/ ||
|
$2 ~ /^XDP_/ ||
|
||||||
$2 ~ /^RWF_/ ||
|
$2 ~ /^RWF_/ ||
|
||||||
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
$2 ~ /^(HDIO|WIN|SMART)_/ ||
|
||||||
|
|
|
@ -1785,6 +1785,8 @@ const (
|
||||||
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
|
LANDLOCK_ACCESS_FS_REMOVE_FILE = 0x20
|
||||||
LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000
|
LANDLOCK_ACCESS_FS_TRUNCATE = 0x4000
|
||||||
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
|
LANDLOCK_ACCESS_FS_WRITE_FILE = 0x2
|
||||||
|
LANDLOCK_ACCESS_NET_BIND_TCP = 0x1
|
||||||
|
LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2
|
||||||
LANDLOCK_CREATE_RULESET_VERSION = 0x1
|
LANDLOCK_CREATE_RULESET_VERSION = 0x1
|
||||||
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
LINUX_REBOOT_CMD_CAD_OFF = 0x0
|
||||||
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
LINUX_REBOOT_CMD_CAD_ON = 0x89abcdef
|
||||||
|
@ -2127,6 +2129,60 @@ const (
|
||||||
NFNL_SUBSYS_QUEUE = 0x3
|
NFNL_SUBSYS_QUEUE = 0x3
|
||||||
NFNL_SUBSYS_ULOG = 0x4
|
NFNL_SUBSYS_ULOG = 0x4
|
||||||
NFS_SUPER_MAGIC = 0x6969
|
NFS_SUPER_MAGIC = 0x6969
|
||||||
|
NFT_CHAIN_FLAGS = 0x7
|
||||||
|
NFT_CHAIN_MAXNAMELEN = 0x100
|
||||||
|
NFT_CT_MAX = 0x17
|
||||||
|
NFT_DATA_RESERVED_MASK = 0xffffff00
|
||||||
|
NFT_DATA_VALUE_MAXLEN = 0x40
|
||||||
|
NFT_EXTHDR_OP_MAX = 0x4
|
||||||
|
NFT_FIB_RESULT_MAX = 0x3
|
||||||
|
NFT_INNER_MASK = 0xf
|
||||||
|
NFT_LOGLEVEL_MAX = 0x8
|
||||||
|
NFT_NAME_MAXLEN = 0x100
|
||||||
|
NFT_NG_MAX = 0x1
|
||||||
|
NFT_OBJECT_CONNLIMIT = 0x5
|
||||||
|
NFT_OBJECT_COUNTER = 0x1
|
||||||
|
NFT_OBJECT_CT_EXPECT = 0x9
|
||||||
|
NFT_OBJECT_CT_HELPER = 0x3
|
||||||
|
NFT_OBJECT_CT_TIMEOUT = 0x7
|
||||||
|
NFT_OBJECT_LIMIT = 0x4
|
||||||
|
NFT_OBJECT_MAX = 0xa
|
||||||
|
NFT_OBJECT_QUOTA = 0x2
|
||||||
|
NFT_OBJECT_SECMARK = 0x8
|
||||||
|
NFT_OBJECT_SYNPROXY = 0xa
|
||||||
|
NFT_OBJECT_TUNNEL = 0x6
|
||||||
|
NFT_OBJECT_UNSPEC = 0x0
|
||||||
|
NFT_OBJ_MAXNAMELEN = 0x100
|
||||||
|
NFT_OSF_MAXGENRELEN = 0x10
|
||||||
|
NFT_QUEUE_FLAG_BYPASS = 0x1
|
||||||
|
NFT_QUEUE_FLAG_CPU_FANOUT = 0x2
|
||||||
|
NFT_QUEUE_FLAG_MASK = 0x3
|
||||||
|
NFT_REG32_COUNT = 0x10
|
||||||
|
NFT_REG32_SIZE = 0x4
|
||||||
|
NFT_REG_MAX = 0x4
|
||||||
|
NFT_REG_SIZE = 0x10
|
||||||
|
NFT_REJECT_ICMPX_MAX = 0x3
|
||||||
|
NFT_RT_MAX = 0x4
|
||||||
|
NFT_SECMARK_CTX_MAXLEN = 0x100
|
||||||
|
NFT_SET_MAXNAMELEN = 0x100
|
||||||
|
NFT_SOCKET_MAX = 0x3
|
||||||
|
NFT_TABLE_F_MASK = 0x3
|
||||||
|
NFT_TABLE_MAXNAMELEN = 0x100
|
||||||
|
NFT_TRACETYPE_MAX = 0x3
|
||||||
|
NFT_TUNNEL_F_MASK = 0x7
|
||||||
|
NFT_TUNNEL_MAX = 0x1
|
||||||
|
NFT_TUNNEL_MODE_MAX = 0x2
|
||||||
|
NFT_USERDATA_MAXLEN = 0x100
|
||||||
|
NFT_XFRM_KEY_MAX = 0x6
|
||||||
|
NF_NAT_RANGE_MAP_IPS = 0x1
|
||||||
|
NF_NAT_RANGE_MASK = 0x7f
|
||||||
|
NF_NAT_RANGE_NETMAP = 0x40
|
||||||
|
NF_NAT_RANGE_PERSISTENT = 0x8
|
||||||
|
NF_NAT_RANGE_PROTO_OFFSET = 0x20
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM = 0x4
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_ALL = 0x14
|
||||||
|
NF_NAT_RANGE_PROTO_RANDOM_FULLY = 0x10
|
||||||
|
NF_NAT_RANGE_PROTO_SPECIFIED = 0x2
|
||||||
NILFS_SUPER_MAGIC = 0x3434
|
NILFS_SUPER_MAGIC = 0x3434
|
||||||
NL0 = 0x0
|
NL0 = 0x0
|
||||||
NL1 = 0x100
|
NL1 = 0x100
|
||||||
|
@ -2411,6 +2467,7 @@ const (
|
||||||
PR_MCE_KILL_GET = 0x22
|
PR_MCE_KILL_GET = 0x22
|
||||||
PR_MCE_KILL_LATE = 0x0
|
PR_MCE_KILL_LATE = 0x0
|
||||||
PR_MCE_KILL_SET = 0x1
|
PR_MCE_KILL_SET = 0x1
|
||||||
|
PR_MDWE_NO_INHERIT = 0x2
|
||||||
PR_MDWE_REFUSE_EXEC_GAIN = 0x1
|
PR_MDWE_REFUSE_EXEC_GAIN = 0x1
|
||||||
PR_MPX_DISABLE_MANAGEMENT = 0x2c
|
PR_MPX_DISABLE_MANAGEMENT = 0x2c
|
||||||
PR_MPX_ENABLE_MANAGEMENT = 0x2b
|
PR_MPX_ENABLE_MANAGEMENT = 0x2b
|
||||||
|
@ -2615,8 +2672,9 @@ const (
|
||||||
RTAX_FEATURES = 0xc
|
RTAX_FEATURES = 0xc
|
||||||
RTAX_FEATURE_ALLFRAG = 0x8
|
RTAX_FEATURE_ALLFRAG = 0x8
|
||||||
RTAX_FEATURE_ECN = 0x1
|
RTAX_FEATURE_ECN = 0x1
|
||||||
RTAX_FEATURE_MASK = 0xf
|
RTAX_FEATURE_MASK = 0x1f
|
||||||
RTAX_FEATURE_SACK = 0x2
|
RTAX_FEATURE_SACK = 0x2
|
||||||
|
RTAX_FEATURE_TCP_USEC_TS = 0x10
|
||||||
RTAX_FEATURE_TIMESTAMP = 0x4
|
RTAX_FEATURE_TIMESTAMP = 0x4
|
||||||
RTAX_HOPLIMIT = 0xa
|
RTAX_HOPLIMIT = 0xa
|
||||||
RTAX_INITCWND = 0xb
|
RTAX_INITCWND = 0xb
|
||||||
|
@ -2859,9 +2917,38 @@ const (
|
||||||
SCM_RIGHTS = 0x1
|
SCM_RIGHTS = 0x1
|
||||||
SCM_TIMESTAMP = 0x1d
|
SCM_TIMESTAMP = 0x1d
|
||||||
SC_LOG_FLUSH = 0x100000
|
SC_LOG_FLUSH = 0x100000
|
||||||
|
SECCOMP_ADDFD_FLAG_SEND = 0x2
|
||||||
|
SECCOMP_ADDFD_FLAG_SETFD = 0x1
|
||||||
|
SECCOMP_FILTER_FLAG_LOG = 0x2
|
||||||
|
SECCOMP_FILTER_FLAG_NEW_LISTENER = 0x8
|
||||||
|
SECCOMP_FILTER_FLAG_SPEC_ALLOW = 0x4
|
||||||
|
SECCOMP_FILTER_FLAG_TSYNC = 0x1
|
||||||
|
SECCOMP_FILTER_FLAG_TSYNC_ESRCH = 0x10
|
||||||
|
SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV = 0x20
|
||||||
|
SECCOMP_GET_ACTION_AVAIL = 0x2
|
||||||
|
SECCOMP_GET_NOTIF_SIZES = 0x3
|
||||||
|
SECCOMP_IOCTL_NOTIF_RECV = 0xc0502100
|
||||||
|
SECCOMP_IOCTL_NOTIF_SEND = 0xc0182101
|
||||||
|
SECCOMP_IOC_MAGIC = '!'
|
||||||
SECCOMP_MODE_DISABLED = 0x0
|
SECCOMP_MODE_DISABLED = 0x0
|
||||||
SECCOMP_MODE_FILTER = 0x2
|
SECCOMP_MODE_FILTER = 0x2
|
||||||
SECCOMP_MODE_STRICT = 0x1
|
SECCOMP_MODE_STRICT = 0x1
|
||||||
|
SECCOMP_RET_ACTION = 0x7fff0000
|
||||||
|
SECCOMP_RET_ACTION_FULL = 0xffff0000
|
||||||
|
SECCOMP_RET_ALLOW = 0x7fff0000
|
||||||
|
SECCOMP_RET_DATA = 0xffff
|
||||||
|
SECCOMP_RET_ERRNO = 0x50000
|
||||||
|
SECCOMP_RET_KILL = 0x0
|
||||||
|
SECCOMP_RET_KILL_PROCESS = 0x80000000
|
||||||
|
SECCOMP_RET_KILL_THREAD = 0x0
|
||||||
|
SECCOMP_RET_LOG = 0x7ffc0000
|
||||||
|
SECCOMP_RET_TRACE = 0x7ff00000
|
||||||
|
SECCOMP_RET_TRAP = 0x30000
|
||||||
|
SECCOMP_RET_USER_NOTIF = 0x7fc00000
|
||||||
|
SECCOMP_SET_MODE_FILTER = 0x1
|
||||||
|
SECCOMP_SET_MODE_STRICT = 0x0
|
||||||
|
SECCOMP_USER_NOTIF_FD_SYNC_WAKE_UP = 0x1
|
||||||
|
SECCOMP_USER_NOTIF_FLAG_CONTINUE = 0x1
|
||||||
SECRETMEM_MAGIC = 0x5345434d
|
SECRETMEM_MAGIC = 0x5345434d
|
||||||
SECURITYFS_MAGIC = 0x73636673
|
SECURITYFS_MAGIC = 0x73636673
|
||||||
SEEK_CUR = 0x1
|
SEEK_CUR = 0x1
|
||||||
|
@ -3021,6 +3108,7 @@ const (
|
||||||
SOL_TIPC = 0x10f
|
SOL_TIPC = 0x10f
|
||||||
SOL_TLS = 0x11a
|
SOL_TLS = 0x11a
|
||||||
SOL_UDP = 0x11
|
SOL_UDP = 0x11
|
||||||
|
SOL_VSOCK = 0x11f
|
||||||
SOL_X25 = 0x106
|
SOL_X25 = 0x106
|
||||||
SOL_XDP = 0x11b
|
SOL_XDP = 0x11b
|
||||||
SOMAXCONN = 0x1000
|
SOMAXCONN = 0x1000
|
||||||
|
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -282,6 +282,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -288,6 +288,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -278,6 +278,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -275,6 +275,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
@ -281,6 +281,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x80
|
SFD_NONBLOCK = 0x80
|
||||||
SIOCATMARK = 0x40047307
|
SIOCATMARK = 0x40047307
|
||||||
|
|
|
@ -336,6 +336,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -340,6 +340,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -340,6 +340,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -272,6 +272,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -344,6 +344,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x23
|
SCM_TIMESTAMPNS = 0x23
|
||||||
SCM_TXTIME = 0x3d
|
SCM_TXTIME = 0x3d
|
||||||
SCM_WIFI_STATUS = 0x29
|
SCM_WIFI_STATUS = 0x29
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x40082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x40082104
|
||||||
SFD_CLOEXEC = 0x80000
|
SFD_CLOEXEC = 0x80000
|
||||||
SFD_NONBLOCK = 0x800
|
SFD_NONBLOCK = 0x800
|
||||||
SIOCATMARK = 0x8905
|
SIOCATMARK = 0x8905
|
||||||
|
|
|
@ -335,6 +335,9 @@ const (
|
||||||
SCM_TIMESTAMPNS = 0x21
|
SCM_TIMESTAMPNS = 0x21
|
||||||
SCM_TXTIME = 0x3f
|
SCM_TXTIME = 0x3f
|
||||||
SCM_WIFI_STATUS = 0x25
|
SCM_WIFI_STATUS = 0x25
|
||||||
|
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103
|
||||||
|
SECCOMP_IOCTL_NOTIF_ID_VALID = 0x80082102
|
||||||
|
SECCOMP_IOCTL_NOTIF_SET_FLAGS = 0x80082104
|
||||||
SFD_CLOEXEC = 0x400000
|
SFD_CLOEXEC = 0x400000
|
||||||
SFD_NONBLOCK = 0x4000
|
SFD_NONBLOCK = 0x4000
|
||||||
SF_FP = 0x38
|
SF_FP = 0x38
|
||||||
|
|
|
@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
|
||||||
var libc_unveil_trampoline_addr uintptr
|
var libc_unveil_trampoline_addr uintptr
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
|
||||||
var libc_unveil_trampoline_addr uintptr
|
var libc_unveil_trampoline_addr uintptr
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
|
||||||
var libc_unveil_trampoline_addr uintptr
|
var libc_unveil_trampoline_addr uintptr
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
|
||||||
var libc_unveil_trampoline_addr uintptr
|
var libc_unveil_trampoline_addr uintptr
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
|
||||||
var libc_unveil_trampoline_addr uintptr
|
var libc_unveil_trampoline_addr uintptr
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
|
||||||
var libc_unveil_trampoline_addr uintptr
|
var libc_unveil_trampoline_addr uintptr
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2297,5 +2297,3 @@ func unveil(path *byte, flags *byte) (err error) {
|
||||||
var libc_unveil_trampoline_addr uintptr
|
var libc_unveil_trampoline_addr uintptr
|
||||||
|
|
||||||
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
//go:cgo_import_dynamic libc_unveil unveil "libc.so"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -448,4 +448,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -371,4 +371,7 @@ const (
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
SYS_MAP_SHADOW_STACK = 453
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -412,4 +412,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -315,4 +315,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -309,4 +309,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -432,4 +432,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 4450
|
SYS_SET_MEMPOLICY_HOME_NODE = 4450
|
||||||
SYS_CACHESTAT = 4451
|
SYS_CACHESTAT = 4451
|
||||||
SYS_FCHMODAT2 = 4452
|
SYS_FCHMODAT2 = 4452
|
||||||
|
SYS_MAP_SHADOW_STACK = 4453
|
||||||
|
SYS_FUTEX_WAKE = 4454
|
||||||
|
SYS_FUTEX_WAIT = 4455
|
||||||
|
SYS_FUTEX_REQUEUE = 4456
|
||||||
)
|
)
|
||||||
|
|
|
@ -362,4 +362,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 5450
|
SYS_SET_MEMPOLICY_HOME_NODE = 5450
|
||||||
SYS_CACHESTAT = 5451
|
SYS_CACHESTAT = 5451
|
||||||
SYS_FCHMODAT2 = 5452
|
SYS_FCHMODAT2 = 5452
|
||||||
|
SYS_MAP_SHADOW_STACK = 5453
|
||||||
|
SYS_FUTEX_WAKE = 5454
|
||||||
|
SYS_FUTEX_WAIT = 5455
|
||||||
|
SYS_FUTEX_REQUEUE = 5456
|
||||||
)
|
)
|
||||||
|
|
|
@ -362,4 +362,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 5450
|
SYS_SET_MEMPOLICY_HOME_NODE = 5450
|
||||||
SYS_CACHESTAT = 5451
|
SYS_CACHESTAT = 5451
|
||||||
SYS_FCHMODAT2 = 5452
|
SYS_FCHMODAT2 = 5452
|
||||||
|
SYS_MAP_SHADOW_STACK = 5453
|
||||||
|
SYS_FUTEX_WAKE = 5454
|
||||||
|
SYS_FUTEX_WAIT = 5455
|
||||||
|
SYS_FUTEX_REQUEUE = 5456
|
||||||
)
|
)
|
||||||
|
|
|
@ -432,4 +432,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 4450
|
SYS_SET_MEMPOLICY_HOME_NODE = 4450
|
||||||
SYS_CACHESTAT = 4451
|
SYS_CACHESTAT = 4451
|
||||||
SYS_FCHMODAT2 = 4452
|
SYS_FCHMODAT2 = 4452
|
||||||
|
SYS_MAP_SHADOW_STACK = 4453
|
||||||
|
SYS_FUTEX_WAKE = 4454
|
||||||
|
SYS_FUTEX_WAIT = 4455
|
||||||
|
SYS_FUTEX_REQUEUE = 4456
|
||||||
)
|
)
|
||||||
|
|
|
@ -439,4 +439,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -411,4 +411,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -411,4 +411,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -316,4 +316,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -377,4 +377,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -390,4 +390,8 @@ const (
|
||||||
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
SYS_SET_MEMPOLICY_HOME_NODE = 450
|
||||||
SYS_CACHESTAT = 451
|
SYS_CACHESTAT = 451
|
||||||
SYS_FCHMODAT2 = 452
|
SYS_FCHMODAT2 = 452
|
||||||
|
SYS_MAP_SHADOW_STACK = 453
|
||||||
|
SYS_FUTEX_WAKE = 454
|
||||||
|
SYS_FUTEX_WAIT = 455
|
||||||
|
SYS_FUTEX_REQUEUE = 456
|
||||||
)
|
)
|
||||||
|
|
|
@ -174,7 +174,8 @@ type FscryptPolicyV2 struct {
|
||||||
Contents_encryption_mode uint8
|
Contents_encryption_mode uint8
|
||||||
Filenames_encryption_mode uint8
|
Filenames_encryption_mode uint8
|
||||||
Flags uint8
|
Flags uint8
|
||||||
_ [4]uint8
|
Log2_data_unit_size uint8
|
||||||
|
_ [3]uint8
|
||||||
Master_key_identifier [16]uint8
|
Master_key_identifier [16]uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,6 +510,9 @@ type TCPInfo struct {
|
||||||
Snd_wnd uint32
|
Snd_wnd uint32
|
||||||
Rcv_wnd uint32
|
Rcv_wnd uint32
|
||||||
Rehash uint32
|
Rehash uint32
|
||||||
|
Total_rto uint16
|
||||||
|
Total_rto_recoveries uint16
|
||||||
|
Total_rto_time uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type CanFilter struct {
|
type CanFilter struct {
|
||||||
|
@ -551,7 +555,7 @@ const (
|
||||||
SizeofIPv6MTUInfo = 0x20
|
SizeofIPv6MTUInfo = 0x20
|
||||||
SizeofICMPv6Filter = 0x20
|
SizeofICMPv6Filter = 0x20
|
||||||
SizeofUcred = 0xc
|
SizeofUcred = 0xc
|
||||||
SizeofTCPInfo = 0xf0
|
SizeofTCPInfo = 0xf8
|
||||||
SizeofCanFilter = 0x8
|
SizeofCanFilter = 0x8
|
||||||
SizeofTCPRepairOpt = 0x8
|
SizeofTCPRepairOpt = 0x8
|
||||||
)
|
)
|
||||||
|
@ -3399,7 +3403,7 @@ const (
|
||||||
DEVLINK_PORT_FN_ATTR_STATE = 0x2
|
DEVLINK_PORT_FN_ATTR_STATE = 0x2
|
||||||
DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3
|
DEVLINK_PORT_FN_ATTR_OPSTATE = 0x3
|
||||||
DEVLINK_PORT_FN_ATTR_CAPS = 0x4
|
DEVLINK_PORT_FN_ATTR_CAPS = 0x4
|
||||||
DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x4
|
DEVLINK_PORT_FUNCTION_ATTR_MAX = 0x5
|
||||||
)
|
)
|
||||||
|
|
||||||
type FsverityDigest struct {
|
type FsverityDigest struct {
|
||||||
|
@ -4184,6 +4188,7 @@ const (
|
||||||
|
|
||||||
type LandlockRulesetAttr struct {
|
type LandlockRulesetAttr struct {
|
||||||
Access_fs uint64
|
Access_fs uint64
|
||||||
|
Access_net uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
type LandlockPathBeneathAttr struct {
|
type LandlockPathBeneathAttr struct {
|
||||||
|
@ -5134,7 +5139,7 @@ const (
|
||||||
NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf
|
NL80211_FREQUENCY_ATTR_GO_CONCURRENT = 0xf
|
||||||
NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe
|
NL80211_FREQUENCY_ATTR_INDOOR_ONLY = 0xe
|
||||||
NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf
|
NL80211_FREQUENCY_ATTR_IR_CONCURRENT = 0xf
|
||||||
NL80211_FREQUENCY_ATTR_MAX = 0x1b
|
NL80211_FREQUENCY_ATTR_MAX = 0x1c
|
||||||
NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6
|
NL80211_FREQUENCY_ATTR_MAX_TX_POWER = 0x6
|
||||||
NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11
|
NL80211_FREQUENCY_ATTR_NO_10MHZ = 0x11
|
||||||
NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc
|
NL80211_FREQUENCY_ATTR_NO_160MHZ = 0xc
|
||||||
|
@ -5547,7 +5552,7 @@ const (
|
||||||
NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2
|
NL80211_REGDOM_TYPE_CUSTOM_WORLD = 0x2
|
||||||
NL80211_REGDOM_TYPE_INTERSECTION = 0x3
|
NL80211_REGDOM_TYPE_INTERSECTION = 0x3
|
||||||
NL80211_REGDOM_TYPE_WORLD = 0x1
|
NL80211_REGDOM_TYPE_WORLD = 0x1
|
||||||
NL80211_REG_RULE_ATTR_MAX = 0x7
|
NL80211_REG_RULE_ATTR_MAX = 0x8
|
||||||
NL80211_REKEY_DATA_AKM = 0x4
|
NL80211_REKEY_DATA_AKM = 0x4
|
||||||
NL80211_REKEY_DATA_KCK = 0x2
|
NL80211_REKEY_DATA_KCK = 0x2
|
||||||
NL80211_REKEY_DATA_KEK = 0x1
|
NL80211_REKEY_DATA_KEK = 0x1
|
||||||
|
|
|
@ -37,14 +37,17 @@ func (token Token) Environ(inheritExisting bool) (env []string, err error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer DestroyEnvironmentBlock(block)
|
defer DestroyEnvironmentBlock(block)
|
||||||
blockp := unsafe.Pointer(block)
|
size := unsafe.Sizeof(*block)
|
||||||
for {
|
for *block != 0 {
|
||||||
entry := UTF16PtrToString((*uint16)(blockp))
|
// find NUL terminator
|
||||||
if len(entry) == 0 {
|
end := unsafe.Pointer(block)
|
||||||
break
|
for *(*uint16)(end) != 0 {
|
||||||
|
end = unsafe.Add(end, size)
|
||||||
}
|
}
|
||||||
env = append(env, entry)
|
|
||||||
blockp = unsafe.Add(blockp, 2*(len(entry)+1))
|
entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size)
|
||||||
|
env = append(env, UTF16ToString(entry))
|
||||||
|
block = (*uint16)(unsafe.Add(end, size))
|
||||||
}
|
}
|
||||||
return env, nil
|
return env, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,8 +125,7 @@ func UTF16PtrToString(p *uint16) string {
|
||||||
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
|
for ptr := unsafe.Pointer(p); *(*uint16)(ptr) != 0; n++ {
|
||||||
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
|
ptr = unsafe.Pointer(uintptr(ptr) + unsafe.Sizeof(*p))
|
||||||
}
|
}
|
||||||
|
return UTF16ToString(unsafe.Slice(p, n))
|
||||||
return string(utf16.Decode(unsafe.Slice(p, n)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Getpagesize() int { return 4096 }
|
func Getpagesize() int { return 4096 }
|
||||||
|
@ -194,6 +193,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
||||||
//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
|
//sys GetComputerName(buf *uint16, n *uint32) (err error) = GetComputerNameW
|
||||||
//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
|
//sys GetComputerNameEx(nametype uint32, buf *uint16, n *uint32) (err error) = GetComputerNameExW
|
||||||
//sys SetEndOfFile(handle Handle) (err error)
|
//sys SetEndOfFile(handle Handle) (err error)
|
||||||
|
//sys SetFileValidData(handle Handle, validDataLength int64) (err error)
|
||||||
//sys GetSystemTimeAsFileTime(time *Filetime)
|
//sys GetSystemTimeAsFileTime(time *Filetime)
|
||||||
//sys GetSystemTimePreciseAsFileTime(time *Filetime)
|
//sys GetSystemTimePreciseAsFileTime(time *Filetime)
|
||||||
//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
|
//sys GetTimeZoneInformation(tzi *Timezoneinformation) (rc uint32, err error) [failretval==0xffffffff]
|
||||||
|
|
|
@ -342,6 +342,7 @@ var (
|
||||||
procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories")
|
procSetDefaultDllDirectories = modkernel32.NewProc("SetDefaultDllDirectories")
|
||||||
procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW")
|
procSetDllDirectoryW = modkernel32.NewProc("SetDllDirectoryW")
|
||||||
procSetEndOfFile = modkernel32.NewProc("SetEndOfFile")
|
procSetEndOfFile = modkernel32.NewProc("SetEndOfFile")
|
||||||
|
procSetFileValidData = modkernel32.NewProc("SetFileValidData")
|
||||||
procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW")
|
procSetEnvironmentVariableW = modkernel32.NewProc("SetEnvironmentVariableW")
|
||||||
procSetErrorMode = modkernel32.NewProc("SetErrorMode")
|
procSetErrorMode = modkernel32.NewProc("SetErrorMode")
|
||||||
procSetEvent = modkernel32.NewProc("SetEvent")
|
procSetEvent = modkernel32.NewProc("SetEvent")
|
||||||
|
@ -2988,6 +2989,14 @@ func SetEndOfFile(handle Handle) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetFileValidData(handle Handle, validDataLength int64) (err error) {
|
||||||
|
r1, _, e1 := syscall.Syscall(procSetFileValidData.Addr(), 2, uintptr(handle), uintptr(validDataLength), 0)
|
||||||
|
if r1 == 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
|
func SetEnvironmentVariable(name *uint16, value *uint16) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
|
r1, _, e1 := syscall.Syscall(procSetEnvironmentVariableW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
|
|
|
@ -9,11 +9,13 @@ package gopathwalk
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,8 +23,13 @@ import (
|
||||||
type Options struct {
|
type Options struct {
|
||||||
// If Logf is non-nil, debug logging is enabled through this function.
|
// If Logf is non-nil, debug logging is enabled through this function.
|
||||||
Logf func(format string, args ...interface{})
|
Logf func(format string, args ...interface{})
|
||||||
|
|
||||||
// Search module caches. Also disables legacy goimports ignore rules.
|
// Search module caches. Also disables legacy goimports ignore rules.
|
||||||
ModulesEnabled bool
|
ModulesEnabled bool
|
||||||
|
|
||||||
|
// Maximum number of concurrent calls to user-provided callbacks,
|
||||||
|
// or 0 for GOMAXPROCS.
|
||||||
|
Concurrency int
|
||||||
}
|
}
|
||||||
|
|
||||||
// RootType indicates the type of a Root.
|
// RootType indicates the type of a Root.
|
||||||
|
@ -43,19 +50,28 @@ type Root struct {
|
||||||
Type RootType
|
Type RootType
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk walks Go source directories ($GOROOT, $GOPATH, etc) to find packages.
|
// Walk concurrently walks Go source directories ($GOROOT, $GOPATH, etc) to find packages.
|
||||||
|
//
|
||||||
// For each package found, add will be called with the absolute
|
// For each package found, add will be called with the absolute
|
||||||
// paths of the containing source directory and the package directory.
|
// paths of the containing source directory and the package directory.
|
||||||
|
//
|
||||||
|
// Unlike filepath.WalkDir, Walk follows symbolic links
|
||||||
|
// (while guarding against cycles).
|
||||||
func Walk(roots []Root, add func(root Root, dir string), opts Options) {
|
func Walk(roots []Root, add func(root Root, dir string), opts Options) {
|
||||||
WalkSkip(roots, add, func(Root, string) bool { return false }, opts)
|
WalkSkip(roots, add, func(Root, string) bool { return false }, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WalkSkip walks Go source directories ($GOROOT, $GOPATH, etc) to find packages.
|
// WalkSkip concurrently walks Go source directories ($GOROOT, $GOPATH, etc) to
|
||||||
|
// find packages.
|
||||||
|
//
|
||||||
// For each package found, add will be called with the absolute
|
// For each package found, add will be called with the absolute
|
||||||
// paths of the containing source directory and the package directory.
|
// paths of the containing source directory and the package directory.
|
||||||
// For each directory that will be scanned, skip will be called
|
// For each directory that will be scanned, skip will be called
|
||||||
// with the absolute paths of the containing source directory and the directory.
|
// with the absolute paths of the containing source directory and the directory.
|
||||||
// If skip returns false on a directory it will be processed.
|
// If skip returns false on a directory it will be processed.
|
||||||
|
//
|
||||||
|
// Unlike filepath.WalkDir, WalkSkip follows symbolic links
|
||||||
|
// (while guarding against cycles).
|
||||||
func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root, dir string) bool, opts Options) {
|
func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root, dir string) bool, opts Options) {
|
||||||
for _, root := range roots {
|
for _, root := range roots {
|
||||||
walkDir(root, add, skip, opts)
|
walkDir(root, add, skip, opts)
|
||||||
|
@ -64,46 +80,52 @@ func WalkSkip(roots []Root, add func(root Root, dir string), skip func(root Root
|
||||||
|
|
||||||
// walkDir creates a walker and starts fastwalk with this walker.
|
// walkDir creates a walker and starts fastwalk with this walker.
|
||||||
func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) {
|
func walkDir(root Root, add func(Root, string), skip func(root Root, dir string) bool, opts Options) {
|
||||||
if _, err := os.Stat(root.Path); os.IsNotExist(err) {
|
if opts.Logf == nil {
|
||||||
if opts.Logf != nil {
|
opts.Logf = func(format string, args ...interface{}) {}
|
||||||
opts.Logf("skipping nonexistent directory: %v", root.Path)
|
|
||||||
}
|
}
|
||||||
|
if _, err := os.Stat(root.Path); os.IsNotExist(err) {
|
||||||
|
opts.Logf("skipping nonexistent directory: %v", root.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
if opts.Logf != nil {
|
|
||||||
opts.Logf("scanning %s", root.Path)
|
opts.Logf("scanning %s", root.Path)
|
||||||
}
|
|
||||||
|
|
||||||
|
concurrency := opts.Concurrency
|
||||||
|
if concurrency == 0 {
|
||||||
|
// The walk be either CPU-bound or I/O-bound, depending on what the
|
||||||
|
// caller-supplied add function does and the details of the user's platform
|
||||||
|
// and machine. Rather than trying to fine-tune the concurrency level for a
|
||||||
|
// specific environment, we default to GOMAXPROCS: it is likely to be a good
|
||||||
|
// choice for a CPU-bound add function, and if it is instead I/O-bound, then
|
||||||
|
// dealing with I/O saturation is arguably the job of the kernel and/or
|
||||||
|
// runtime. (Oversaturating I/O seems unlikely to harm performance as badly
|
||||||
|
// as failing to saturate would.)
|
||||||
|
concurrency = runtime.GOMAXPROCS(0)
|
||||||
|
}
|
||||||
w := &walker{
|
w := &walker{
|
||||||
root: root,
|
root: root,
|
||||||
add: add,
|
add: add,
|
||||||
skip: skip,
|
skip: skip,
|
||||||
opts: opts,
|
opts: opts,
|
||||||
added: make(map[string]bool),
|
sem: make(chan struct{}, concurrency),
|
||||||
}
|
}
|
||||||
w.init()
|
w.init()
|
||||||
|
|
||||||
// Add a trailing path separator to cause filepath.WalkDir to traverse symlinks.
|
w.sem <- struct{}{}
|
||||||
path := root.Path
|
path := root.Path
|
||||||
if len(path) == 0 {
|
if path == "" {
|
||||||
path = "." + string(filepath.Separator)
|
path = "."
|
||||||
} else if !os.IsPathSeparator(path[len(path)-1]) {
|
|
||||||
path = path + string(filepath.Separator)
|
|
||||||
}
|
}
|
||||||
|
if fi, err := os.Lstat(path); err == nil {
|
||||||
|
w.walk(path, nil, fs.FileInfoToDirEntry(fi))
|
||||||
|
} else {
|
||||||
|
w.opts.Logf("scanning directory %v: %v", root.Path, err)
|
||||||
|
}
|
||||||
|
<-w.sem
|
||||||
|
w.walking.Wait()
|
||||||
|
|
||||||
if err := filepath.WalkDir(path, w.walk); err != nil {
|
|
||||||
logf := opts.Logf
|
|
||||||
if logf == nil {
|
|
||||||
logf = log.Printf
|
|
||||||
}
|
|
||||||
logf("scanning directory %v: %v", root.Path, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Logf != nil {
|
|
||||||
opts.Logf("scanned %s in %v", root.Path, time.Since(start))
|
opts.Logf("scanned %s in %v", root.Path, time.Since(start))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// walker is the callback for fastwalk.Walk.
|
// walker is the callback for fastwalk.Walk.
|
||||||
type walker struct {
|
type walker struct {
|
||||||
|
@ -112,10 +134,18 @@ type walker struct {
|
||||||
skip func(Root, string) bool // The callback that will be invoked for every dir. dir is skipped if it returns true.
|
skip func(Root, string) bool // The callback that will be invoked for every dir. dir is skipped if it returns true.
|
||||||
opts Options // Options passed to Walk by the user.
|
opts Options // Options passed to Walk by the user.
|
||||||
|
|
||||||
pathSymlinks []os.FileInfo
|
walking sync.WaitGroup
|
||||||
|
sem chan struct{} // Channel of semaphore tokens; send to acquire, receive to release.
|
||||||
ignoredDirs []string
|
ignoredDirs []string
|
||||||
|
|
||||||
added map[string]bool
|
added sync.Map // map[string]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// A symlinkList is a linked list of os.FileInfos for parent directories
|
||||||
|
// reached via symlinks.
|
||||||
|
type symlinkList struct {
|
||||||
|
info os.FileInfo
|
||||||
|
prev *symlinkList
|
||||||
}
|
}
|
||||||
|
|
||||||
// init initializes the walker based on its Options
|
// init initializes the walker based on its Options
|
||||||
|
@ -132,11 +162,9 @@ func (w *walker) init() {
|
||||||
for _, p := range ignoredPaths {
|
for _, p := range ignoredPaths {
|
||||||
full := filepath.Join(w.root.Path, p)
|
full := filepath.Join(w.root.Path, p)
|
||||||
w.ignoredDirs = append(w.ignoredDirs, full)
|
w.ignoredDirs = append(w.ignoredDirs, full)
|
||||||
if w.opts.Logf != nil {
|
|
||||||
w.opts.Logf("Directory added to ignore list: %s", full)
|
w.opts.Logf("Directory added to ignore list: %s", full)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// getIgnoredDirs reads an optional config file at <path>/.goimportsignore
|
// getIgnoredDirs reads an optional config file at <path>/.goimportsignore
|
||||||
// of relative directories to ignore when scanning for go files.
|
// of relative directories to ignore when scanning for go files.
|
||||||
|
@ -144,13 +172,11 @@ func (w *walker) init() {
|
||||||
func (w *walker) getIgnoredDirs(path string) []string {
|
func (w *walker) getIgnoredDirs(path string) []string {
|
||||||
file := filepath.Join(path, ".goimportsignore")
|
file := filepath.Join(path, ".goimportsignore")
|
||||||
slurp, err := os.ReadFile(file)
|
slurp, err := os.ReadFile(file)
|
||||||
if w.opts.Logf != nil {
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.opts.Logf("%v", err)
|
w.opts.Logf("%v", err)
|
||||||
} else {
|
} else {
|
||||||
w.opts.Logf("Read %s", file)
|
w.opts.Logf("Read %s", file)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -183,63 +209,22 @@ func (w *walker) shouldSkipDir(dir string) bool {
|
||||||
|
|
||||||
// walk walks through the given path.
|
// walk walks through the given path.
|
||||||
//
|
//
|
||||||
// Errors are logged if w.opts.Logf is non-nil, but otherwise ignored:
|
// Errors are logged if w.opts.Logf is non-nil, but otherwise ignored.
|
||||||
// walk returns only nil or fs.SkipDir.
|
func (w *walker) walk(path string, pathSymlinks *symlinkList, d fs.DirEntry) {
|
||||||
func (w *walker) walk(path string, d fs.DirEntry, err error) error {
|
|
||||||
if err != nil {
|
|
||||||
// We have no way to report errors back through Walk or WalkSkip,
|
|
||||||
// so just log and ignore them.
|
|
||||||
if w.opts.Logf != nil {
|
|
||||||
w.opts.Logf("%v", err)
|
|
||||||
}
|
|
||||||
if d == nil {
|
|
||||||
// Nothing more to do: the error prevents us from knowing
|
|
||||||
// what path even represents.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.Type().IsRegular() {
|
|
||||||
if !strings.HasSuffix(path, ".go") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
dir := filepath.Dir(path)
|
|
||||||
if dir == w.root.Path && (w.root.Type == RootGOROOT || w.root.Type == RootGOPATH) {
|
|
||||||
// Doesn't make sense to have regular files
|
|
||||||
// directly in your $GOPATH/src or $GOROOT/src.
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if !w.added[dir] {
|
|
||||||
w.add(w.root, dir)
|
|
||||||
w.added[dir] = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.IsDir() {
|
|
||||||
base := filepath.Base(path)
|
|
||||||
if base == "" || base[0] == '.' || base[0] == '_' ||
|
|
||||||
base == "testdata" ||
|
|
||||||
(w.root.Type == RootGOROOT && w.opts.ModulesEnabled && base == "vendor") ||
|
|
||||||
(!w.opts.ModulesEnabled && base == "node_modules") {
|
|
||||||
return fs.SkipDir
|
|
||||||
}
|
|
||||||
if w.shouldSkipDir(path) {
|
|
||||||
return fs.SkipDir
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.Type()&os.ModeSymlink != 0 {
|
if d.Type()&os.ModeSymlink != 0 {
|
||||||
|
// Walk the symlink's target rather than the symlink itself.
|
||||||
|
//
|
||||||
|
// (Note that os.Stat, unlike the lower-lever os.Readlink,
|
||||||
|
// follows arbitrarily many layers of symlinks, so it will eventually
|
||||||
|
// reach either a non-symlink or a nonexistent target.)
|
||||||
|
//
|
||||||
// TODO(bcmills): 'go list all' itself ignores symlinks within GOROOT/src
|
// TODO(bcmills): 'go list all' itself ignores symlinks within GOROOT/src
|
||||||
// and GOPATH/src. Do we really need to traverse them here? If so, why?
|
// and GOPATH/src. Do we really need to traverse them here? If so, why?
|
||||||
|
|
||||||
fi, err := os.Stat(path)
|
fi, err := os.Stat(path)
|
||||||
if err != nil || !fi.IsDir() {
|
if err != nil {
|
||||||
// Not a directory. Just walk the file (or broken link) and be done.
|
w.opts.Logf("%v", err)
|
||||||
return w.walk(path, fs.FileInfoToDirEntry(fi), err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid walking symlink cycles: if we have already followed a symlink to
|
// Avoid walking symlink cycles: if we have already followed a symlink to
|
||||||
|
@ -249,83 +234,104 @@ func (w *walker) walk(path string, d fs.DirEntry, err error) error {
|
||||||
// the number of extra stat calls we make if we *don't* encounter a cycle.
|
// the number of extra stat calls we make if we *don't* encounter a cycle.
|
||||||
// Since we don't actually expect to encounter symlink cycles in practice,
|
// Since we don't actually expect to encounter symlink cycles in practice,
|
||||||
// this seems like the right tradeoff.
|
// this seems like the right tradeoff.
|
||||||
for _, parent := range w.pathSymlinks {
|
for parent := pathSymlinks; parent != nil; parent = parent.prev {
|
||||||
if os.SameFile(fi, parent) {
|
if os.SameFile(fi, parent.info) {
|
||||||
return nil
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.pathSymlinks = append(w.pathSymlinks, fi)
|
pathSymlinks = &symlinkList{
|
||||||
defer func() {
|
info: fi,
|
||||||
w.pathSymlinks = w.pathSymlinks[:len(w.pathSymlinks)-1]
|
prev: pathSymlinks,
|
||||||
}()
|
}
|
||||||
|
d = fs.FileInfoToDirEntry(fi)
|
||||||
// On some platforms the OS (or the Go os package) sometimes fails to
|
|
||||||
// resolve directory symlinks before a trailing slash
|
|
||||||
// (even though POSIX requires it to do so).
|
|
||||||
//
|
|
||||||
// On macOS that failure may be caused by a known libc/kernel bug;
|
|
||||||
// see https://go.dev/issue/59586.
|
|
||||||
//
|
|
||||||
// On Windows before Go 1.21, it may be caused by a bug in
|
|
||||||
// os.Lstat (fixed in https://go.dev/cl/463177).
|
|
||||||
//
|
|
||||||
// Since we need to handle this explicitly on broken platforms anyway,
|
|
||||||
// it is simplest to just always do that and not rely on POSIX pathname
|
|
||||||
// resolution to walk the directory (such as by calling WalkDir with
|
|
||||||
// a trailing slash appended to the path).
|
|
||||||
//
|
|
||||||
// Instead, we make a sequence of walk calls — directly and through
|
|
||||||
// recursive calls to filepath.WalkDir — simulating what WalkDir would do
|
|
||||||
// if the symlink were a regular directory.
|
|
||||||
|
|
||||||
// First we call walk on the path as a directory
|
|
||||||
// (instead of a symlink).
|
|
||||||
err = w.walk(path, fs.FileInfoToDirEntry(fi), nil)
|
|
||||||
if err == fs.SkipDir {
|
|
||||||
return nil
|
|
||||||
} else if err != nil {
|
|
||||||
// This should be impossible, but handle it anyway in case
|
|
||||||
// walk is changed to return other errors.
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now read the directory and walk its entries.
|
if d.Type().IsRegular() {
|
||||||
ents, err := os.ReadDir(path)
|
if !strings.HasSuffix(path, ".go") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := filepath.Dir(path)
|
||||||
|
if dir == w.root.Path && (w.root.Type == RootGOROOT || w.root.Type == RootGOPATH) {
|
||||||
|
// Doesn't make sense to have regular files
|
||||||
|
// directly in your $GOPATH/src or $GOROOT/src.
|
||||||
|
//
|
||||||
|
// TODO(bcmills): there are many levels of directory within
|
||||||
|
// RootModuleCache where this also wouldn't make sense,
|
||||||
|
// Can we generalize this to any directory without a corresponding
|
||||||
|
// import path?
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, dup := w.added.LoadOrStore(dir, true); !dup {
|
||||||
|
w.add(w.root, dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !d.IsDir() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
base := filepath.Base(path)
|
||||||
|
if base == "" || base[0] == '.' || base[0] == '_' ||
|
||||||
|
base == "testdata" ||
|
||||||
|
(w.root.Type == RootGOROOT && w.opts.ModulesEnabled && base == "vendor") ||
|
||||||
|
(!w.opts.ModulesEnabled && base == "node_modules") ||
|
||||||
|
w.shouldSkipDir(path) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the directory and walk its entries.
|
||||||
|
|
||||||
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Report the ReadDir error, as filepath.WalkDir would do.
|
w.opts.Logf("%v", err)
|
||||||
err = w.walk(path, fs.FileInfoToDirEntry(fi), err)
|
return
|
||||||
if err == fs.SkipDir {
|
|
||||||
return nil
|
|
||||||
} else if err != nil {
|
|
||||||
return err // Again, should be impossible.
|
|
||||||
}
|
}
|
||||||
// Fall through and iterate over whatever entries we did manage to get.
|
defer f.Close()
|
||||||
|
|
||||||
|
for {
|
||||||
|
// We impose an arbitrary limit on the number of ReadDir results per
|
||||||
|
// directory to limit the amount of memory consumed for stale or upcoming
|
||||||
|
// directory entries. The limit trades off CPU (number of syscalls to read
|
||||||
|
// the whole directory) against RAM (reachable directory entries other than
|
||||||
|
// the one currently being processed).
|
||||||
|
//
|
||||||
|
// Since we process the directories recursively, we will end up maintaining
|
||||||
|
// a slice of entries for each level of the directory tree.
|
||||||
|
// (Compare https://go.dev/issue/36197.)
|
||||||
|
ents, err := f.ReadDir(1024)
|
||||||
|
if err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
w.opts.Logf("%v", err)
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, d := range ents {
|
for _, d := range ents {
|
||||||
nextPath := filepath.Join(path, d.Name())
|
nextPath := filepath.Join(path, d.Name())
|
||||||
if d.IsDir() {
|
if d.IsDir() {
|
||||||
// We want to walk the whole directory tree rooted at nextPath,
|
select {
|
||||||
// not just the single entry for the directory.
|
case w.sem <- struct{}{}:
|
||||||
err := filepath.WalkDir(nextPath, w.walk)
|
// Got a new semaphore token, so we can traverse the directory concurrently.
|
||||||
if err != nil && w.opts.Logf != nil {
|
d := d
|
||||||
w.opts.Logf("%v", err)
|
w.walking.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer func() {
|
||||||
|
<-w.sem
|
||||||
|
w.walking.Done()
|
||||||
|
}()
|
||||||
|
w.walk(nextPath, pathSymlinks, d)
|
||||||
|
}()
|
||||||
|
continue
|
||||||
|
|
||||||
|
default:
|
||||||
|
// No tokens available, so traverse serially.
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
err := w.walk(nextPath, d, nil)
|
|
||||||
if err == fs.SkipDir {
|
|
||||||
// Skip the rest of the entries in the parent directory of nextPath
|
|
||||||
// (that is, path itself).
|
|
||||||
break
|
|
||||||
} else if err != nil {
|
|
||||||
return err // Again, should be impossible.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not a file, regular directory, or symlink; skip.
|
w.walk(nextPath, pathSymlinks, d)
|
||||||
return nil
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"go/build"
|
"go/build"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"go/types"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -700,20 +701,21 @@ func ScoreImportPaths(ctx context.Context, env *ProcessEnv, paths []string) (map
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func PrimeCache(ctx context.Context, env *ProcessEnv) error {
|
func PrimeCache(ctx context.Context, resolver Resolver) error {
|
||||||
// Fully scan the disk for directories, but don't actually read any Go files.
|
// Fully scan the disk for directories, but don't actually read any Go files.
|
||||||
callback := &scanCallback{
|
callback := &scanCallback{
|
||||||
rootFound: func(gopathwalk.Root) bool {
|
rootFound: func(root gopathwalk.Root) bool {
|
||||||
return true
|
// See getCandidatePkgs: walking GOROOT is apparently expensive and
|
||||||
|
// unnecessary.
|
||||||
|
return root.Type != gopathwalk.RootGOROOT
|
||||||
},
|
},
|
||||||
dirFound: func(pkg *pkg) bool {
|
dirFound: func(pkg *pkg) bool {
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
packageNameLoaded: func(pkg *pkg) bool {
|
// packageNameLoaded and exportsLoaded must never be called.
|
||||||
return false
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
return getCandidatePkgs(ctx, callback, "", "", env)
|
|
||||||
|
return resolver.scan(ctx, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func candidateImportName(pkg *pkg) string {
|
func candidateImportName(pkg *pkg) string {
|
||||||
|
@ -827,16 +829,45 @@ func GetPackageExports(ctx context.Context, wrapped func(PackageExport), searchP
|
||||||
return getCandidatePkgs(ctx, callback, filename, filePkg, env)
|
return getCandidatePkgs(ctx, callback, filename, filePkg, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
var requiredGoEnvVars = []string{"GO111MODULE", "GOFLAGS", "GOINSECURE", "GOMOD", "GOMODCACHE", "GONOPROXY", "GONOSUMDB", "GOPATH", "GOPROXY", "GOROOT", "GOSUMDB", "GOWORK"}
|
// TODO(rfindley): we should depend on GOOS and GOARCH, to provide accurate
|
||||||
|
// imports when doing cross-platform development.
|
||||||
|
var requiredGoEnvVars = []string{
|
||||||
|
"GO111MODULE",
|
||||||
|
"GOFLAGS",
|
||||||
|
"GOINSECURE",
|
||||||
|
"GOMOD",
|
||||||
|
"GOMODCACHE",
|
||||||
|
"GONOPROXY",
|
||||||
|
"GONOSUMDB",
|
||||||
|
"GOPATH",
|
||||||
|
"GOPROXY",
|
||||||
|
"GOROOT",
|
||||||
|
"GOSUMDB",
|
||||||
|
"GOWORK",
|
||||||
|
}
|
||||||
|
|
||||||
// ProcessEnv contains environment variables and settings that affect the use of
|
// ProcessEnv contains environment variables and settings that affect the use of
|
||||||
// the go command, the go/build package, etc.
|
// the go command, the go/build package, etc.
|
||||||
|
//
|
||||||
|
// ...a ProcessEnv *also* overwrites its Env along with derived state in the
|
||||||
|
// form of the resolver. And because it is lazily initialized, an env may just
|
||||||
|
// be broken and unusable, but there is no way for the caller to detect that:
|
||||||
|
// all queries will just fail.
|
||||||
|
//
|
||||||
|
// TODO(rfindley): refactor this package so that this type (perhaps renamed to
|
||||||
|
// just Env or Config) is an immutable configuration struct, to be exchanged
|
||||||
|
// for an initialized object via a constructor that returns an error. Perhaps
|
||||||
|
// the signature should be `func NewResolver(*Env) (*Resolver, error)`, where
|
||||||
|
// resolver is a concrete type used for resolving imports. Via this
|
||||||
|
// refactoring, we can avoid the need to call ProcessEnv.init and
|
||||||
|
// ProcessEnv.GoEnv everywhere, and implicitly fix all the places where this
|
||||||
|
// these are misused. Also, we'd delegate the caller the decision of how to
|
||||||
|
// handle a broken environment.
|
||||||
type ProcessEnv struct {
|
type ProcessEnv struct {
|
||||||
GocmdRunner *gocommand.Runner
|
GocmdRunner *gocommand.Runner
|
||||||
|
|
||||||
BuildFlags []string
|
BuildFlags []string
|
||||||
ModFlag string
|
ModFlag string
|
||||||
ModFile string
|
|
||||||
|
|
||||||
// SkipPathInScan returns true if the path should be skipped from scans of
|
// SkipPathInScan returns true if the path should be skipped from scans of
|
||||||
// the RootCurrentModule root type. The function argument is a clean,
|
// the RootCurrentModule root type. The function argument is a clean,
|
||||||
|
@ -846,7 +877,7 @@ type ProcessEnv struct {
|
||||||
// Env overrides the OS environment, and can be used to specify
|
// Env overrides the OS environment, and can be used to specify
|
||||||
// GOPROXY, GO111MODULE, etc. PATH cannot be set here, because
|
// GOPROXY, GO111MODULE, etc. PATH cannot be set here, because
|
||||||
// exec.Command will not honor it.
|
// exec.Command will not honor it.
|
||||||
// Specifying all of RequiredGoEnvVars avoids a call to `go env`.
|
// Specifying all of requiredGoEnvVars avoids a call to `go env`.
|
||||||
Env map[string]string
|
Env map[string]string
|
||||||
|
|
||||||
WorkingDir string
|
WorkingDir string
|
||||||
|
@ -854,9 +885,17 @@ type ProcessEnv struct {
|
||||||
// If Logf is non-nil, debug logging is enabled through this function.
|
// If Logf is non-nil, debug logging is enabled through this function.
|
||||||
Logf func(format string, args ...interface{})
|
Logf func(format string, args ...interface{})
|
||||||
|
|
||||||
initialized bool
|
// If set, ModCache holds a shared cache of directory info to use across
|
||||||
|
// multiple ProcessEnvs.
|
||||||
|
ModCache *DirInfoCache
|
||||||
|
|
||||||
|
initialized bool // see TODO above
|
||||||
|
|
||||||
|
// resolver and resolverErr are lazily evaluated (see GetResolver).
|
||||||
|
// This is unclean, but see the big TODO in the docstring for ProcessEnv
|
||||||
|
// above: for now, we can't be sure that the ProcessEnv is fully initialized.
|
||||||
resolver Resolver
|
resolver Resolver
|
||||||
|
resolverErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ProcessEnv) goEnv() (map[string]string, error) {
|
func (e *ProcessEnv) goEnv() (map[string]string, error) {
|
||||||
|
@ -936,20 +975,31 @@ func (e *ProcessEnv) env() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ProcessEnv) GetResolver() (Resolver, error) {
|
func (e *ProcessEnv) GetResolver() (Resolver, error) {
|
||||||
if e.resolver != nil {
|
|
||||||
return e.resolver, nil
|
|
||||||
}
|
|
||||||
if err := e.init(); err != nil {
|
if err := e.init(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if e.resolver == nil && e.resolverErr == nil {
|
||||||
|
// TODO(rfindley): we should only use a gopathResolver here if the working
|
||||||
|
// directory is actually *in* GOPATH. (I seem to recall an open gopls issue
|
||||||
|
// for this behavior, but I can't find it).
|
||||||
|
//
|
||||||
|
// For gopls, we can optionally explicitly choose a resolver type, since we
|
||||||
|
// already know the view type.
|
||||||
if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 {
|
if len(e.Env["GOMOD"]) == 0 && len(e.Env["GOWORK"]) == 0 {
|
||||||
e.resolver = newGopathResolver(e)
|
e.resolver = newGopathResolver(e)
|
||||||
return e.resolver, nil
|
} else {
|
||||||
|
e.resolver, e.resolverErr = newModuleResolver(e, e.ModCache)
|
||||||
}
|
}
|
||||||
e.resolver = newModuleResolver(e)
|
|
||||||
return e.resolver, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return e.resolver, e.resolverErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildContext returns the build.Context to use for matching files.
|
||||||
|
//
|
||||||
|
// TODO(rfindley): support dynamic GOOS, GOARCH here, when doing cross-platform
|
||||||
|
// development.
|
||||||
func (e *ProcessEnv) buildContext() (*build.Context, error) {
|
func (e *ProcessEnv) buildContext() (*build.Context, error) {
|
||||||
ctx := build.Default
|
ctx := build.Default
|
||||||
goenv, err := e.goEnv()
|
goenv, err := e.goEnv()
|
||||||
|
@ -1029,15 +1079,23 @@ func addStdlibCandidates(pass *pass, refs references) error {
|
||||||
type Resolver interface {
|
type Resolver interface {
|
||||||
// loadPackageNames loads the package names in importPaths.
|
// loadPackageNames loads the package names in importPaths.
|
||||||
loadPackageNames(importPaths []string, srcDir string) (map[string]string, error)
|
loadPackageNames(importPaths []string, srcDir string) (map[string]string, error)
|
||||||
|
|
||||||
// scan works with callback to search for packages. See scanCallback for details.
|
// scan works with callback to search for packages. See scanCallback for details.
|
||||||
scan(ctx context.Context, callback *scanCallback) error
|
scan(ctx context.Context, callback *scanCallback) error
|
||||||
|
|
||||||
// loadExports returns the set of exported symbols in the package at dir.
|
// loadExports returns the set of exported symbols in the package at dir.
|
||||||
// loadExports may be called concurrently.
|
// loadExports may be called concurrently.
|
||||||
loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error)
|
loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error)
|
||||||
|
|
||||||
// scoreImportPath returns the relevance for an import path.
|
// scoreImportPath returns the relevance for an import path.
|
||||||
scoreImportPath(ctx context.Context, path string) float64
|
scoreImportPath(ctx context.Context, path string) float64
|
||||||
|
|
||||||
ClearForNewScan()
|
// ClearForNewScan returns a new Resolver based on the receiver that has
|
||||||
|
// cleared its internal caches of directory contents.
|
||||||
|
//
|
||||||
|
// The new resolver should be primed and then set via
|
||||||
|
// [ProcessEnv.UpdateResolver].
|
||||||
|
ClearForNewScan() Resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
// A scanCallback controls a call to scan and receives its results.
|
// A scanCallback controls a call to scan and receives its results.
|
||||||
|
@ -1120,7 +1178,7 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs references, fil
|
||||||
go func(pkgName string, symbols map[string]bool) {
|
go func(pkgName string, symbols map[string]bool) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
found, err := findImport(ctx, pass, found[pkgName], pkgName, symbols, filename)
|
found, err := findImport(ctx, pass, found[pkgName], pkgName, symbols)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
firstErrOnce.Do(func() {
|
firstErrOnce.Do(func() {
|
||||||
|
@ -1151,6 +1209,17 @@ func addExternalCandidates(ctx context.Context, pass *pass, refs references, fil
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for result := range results {
|
for result := range results {
|
||||||
|
// Don't offer completions that would shadow predeclared
|
||||||
|
// names, such as github.com/coreos/etcd/error.
|
||||||
|
if types.Universe.Lookup(result.pkg.name) != nil { // predeclared
|
||||||
|
// Ideally we would skip this candidate only
|
||||||
|
// if the predeclared name is actually
|
||||||
|
// referenced by the file, but that's a lot
|
||||||
|
// trickier to compute and would still create
|
||||||
|
// an import that is likely to surprise the
|
||||||
|
// user before long.
|
||||||
|
continue
|
||||||
|
}
|
||||||
pass.addCandidate(result.imp, result.pkg)
|
pass.addCandidate(result.imp, result.pkg)
|
||||||
}
|
}
|
||||||
return firstErr
|
return firstErr
|
||||||
|
@ -1193,31 +1262,22 @@ func ImportPathToAssumedName(importPath string) string {
|
||||||
type gopathResolver struct {
|
type gopathResolver struct {
|
||||||
env *ProcessEnv
|
env *ProcessEnv
|
||||||
walked bool
|
walked bool
|
||||||
cache *dirInfoCache
|
cache *DirInfoCache
|
||||||
scanSema chan struct{} // scanSema prevents concurrent scans.
|
scanSema chan struct{} // scanSema prevents concurrent scans.
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGopathResolver(env *ProcessEnv) *gopathResolver {
|
func newGopathResolver(env *ProcessEnv) *gopathResolver {
|
||||||
r := &gopathResolver{
|
r := &gopathResolver{
|
||||||
env: env,
|
env: env,
|
||||||
cache: &dirInfoCache{
|
cache: NewDirInfoCache(),
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
|
||||||
listeners: map[*int]cacheListener{},
|
|
||||||
},
|
|
||||||
scanSema: make(chan struct{}, 1),
|
scanSema: make(chan struct{}, 1),
|
||||||
}
|
}
|
||||||
r.scanSema <- struct{}{}
|
r.scanSema <- struct{}{}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *gopathResolver) ClearForNewScan() {
|
func (r *gopathResolver) ClearForNewScan() Resolver {
|
||||||
<-r.scanSema
|
return newGopathResolver(r.env)
|
||||||
r.cache = &dirInfoCache{
|
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
|
||||||
listeners: map[*int]cacheListener{},
|
|
||||||
}
|
|
||||||
r.walked = false
|
|
||||||
r.scanSema <- struct{}{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
func (r *gopathResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
||||||
|
@ -1538,7 +1598,7 @@ func loadExportsFromFiles(ctx context.Context, env *ProcessEnv, dir string, incl
|
||||||
|
|
||||||
// findImport searches for a package with the given symbols.
|
// findImport searches for a package with the given symbols.
|
||||||
// If no package is found, findImport returns ("", false, nil)
|
// If no package is found, findImport returns ("", false, nil)
|
||||||
func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgName string, symbols map[string]bool, filename string) (*pkg, error) {
|
func findImport(ctx context.Context, pass *pass, candidates []pkgDistance, pkgName string, symbols map[string]bool) (*pkg, error) {
|
||||||
// Sort the candidates by their import package length,
|
// Sort the candidates by their import package length,
|
||||||
// assuming that shorter package names are better than long
|
// assuming that shorter package names are better than long
|
||||||
// ones. Note that this sorts by the de-vendored name, so
|
// ones. Note that this sorts by the de-vendored name, so
|
||||||
|
|
|
@ -236,7 +236,7 @@ func parse(fset *token.FileSet, filename string, src []byte, opt *Options) (*ast
|
||||||
src = src[:len(src)-len("}\n")]
|
src = src[:len(src)-len("}\n")]
|
||||||
// Gofmt has also indented the function body one level.
|
// Gofmt has also indented the function body one level.
|
||||||
// Remove that indent.
|
// Remove that indent.
|
||||||
src = bytes.Replace(src, []byte("\n\t"), []byte("\n"), -1)
|
src = bytes.ReplaceAll(src, []byte("\n\t"), []byte("\n"))
|
||||||
return matchSpace(orig, src)
|
return matchSpace(orig, src)
|
||||||
}
|
}
|
||||||
return file, adjust, nil
|
return file, adjust, nil
|
||||||
|
|
|
@ -23,49 +23,88 @@ import (
|
||||||
"golang.org/x/tools/internal/gopathwalk"
|
"golang.org/x/tools/internal/gopathwalk"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ModuleResolver implements resolver for modules using the go command as little
|
// Notes(rfindley): ModuleResolver appears to be heavily optimized for scanning
|
||||||
// as feasible.
|
// as fast as possible, which is desirable for a call to goimports from the
|
||||||
|
// command line, but it doesn't work as well for gopls, where it suffers from
|
||||||
|
// slow startup (golang/go#44863) and intermittent hanging (golang/go#59216),
|
||||||
|
// both caused by populating the cache, albeit in slightly different ways.
|
||||||
|
//
|
||||||
|
// A high level list of TODOs:
|
||||||
|
// - Optimize the scan itself, as there is some redundancy statting and
|
||||||
|
// reading go.mod files.
|
||||||
|
// - Invert the relationship between ProcessEnv and Resolver (see the
|
||||||
|
// docstring of ProcessEnv).
|
||||||
|
// - Make it easier to use an external resolver implementation.
|
||||||
|
//
|
||||||
|
// Smaller TODOs are annotated in the code below.
|
||||||
|
|
||||||
|
// ModuleResolver implements the Resolver interface for a workspace using
|
||||||
|
// modules.
|
||||||
|
//
|
||||||
|
// A goal of the ModuleResolver is to invoke the Go command as little as
|
||||||
|
// possible. To this end, it runs the Go command only for listing module
|
||||||
|
// information (i.e. `go list -m -e -json ...`). Package scanning, the process
|
||||||
|
// of loading package information for the modules, is implemented internally
|
||||||
|
// via the scan method.
|
||||||
|
//
|
||||||
|
// It has two types of state: the state derived from the go command, which
|
||||||
|
// is populated by init, and the state derived from scans, which is populated
|
||||||
|
// via scan. A root is considered scanned if it has been walked to discover
|
||||||
|
// directories. However, if the scan did not require additional information
|
||||||
|
// from the directory (such as package name or exports), the directory
|
||||||
|
// information itself may be partially populated. It will be lazily filled in
|
||||||
|
// as needed by scans, using the scanCallback.
|
||||||
type ModuleResolver struct {
|
type ModuleResolver struct {
|
||||||
env *ProcessEnv
|
env *ProcessEnv
|
||||||
moduleCacheDir string
|
|
||||||
dummyVendorMod *gocommand.ModuleJSON // If vendoring is enabled, the pseudo-module that represents the /vendor directory.
|
|
||||||
roots []gopathwalk.Root
|
|
||||||
scanSema chan struct{} // scanSema prevents concurrent scans and guards scannedRoots.
|
|
||||||
scannedRoots map[gopathwalk.Root]bool
|
|
||||||
|
|
||||||
initialized bool
|
// Module state, populated during construction
|
||||||
mains []*gocommand.ModuleJSON
|
dummyVendorMod *gocommand.ModuleJSON // if vendoring is enabled, a pseudo-module to represent the /vendor directory
|
||||||
mainByDir map[string]*gocommand.ModuleJSON
|
moduleCacheDir string // GOMODCACHE, inferred from GOPATH if unset
|
||||||
modsByModPath []*gocommand.ModuleJSON // All modules, ordered by # of path components in module Path...
|
roots []gopathwalk.Root // roots to scan, in approximate order of importance
|
||||||
modsByDir []*gocommand.ModuleJSON // ...or number of path components in their Dir.
|
mains []*gocommand.ModuleJSON // main modules
|
||||||
|
mainByDir map[string]*gocommand.ModuleJSON // module information by dir, to join with roots
|
||||||
|
modsByModPath []*gocommand.ModuleJSON // all modules, ordered by # of path components in their module path
|
||||||
|
modsByDir []*gocommand.ModuleJSON // ...or by the number of path components in their Dir.
|
||||||
|
|
||||||
// moduleCacheCache stores information about the module cache.
|
// Scanning state, populated by scan
|
||||||
moduleCacheCache *dirInfoCache
|
|
||||||
otherCache *dirInfoCache
|
// scanSema prevents concurrent scans, and guards scannedRoots and the cache
|
||||||
|
// fields below (though the caches themselves are concurrency safe).
|
||||||
|
// Receive to acquire, send to release.
|
||||||
|
scanSema chan struct{}
|
||||||
|
scannedRoots map[gopathwalk.Root]bool // if true, root has been walked
|
||||||
|
|
||||||
|
// Caches of directory info, populated by scans and scan callbacks
|
||||||
|
//
|
||||||
|
// moduleCacheCache stores cached information about roots in the module
|
||||||
|
// cache, which are immutable and therefore do not need to be invalidated.
|
||||||
|
//
|
||||||
|
// otherCache stores information about all other roots (even GOROOT), which
|
||||||
|
// may change.
|
||||||
|
moduleCacheCache *DirInfoCache
|
||||||
|
otherCache *DirInfoCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func newModuleResolver(e *ProcessEnv) *ModuleResolver {
|
// newModuleResolver returns a new module-aware goimports resolver.
|
||||||
|
//
|
||||||
|
// Note: use caution when modifying this constructor: changes must also be
|
||||||
|
// reflected in ModuleResolver.ClearForNewScan.
|
||||||
|
func newModuleResolver(e *ProcessEnv, moduleCacheCache *DirInfoCache) (*ModuleResolver, error) {
|
||||||
r := &ModuleResolver{
|
r := &ModuleResolver{
|
||||||
env: e,
|
env: e,
|
||||||
scanSema: make(chan struct{}, 1),
|
scanSema: make(chan struct{}, 1),
|
||||||
}
|
}
|
||||||
r.scanSema <- struct{}{}
|
r.scanSema <- struct{}{} // release
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ModuleResolver) init() error {
|
|
||||||
if r.initialized {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
goenv, err := r.env.goEnv()
|
goenv, err := r.env.goEnv()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(rfindley): can we refactor to share logic with r.env.invokeGo?
|
||||||
inv := gocommand.Invocation{
|
inv := gocommand.Invocation{
|
||||||
BuildFlags: r.env.BuildFlags,
|
BuildFlags: r.env.BuildFlags,
|
||||||
ModFlag: r.env.ModFlag,
|
ModFlag: r.env.ModFlag,
|
||||||
ModFile: r.env.ModFile,
|
|
||||||
Env: r.env.env(),
|
Env: r.env.env(),
|
||||||
Logf: r.env.Logf,
|
Logf: r.env.Logf,
|
||||||
WorkingDir: r.env.WorkingDir,
|
WorkingDir: r.env.WorkingDir,
|
||||||
|
@ -77,9 +116,12 @@ func (r *ModuleResolver) init() error {
|
||||||
// Module vendor directories are ignored in workspace mode:
|
// Module vendor directories are ignored in workspace mode:
|
||||||
// https://go.googlesource.com/proposal/+/master/design/45713-workspace.md
|
// https://go.googlesource.com/proposal/+/master/design/45713-workspace.md
|
||||||
if len(r.env.Env["GOWORK"]) == 0 {
|
if len(r.env.Env["GOWORK"]) == 0 {
|
||||||
|
// TODO(rfindley): VendorEnabled runs the go command to get GOFLAGS, but
|
||||||
|
// they should be available from the ProcessEnv. Can we avoid the redundant
|
||||||
|
// invocation?
|
||||||
vendorEnabled, mainModVendor, err = gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner)
|
vendorEnabled, mainModVendor, err = gocommand.VendorEnabled(context.TODO(), inv, r.env.GocmdRunner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,19 +142,14 @@ func (r *ModuleResolver) init() error {
|
||||||
// GO111MODULE=on. Other errors are fatal.
|
// GO111MODULE=on. Other errors are fatal.
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errMsg := err.Error(); !strings.Contains(errMsg, "working directory is not part of a module") && !strings.Contains(errMsg, "go.mod file not found") {
|
if errMsg := err.Error(); !strings.Contains(errMsg, "working directory is not part of a module") && !strings.Contains(errMsg, "go.mod file not found") {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if gmc := r.env.Env["GOMODCACHE"]; gmc != "" {
|
r.moduleCacheDir = gomodcacheForEnv(goenv)
|
||||||
r.moduleCacheDir = gmc
|
if r.moduleCacheDir == "" {
|
||||||
} else {
|
return nil, fmt.Errorf("cannot resolve GOMODCACHE")
|
||||||
gopaths := filepath.SplitList(goenv["GOPATH"])
|
|
||||||
if len(gopaths) == 0 {
|
|
||||||
return fmt.Errorf("empty GOPATH")
|
|
||||||
}
|
|
||||||
r.moduleCacheDir = filepath.Join(gopaths[0], "/pkg/mod")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(r.modsByModPath, func(i, j int) bool {
|
sort.Slice(r.modsByModPath, func(i, j int) bool {
|
||||||
|
@ -141,7 +178,11 @@ func (r *ModuleResolver) init() error {
|
||||||
} else {
|
} else {
|
||||||
addDep := func(mod *gocommand.ModuleJSON) {
|
addDep := func(mod *gocommand.ModuleJSON) {
|
||||||
if mod.Replace == nil {
|
if mod.Replace == nil {
|
||||||
// This is redundant with the cache, but we'll skip it cheaply enough.
|
// This is redundant with the cache, but we'll skip it cheaply enough
|
||||||
|
// when we encounter it in the module cache scan.
|
||||||
|
//
|
||||||
|
// Including it at a lower index in r.roots than the module cache dir
|
||||||
|
// helps prioritize matches from within existing dependencies.
|
||||||
r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootModuleCache})
|
r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootModuleCache})
|
||||||
} else {
|
} else {
|
||||||
r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootOther})
|
r.roots = append(r.roots, gopathwalk.Root{Path: mod.Dir, Type: gopathwalk.RootOther})
|
||||||
|
@ -158,24 +199,40 @@ func (r *ModuleResolver) init() error {
|
||||||
addDep(mod)
|
addDep(mod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If provided, share the moduleCacheCache.
|
||||||
|
//
|
||||||
|
// TODO(rfindley): The module cache is immutable. However, the loaded
|
||||||
|
// exports do depend on GOOS and GOARCH. Fortunately, the
|
||||||
|
// ProcessEnv.buildContext does not adjust these from build.DefaultContext
|
||||||
|
// (even though it should). So for now, this is OK to share, but we need to
|
||||||
|
// add logic for handling GOOS/GOARCH.
|
||||||
|
r.moduleCacheCache = moduleCacheCache
|
||||||
r.roots = append(r.roots, gopathwalk.Root{Path: r.moduleCacheDir, Type: gopathwalk.RootModuleCache})
|
r.roots = append(r.roots, gopathwalk.Root{Path: r.moduleCacheDir, Type: gopathwalk.RootModuleCache})
|
||||||
}
|
}
|
||||||
|
|
||||||
r.scannedRoots = map[gopathwalk.Root]bool{}
|
r.scannedRoots = map[gopathwalk.Root]bool{}
|
||||||
if r.moduleCacheCache == nil {
|
if r.moduleCacheCache == nil {
|
||||||
r.moduleCacheCache = &dirInfoCache{
|
r.moduleCacheCache = NewDirInfoCache()
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
|
||||||
listeners: map[*int]cacheListener{},
|
|
||||||
}
|
}
|
||||||
|
r.otherCache = NewDirInfoCache()
|
||||||
|
return r, nil
|
||||||
}
|
}
|
||||||
if r.otherCache == nil {
|
|
||||||
r.otherCache = &dirInfoCache{
|
// gomodcacheForEnv returns the GOMODCACHE value to use based on the given env
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
// map, which must have GOMODCACHE and GOPATH populated.
|
||||||
listeners: map[*int]cacheListener{},
|
//
|
||||||
|
// TODO(rfindley): this is defensive refactoring.
|
||||||
|
// 1. Is this even relevant anymore? Can't we just read GOMODCACHE.
|
||||||
|
// 2. Use this to separate module cache scanning from other scanning.
|
||||||
|
func gomodcacheForEnv(goenv map[string]string) string {
|
||||||
|
if gmc := goenv["GOMODCACHE"]; gmc != "" {
|
||||||
|
return gmc
|
||||||
}
|
}
|
||||||
|
gopaths := filepath.SplitList(goenv["GOPATH"])
|
||||||
|
if len(gopaths) == 0 {
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
r.initialized = true
|
return filepath.Join(gopaths[0], "/pkg/mod")
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) initAllMods() error {
|
func (r *ModuleResolver) initAllMods() error {
|
||||||
|
@ -206,30 +263,82 @@ func (r *ModuleResolver) initAllMods() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) ClearForNewScan() {
|
// ClearForNewScan invalidates the last scan.
|
||||||
<-r.scanSema
|
//
|
||||||
r.scannedRoots = map[gopathwalk.Root]bool{}
|
// It preserves the set of roots, but forgets about the set of directories.
|
||||||
r.otherCache = &dirInfoCache{
|
// Though it forgets the set of module cache directories, it remembers their
|
||||||
dirs: map[string]*directoryPackageInfo{},
|
// contents, since they are assumed to be immutable.
|
||||||
listeners: map[*int]cacheListener{},
|
func (r *ModuleResolver) ClearForNewScan() Resolver {
|
||||||
}
|
<-r.scanSema // acquire r, to guard scannedRoots
|
||||||
r.scanSema <- struct{}{}
|
r2 := &ModuleResolver{
|
||||||
}
|
|
||||||
|
|
||||||
func (r *ModuleResolver) ClearForNewMod() {
|
|
||||||
<-r.scanSema
|
|
||||||
*r = ModuleResolver{
|
|
||||||
env: r.env,
|
env: r.env,
|
||||||
|
dummyVendorMod: r.dummyVendorMod,
|
||||||
|
moduleCacheDir: r.moduleCacheDir,
|
||||||
|
roots: r.roots,
|
||||||
|
mains: r.mains,
|
||||||
|
mainByDir: r.mainByDir,
|
||||||
|
modsByModPath: r.modsByModPath,
|
||||||
|
|
||||||
|
scanSema: make(chan struct{}, 1),
|
||||||
|
scannedRoots: make(map[gopathwalk.Root]bool),
|
||||||
|
otherCache: NewDirInfoCache(),
|
||||||
moduleCacheCache: r.moduleCacheCache,
|
moduleCacheCache: r.moduleCacheCache,
|
||||||
otherCache: r.otherCache,
|
|
||||||
scanSema: r.scanSema,
|
|
||||||
}
|
}
|
||||||
r.init()
|
r2.scanSema <- struct{}{} // r2 must start released
|
||||||
r.scanSema <- struct{}{}
|
// Invalidate root scans. We don't need to invalidate module cache roots,
|
||||||
|
// because they are immutable.
|
||||||
|
// (We don't support a use case where GOMODCACHE is cleaned in the middle of
|
||||||
|
// e.g. a gopls session: the user must restart gopls to get accurate
|
||||||
|
// imports.)
|
||||||
|
//
|
||||||
|
// Scanning for new directories in GOMODCACHE should be handled elsewhere,
|
||||||
|
// via a call to ScanModuleCache.
|
||||||
|
for _, root := range r.roots {
|
||||||
|
if root.Type == gopathwalk.RootModuleCache && r.scannedRoots[root] {
|
||||||
|
r2.scannedRoots[root] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.scanSema <- struct{}{} // release r
|
||||||
|
return r2
|
||||||
}
|
}
|
||||||
|
|
||||||
// findPackage returns the module and directory that contains the package at
|
// ClearModuleInfo invalidates resolver state that depends on go.mod file
|
||||||
// the given import path, or returns nil, "" if no module is in scope.
|
// contents (essentially, the output of go list -m -json ...).
|
||||||
|
//
|
||||||
|
// Notably, it does not forget directory contents, which are reset
|
||||||
|
// asynchronously via ClearForNewScan.
|
||||||
|
//
|
||||||
|
// If the ProcessEnv is a GOPATH environment, ClearModuleInfo is a no op.
|
||||||
|
//
|
||||||
|
// TODO(rfindley): move this to a new env.go, consolidating ProcessEnv methods.
|
||||||
|
func (e *ProcessEnv) ClearModuleInfo() {
|
||||||
|
if r, ok := e.resolver.(*ModuleResolver); ok {
|
||||||
|
resolver, resolverErr := newModuleResolver(e, e.ModCache)
|
||||||
|
if resolverErr == nil {
|
||||||
|
<-r.scanSema // acquire (guards caches)
|
||||||
|
resolver.moduleCacheCache = r.moduleCacheCache
|
||||||
|
resolver.otherCache = r.otherCache
|
||||||
|
r.scanSema <- struct{}{} // release
|
||||||
|
}
|
||||||
|
e.resolver = resolver
|
||||||
|
e.resolverErr = resolverErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateResolver sets the resolver for the ProcessEnv to use in imports
|
||||||
|
// operations. Only for use with the result of [Resolver.ClearForNewScan].
|
||||||
|
//
|
||||||
|
// TODO(rfindley): this awkward API is a result of the (arguably) inverted
|
||||||
|
// relationship between configuration and state described in the doc comment
|
||||||
|
// for [ProcessEnv].
|
||||||
|
func (e *ProcessEnv) UpdateResolver(r Resolver) {
|
||||||
|
e.resolver = r
|
||||||
|
e.resolverErr = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// findPackage returns the module and directory from within the main modules
|
||||||
|
// and their dependencies that contains the package at the given import path,
|
||||||
|
// or returns nil, "" if no module is in scope.
|
||||||
func (r *ModuleResolver) findPackage(importPath string) (*gocommand.ModuleJSON, string) {
|
func (r *ModuleResolver) findPackage(importPath string) (*gocommand.ModuleJSON, string) {
|
||||||
// This can't find packages in the stdlib, but that's harmless for all
|
// This can't find packages in the stdlib, but that's harmless for all
|
||||||
// the existing code paths.
|
// the existing code paths.
|
||||||
|
@ -295,10 +404,6 @@ func (r *ModuleResolver) cacheStore(info directoryPackageInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) cacheKeys() []string {
|
|
||||||
return append(r.moduleCacheCache.Keys(), r.otherCache.Keys()...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// cachePackageName caches the package name for a dir already in the cache.
|
// cachePackageName caches the package name for a dir already in the cache.
|
||||||
func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (string, error) {
|
func (r *ModuleResolver) cachePackageName(info directoryPackageInfo) (string, error) {
|
||||||
if info.rootType == gopathwalk.RootModuleCache {
|
if info.rootType == gopathwalk.RootModuleCache {
|
||||||
|
@ -367,8 +472,7 @@ func (r *ModuleResolver) dirIsNestedModule(dir string, mod *gocommand.ModuleJSON
|
||||||
return modDir != mod.Dir
|
return modDir != mod.Dir
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) modInfo(dir string) (modDir string, modName string) {
|
func readModName(modFile string) string {
|
||||||
readModName := func(modFile string) string {
|
|
||||||
modBytes, err := os.ReadFile(modFile)
|
modBytes, err := os.ReadFile(modFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
|
@ -376,6 +480,7 @@ func (r *ModuleResolver) modInfo(dir string) (modDir string, modName string) {
|
||||||
return modulePath(modBytes)
|
return modulePath(modBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ModuleResolver) modInfo(dir string) (modDir, modName string) {
|
||||||
if r.dirInModuleCache(dir) {
|
if r.dirInModuleCache(dir) {
|
||||||
if matches := modCacheRegexp.FindStringSubmatch(dir); len(matches) == 3 {
|
if matches := modCacheRegexp.FindStringSubmatch(dir); len(matches) == 3 {
|
||||||
index := strings.Index(dir, matches[1]+"@"+matches[2])
|
index := strings.Index(dir, matches[1]+"@"+matches[2])
|
||||||
|
@ -409,11 +514,9 @@ func (r *ModuleResolver) dirInModuleCache(dir string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
func (r *ModuleResolver) loadPackageNames(importPaths []string, srcDir string) (map[string]string, error) {
|
||||||
if err := r.init(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
names := map[string]string{}
|
names := map[string]string{}
|
||||||
for _, path := range importPaths {
|
for _, path := range importPaths {
|
||||||
|
// TODO(rfindley): shouldn't this use the dirInfoCache?
|
||||||
_, packageDir := r.findPackage(path)
|
_, packageDir := r.findPackage(path)
|
||||||
if packageDir == "" {
|
if packageDir == "" {
|
||||||
continue
|
continue
|
||||||
|
@ -431,10 +534,6 @@ func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error
|
||||||
ctx, done := event.Start(ctx, "imports.ModuleResolver.scan")
|
ctx, done := event.Start(ctx, "imports.ModuleResolver.scan")
|
||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
if err := r.init(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
processDir := func(info directoryPackageInfo) {
|
processDir := func(info directoryPackageInfo) {
|
||||||
// Skip this directory if we were not able to get the package information successfully.
|
// Skip this directory if we were not able to get the package information successfully.
|
||||||
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
if scanned, err := info.reachedStatus(directoryScanned); !scanned || err != nil {
|
||||||
|
@ -444,18 +543,18 @@ func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !callback.dirFound(pkg) {
|
if !callback.dirFound(pkg) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pkg.packageName, err = r.cachePackageName(info)
|
pkg.packageName, err = r.cachePackageName(info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !callback.packageNameLoaded(pkg) {
|
if !callback.packageNameLoaded(pkg) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, exports, err := r.loadExports(ctx, pkg, false)
|
_, exports, err := r.loadExports(ctx, pkg, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -494,7 +593,6 @@ func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error
|
||||||
return packageScanned
|
return packageScanned
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add anything new to the cache, and process it if we're still listening.
|
|
||||||
add := func(root gopathwalk.Root, dir string) {
|
add := func(root gopathwalk.Root, dir string) {
|
||||||
r.cacheStore(r.scanDirForPackage(root, dir))
|
r.cacheStore(r.scanDirForPackage(root, dir))
|
||||||
}
|
}
|
||||||
|
@ -509,9 +607,9 @@ func (r *ModuleResolver) scan(ctx context.Context, callback *scanCallback) error
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return
|
return
|
||||||
case <-r.scanSema:
|
case <-r.scanSema: // acquire
|
||||||
}
|
}
|
||||||
defer func() { r.scanSema <- struct{}{} }()
|
defer func() { r.scanSema <- struct{}{} }() // release
|
||||||
// We have the lock on r.scannedRoots, and no other scans can run.
|
// We have the lock on r.scannedRoots, and no other scans can run.
|
||||||
for _, root := range roots {
|
for _, root := range roots {
|
||||||
if ctx.Err() != nil {
|
if ctx.Err() != nil {
|
||||||
|
@ -613,9 +711,6 @@ func (r *ModuleResolver) canonicalize(info directoryPackageInfo) (*pkg, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ModuleResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error) {
|
func (r *ModuleResolver) loadExports(ctx context.Context, pkg *pkg, includeTest bool) (string, []string, error) {
|
||||||
if err := r.init(); err != nil {
|
|
||||||
return "", nil, err
|
|
||||||
}
|
|
||||||
if info, ok := r.cacheLoad(pkg.dir); ok && !includeTest {
|
if info, ok := r.cacheLoad(pkg.dir); ok && !includeTest {
|
||||||
return r.cacheExports(ctx, r.env, info)
|
return r.cacheExports(ctx, r.env, info)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,12 @@ package imports
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"golang.org/x/mod/module"
|
||||||
"golang.org/x/tools/internal/gopathwalk"
|
"golang.org/x/tools/internal/gopathwalk"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,6 +43,8 @@ const (
|
||||||
exportsLoaded
|
exportsLoaded
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// directoryPackageInfo holds (possibly incomplete) information about packages
|
||||||
|
// contained in a given directory.
|
||||||
type directoryPackageInfo struct {
|
type directoryPackageInfo struct {
|
||||||
// status indicates the extent to which this struct has been filled in.
|
// status indicates the extent to which this struct has been filled in.
|
||||||
status directoryPackageStatus
|
status directoryPackageStatus
|
||||||
|
@ -63,7 +69,10 @@ type directoryPackageInfo struct {
|
||||||
packageName string // the package name, as declared in the source.
|
packageName string // the package name, as declared in the source.
|
||||||
|
|
||||||
// Set when status >= exportsLoaded.
|
// Set when status >= exportsLoaded.
|
||||||
|
// TODO(rfindley): it's hard to see this, but exports depend implicitly on
|
||||||
|
// the default build context GOOS and GOARCH.
|
||||||
|
//
|
||||||
|
// We can make this explicit, and key exports by GOOS, GOARCH.
|
||||||
exports []string
|
exports []string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +88,7 @@ func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// dirInfoCache is a concurrency safe map for storing information about
|
// DirInfoCache is a concurrency-safe map for storing information about
|
||||||
// directories that may contain packages.
|
// directories that may contain packages.
|
||||||
//
|
//
|
||||||
// The information in this cache is built incrementally. Entries are initialized in scan.
|
// The information in this cache is built incrementally. Entries are initialized in scan.
|
||||||
|
@ -92,21 +101,26 @@ func (info *directoryPackageInfo) reachedStatus(target directoryPackageStatus) (
|
||||||
// The information in the cache is not expected to change for the cache's
|
// The information in the cache is not expected to change for the cache's
|
||||||
// lifetime, so there is no protection against competing writes. Users should
|
// lifetime, so there is no protection against competing writes. Users should
|
||||||
// take care not to hold the cache across changes to the underlying files.
|
// take care not to hold the cache across changes to the underlying files.
|
||||||
//
|
type DirInfoCache struct {
|
||||||
// TODO(suzmue): consider other concurrency strategies and data structures (RWLocks, sync.Map, etc)
|
|
||||||
type dirInfoCache struct {
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
// dirs stores information about packages in directories, keyed by absolute path.
|
// dirs stores information about packages in directories, keyed by absolute path.
|
||||||
dirs map[string]*directoryPackageInfo
|
dirs map[string]*directoryPackageInfo
|
||||||
listeners map[*int]cacheListener
|
listeners map[*int]cacheListener
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDirInfoCache() *DirInfoCache {
|
||||||
|
return &DirInfoCache{
|
||||||
|
dirs: make(map[string]*directoryPackageInfo),
|
||||||
|
listeners: make(map[*int]cacheListener),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type cacheListener func(directoryPackageInfo)
|
type cacheListener func(directoryPackageInfo)
|
||||||
|
|
||||||
// ScanAndListen calls listener on all the items in the cache, and on anything
|
// ScanAndListen calls listener on all the items in the cache, and on anything
|
||||||
// newly added. The returned stop function waits for all in-flight callbacks to
|
// newly added. The returned stop function waits for all in-flight callbacks to
|
||||||
// finish and blocks new ones.
|
// finish and blocks new ones.
|
||||||
func (d *dirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func() {
|
func (d *DirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener) func() {
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
|
|
||||||
// Flushing out all the callbacks is tricky without knowing how many there
|
// Flushing out all the callbacks is tricky without knowing how many there
|
||||||
|
@ -162,8 +176,10 @@ func (d *dirInfoCache) ScanAndListen(ctx context.Context, listener cacheListener
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store stores the package info for dir.
|
// Store stores the package info for dir.
|
||||||
func (d *dirInfoCache) Store(dir string, info directoryPackageInfo) {
|
func (d *DirInfoCache) Store(dir string, info directoryPackageInfo) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
|
// TODO(rfindley, golang/go#59216): should we overwrite an existing entry?
|
||||||
|
// That seems incorrect as the cache should be idempotent.
|
||||||
_, old := d.dirs[dir]
|
_, old := d.dirs[dir]
|
||||||
d.dirs[dir] = &info
|
d.dirs[dir] = &info
|
||||||
var listeners []cacheListener
|
var listeners []cacheListener
|
||||||
|
@ -180,7 +196,7 @@ func (d *dirInfoCache) Store(dir string, info directoryPackageInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load returns a copy of the directoryPackageInfo for absolute directory dir.
|
// Load returns a copy of the directoryPackageInfo for absolute directory dir.
|
||||||
func (d *dirInfoCache) Load(dir string) (directoryPackageInfo, bool) {
|
func (d *DirInfoCache) Load(dir string) (directoryPackageInfo, bool) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
info, ok := d.dirs[dir]
|
info, ok := d.dirs[dir]
|
||||||
|
@ -191,7 +207,7 @@ func (d *dirInfoCache) Load(dir string) (directoryPackageInfo, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys returns the keys currently present in d.
|
// Keys returns the keys currently present in d.
|
||||||
func (d *dirInfoCache) Keys() (keys []string) {
|
func (d *DirInfoCache) Keys() (keys []string) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
for key := range d.dirs {
|
for key := range d.dirs {
|
||||||
|
@ -200,7 +216,7 @@ func (d *dirInfoCache) Keys() (keys []string) {
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dirInfoCache) CachePackageName(info directoryPackageInfo) (string, error) {
|
func (d *DirInfoCache) CachePackageName(info directoryPackageInfo) (string, error) {
|
||||||
if loaded, err := info.reachedStatus(nameLoaded); loaded {
|
if loaded, err := info.reachedStatus(nameLoaded); loaded {
|
||||||
return info.packageName, err
|
return info.packageName, err
|
||||||
}
|
}
|
||||||
|
@ -213,7 +229,7 @@ func (d *dirInfoCache) CachePackageName(info directoryPackageInfo) (string, erro
|
||||||
return info.packageName, info.err
|
return info.packageName, info.err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []string, error) {
|
func (d *DirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info directoryPackageInfo) (string, []string, error) {
|
||||||
if reached, _ := info.reachedStatus(exportsLoaded); reached {
|
if reached, _ := info.reachedStatus(exportsLoaded); reached {
|
||||||
return info.packageName, info.exports, info.err
|
return info.packageName, info.exports, info.err
|
||||||
}
|
}
|
||||||
|
@ -234,3 +250,81 @@ func (d *dirInfoCache) CacheExports(ctx context.Context, env *ProcessEnv, info d
|
||||||
d.Store(info.dir, info)
|
d.Store(info.dir, info)
|
||||||
return info.packageName, info.exports, info.err
|
return info.packageName, info.exports, info.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScanModuleCache walks the given directory, which must be a GOMODCACHE value,
|
||||||
|
// for directory package information, storing the results in cache.
|
||||||
|
func ScanModuleCache(dir string, cache *DirInfoCache, logf func(string, ...any)) {
|
||||||
|
// Note(rfindley): it's hard to see, but this function attempts to implement
|
||||||
|
// just the side effects on cache of calling PrimeCache with a ProcessEnv
|
||||||
|
// that has the given dir as its GOMODCACHE.
|
||||||
|
//
|
||||||
|
// Teasing out the control flow, we see that we can avoid any handling of
|
||||||
|
// vendor/ and can infer module info entirely from the path, simplifying the
|
||||||
|
// logic here.
|
||||||
|
|
||||||
|
root := gopathwalk.Root{
|
||||||
|
Path: filepath.Clean(dir),
|
||||||
|
Type: gopathwalk.RootModuleCache,
|
||||||
|
}
|
||||||
|
|
||||||
|
directoryInfo := func(root gopathwalk.Root, dir string) directoryPackageInfo {
|
||||||
|
// This is a copy of ModuleResolver.scanDirForPackage, trimmed down to
|
||||||
|
// logic that applies to a module cache directory.
|
||||||
|
|
||||||
|
subdir := ""
|
||||||
|
if dir != root.Path {
|
||||||
|
subdir = dir[len(root.Path)+len("/"):]
|
||||||
|
}
|
||||||
|
|
||||||
|
matches := modCacheRegexp.FindStringSubmatch(subdir)
|
||||||
|
if len(matches) == 0 {
|
||||||
|
return directoryPackageInfo{
|
||||||
|
status: directoryScanned,
|
||||||
|
err: fmt.Errorf("invalid module cache path: %v", subdir),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modPath, err := module.UnescapePath(filepath.ToSlash(matches[1]))
|
||||||
|
if err != nil {
|
||||||
|
if logf != nil {
|
||||||
|
logf("decoding module cache path %q: %v", subdir, err)
|
||||||
|
}
|
||||||
|
return directoryPackageInfo{
|
||||||
|
status: directoryScanned,
|
||||||
|
err: fmt.Errorf("decoding module cache path %q: %v", subdir, err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
importPath := path.Join(modPath, filepath.ToSlash(matches[3]))
|
||||||
|
index := strings.Index(dir, matches[1]+"@"+matches[2])
|
||||||
|
modDir := filepath.Join(dir[:index], matches[1]+"@"+matches[2])
|
||||||
|
modName := readModName(filepath.Join(modDir, "go.mod"))
|
||||||
|
return directoryPackageInfo{
|
||||||
|
status: directoryScanned,
|
||||||
|
dir: dir,
|
||||||
|
rootType: root.Type,
|
||||||
|
nonCanonicalImportPath: importPath,
|
||||||
|
moduleDir: modDir,
|
||||||
|
moduleName: modName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add := func(root gopathwalk.Root, dir string) {
|
||||||
|
info := directoryInfo(root, dir)
|
||||||
|
cache.Store(info.dir, info)
|
||||||
|
}
|
||||||
|
|
||||||
|
skip := func(_ gopathwalk.Root, dir string) bool {
|
||||||
|
// Skip directories that have already been scanned.
|
||||||
|
//
|
||||||
|
// Note that gopathwalk only adds "package" directories, which must contain
|
||||||
|
// a .go file, and all such package directories in the module cache are
|
||||||
|
// immutable. So if we can load a dir, it can be skipped.
|
||||||
|
info, ok := cache.Load(dir)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
packageScanned, _ := info.reachedStatus(directoryScanned)
|
||||||
|
return packageScanned
|
||||||
|
}
|
||||||
|
|
||||||
|
gopathwalk.WalkSkip([]gopathwalk.Root{root}, add, skip, gopathwalk.Options{Logf: logf, ModulesEnabled: true})
|
||||||
|
}
|
||||||
|
|
|
@ -151,6 +151,7 @@ var stdlib = map[string][]string{
|
||||||
"cmp": {
|
"cmp": {
|
||||||
"Compare",
|
"Compare",
|
||||||
"Less",
|
"Less",
|
||||||
|
"Or",
|
||||||
"Ordered",
|
"Ordered",
|
||||||
},
|
},
|
||||||
"compress/bzip2": {
|
"compress/bzip2": {
|
||||||
|
@ -632,6 +633,8 @@ var stdlib = map[string][]string{
|
||||||
"NameMismatch",
|
"NameMismatch",
|
||||||
"NewCertPool",
|
"NewCertPool",
|
||||||
"NotAuthorizedToSign",
|
"NotAuthorizedToSign",
|
||||||
|
"OID",
|
||||||
|
"OIDFromInts",
|
||||||
"PEMCipher",
|
"PEMCipher",
|
||||||
"PEMCipher3DES",
|
"PEMCipher3DES",
|
||||||
"PEMCipherAES128",
|
"PEMCipherAES128",
|
||||||
|
@ -706,6 +709,7 @@ var stdlib = map[string][]string{
|
||||||
"LevelWriteCommitted",
|
"LevelWriteCommitted",
|
||||||
"Named",
|
"Named",
|
||||||
"NamedArg",
|
"NamedArg",
|
||||||
|
"Null",
|
||||||
"NullBool",
|
"NullBool",
|
||||||
"NullByte",
|
"NullByte",
|
||||||
"NullFloat64",
|
"NullFloat64",
|
||||||
|
@ -1921,6 +1925,7 @@ var stdlib = map[string][]string{
|
||||||
"R_LARCH_32",
|
"R_LARCH_32",
|
||||||
"R_LARCH_32_PCREL",
|
"R_LARCH_32_PCREL",
|
||||||
"R_LARCH_64",
|
"R_LARCH_64",
|
||||||
|
"R_LARCH_64_PCREL",
|
||||||
"R_LARCH_ABS64_HI12",
|
"R_LARCH_ABS64_HI12",
|
||||||
"R_LARCH_ABS64_LO20",
|
"R_LARCH_ABS64_LO20",
|
||||||
"R_LARCH_ABS_HI20",
|
"R_LARCH_ABS_HI20",
|
||||||
|
@ -1928,12 +1933,17 @@ var stdlib = map[string][]string{
|
||||||
"R_LARCH_ADD16",
|
"R_LARCH_ADD16",
|
||||||
"R_LARCH_ADD24",
|
"R_LARCH_ADD24",
|
||||||
"R_LARCH_ADD32",
|
"R_LARCH_ADD32",
|
||||||
|
"R_LARCH_ADD6",
|
||||||
"R_LARCH_ADD64",
|
"R_LARCH_ADD64",
|
||||||
"R_LARCH_ADD8",
|
"R_LARCH_ADD8",
|
||||||
|
"R_LARCH_ADD_ULEB128",
|
||||||
|
"R_LARCH_ALIGN",
|
||||||
"R_LARCH_B16",
|
"R_LARCH_B16",
|
||||||
"R_LARCH_B21",
|
"R_LARCH_B21",
|
||||||
"R_LARCH_B26",
|
"R_LARCH_B26",
|
||||||
|
"R_LARCH_CFA",
|
||||||
"R_LARCH_COPY",
|
"R_LARCH_COPY",
|
||||||
|
"R_LARCH_DELETE",
|
||||||
"R_LARCH_GNU_VTENTRY",
|
"R_LARCH_GNU_VTENTRY",
|
||||||
"R_LARCH_GNU_VTINHERIT",
|
"R_LARCH_GNU_VTINHERIT",
|
||||||
"R_LARCH_GOT64_HI12",
|
"R_LARCH_GOT64_HI12",
|
||||||
|
@ -1953,6 +1963,7 @@ var stdlib = map[string][]string{
|
||||||
"R_LARCH_PCALA64_LO20",
|
"R_LARCH_PCALA64_LO20",
|
||||||
"R_LARCH_PCALA_HI20",
|
"R_LARCH_PCALA_HI20",
|
||||||
"R_LARCH_PCALA_LO12",
|
"R_LARCH_PCALA_LO12",
|
||||||
|
"R_LARCH_PCREL20_S2",
|
||||||
"R_LARCH_RELATIVE",
|
"R_LARCH_RELATIVE",
|
||||||
"R_LARCH_RELAX",
|
"R_LARCH_RELAX",
|
||||||
"R_LARCH_SOP_ADD",
|
"R_LARCH_SOP_ADD",
|
||||||
|
@ -1983,8 +1994,10 @@ var stdlib = map[string][]string{
|
||||||
"R_LARCH_SUB16",
|
"R_LARCH_SUB16",
|
||||||
"R_LARCH_SUB24",
|
"R_LARCH_SUB24",
|
||||||
"R_LARCH_SUB32",
|
"R_LARCH_SUB32",
|
||||||
|
"R_LARCH_SUB6",
|
||||||
"R_LARCH_SUB64",
|
"R_LARCH_SUB64",
|
||||||
"R_LARCH_SUB8",
|
"R_LARCH_SUB8",
|
||||||
|
"R_LARCH_SUB_ULEB128",
|
||||||
"R_LARCH_TLS_DTPMOD32",
|
"R_LARCH_TLS_DTPMOD32",
|
||||||
"R_LARCH_TLS_DTPMOD64",
|
"R_LARCH_TLS_DTPMOD64",
|
||||||
"R_LARCH_TLS_DTPREL32",
|
"R_LARCH_TLS_DTPREL32",
|
||||||
|
@ -2035,6 +2048,7 @@ var stdlib = map[string][]string{
|
||||||
"R_MIPS_LO16",
|
"R_MIPS_LO16",
|
||||||
"R_MIPS_NONE",
|
"R_MIPS_NONE",
|
||||||
"R_MIPS_PC16",
|
"R_MIPS_PC16",
|
||||||
|
"R_MIPS_PC32",
|
||||||
"R_MIPS_PJUMP",
|
"R_MIPS_PJUMP",
|
||||||
"R_MIPS_REL16",
|
"R_MIPS_REL16",
|
||||||
"R_MIPS_REL32",
|
"R_MIPS_REL32",
|
||||||
|
@ -2952,6 +2966,8 @@ var stdlib = map[string][]string{
|
||||||
"RegisterName",
|
"RegisterName",
|
||||||
},
|
},
|
||||||
"encoding/hex": {
|
"encoding/hex": {
|
||||||
|
"AppendDecode",
|
||||||
|
"AppendEncode",
|
||||||
"Decode",
|
"Decode",
|
||||||
"DecodeString",
|
"DecodeString",
|
||||||
"DecodedLen",
|
"DecodedLen",
|
||||||
|
@ -3233,6 +3249,7 @@ var stdlib = map[string][]string{
|
||||||
"TypeSpec",
|
"TypeSpec",
|
||||||
"TypeSwitchStmt",
|
"TypeSwitchStmt",
|
||||||
"UnaryExpr",
|
"UnaryExpr",
|
||||||
|
"Unparen",
|
||||||
"ValueSpec",
|
"ValueSpec",
|
||||||
"Var",
|
"Var",
|
||||||
"Visitor",
|
"Visitor",
|
||||||
|
@ -3492,6 +3509,7 @@ var stdlib = map[string][]string{
|
||||||
"XOR_ASSIGN",
|
"XOR_ASSIGN",
|
||||||
},
|
},
|
||||||
"go/types": {
|
"go/types": {
|
||||||
|
"Alias",
|
||||||
"ArgumentError",
|
"ArgumentError",
|
||||||
"Array",
|
"Array",
|
||||||
"AssertableTo",
|
"AssertableTo",
|
||||||
|
@ -3559,6 +3577,7 @@ var stdlib = map[string][]string{
|
||||||
"MethodVal",
|
"MethodVal",
|
||||||
"MissingMethod",
|
"MissingMethod",
|
||||||
"Named",
|
"Named",
|
||||||
|
"NewAlias",
|
||||||
"NewArray",
|
"NewArray",
|
||||||
"NewChan",
|
"NewChan",
|
||||||
"NewChecker",
|
"NewChecker",
|
||||||
|
@ -3627,6 +3646,7 @@ var stdlib = map[string][]string{
|
||||||
"Uint64",
|
"Uint64",
|
||||||
"Uint8",
|
"Uint8",
|
||||||
"Uintptr",
|
"Uintptr",
|
||||||
|
"Unalias",
|
||||||
"Union",
|
"Union",
|
||||||
"Universe",
|
"Universe",
|
||||||
"Unsafe",
|
"Unsafe",
|
||||||
|
@ -3643,6 +3663,11 @@ var stdlib = map[string][]string{
|
||||||
"WriteSignature",
|
"WriteSignature",
|
||||||
"WriteType",
|
"WriteType",
|
||||||
},
|
},
|
||||||
|
"go/version": {
|
||||||
|
"Compare",
|
||||||
|
"IsValid",
|
||||||
|
"Lang",
|
||||||
|
},
|
||||||
"hash": {
|
"hash": {
|
||||||
"Hash",
|
"Hash",
|
||||||
"Hash32",
|
"Hash32",
|
||||||
|
@ -4078,6 +4103,7 @@ var stdlib = map[string][]string{
|
||||||
"NewTextHandler",
|
"NewTextHandler",
|
||||||
"Record",
|
"Record",
|
||||||
"SetDefault",
|
"SetDefault",
|
||||||
|
"SetLogLoggerLevel",
|
||||||
"Source",
|
"Source",
|
||||||
"SourceKey",
|
"SourceKey",
|
||||||
"String",
|
"String",
|
||||||
|
@ -4367,6 +4393,35 @@ var stdlib = map[string][]string{
|
||||||
"Uint64",
|
"Uint64",
|
||||||
"Zipf",
|
"Zipf",
|
||||||
},
|
},
|
||||||
|
"math/rand/v2": {
|
||||||
|
"ChaCha8",
|
||||||
|
"ExpFloat64",
|
||||||
|
"Float32",
|
||||||
|
"Float64",
|
||||||
|
"Int",
|
||||||
|
"Int32",
|
||||||
|
"Int32N",
|
||||||
|
"Int64",
|
||||||
|
"Int64N",
|
||||||
|
"IntN",
|
||||||
|
"N",
|
||||||
|
"New",
|
||||||
|
"NewChaCha8",
|
||||||
|
"NewPCG",
|
||||||
|
"NewZipf",
|
||||||
|
"NormFloat64",
|
||||||
|
"PCG",
|
||||||
|
"Perm",
|
||||||
|
"Rand",
|
||||||
|
"Shuffle",
|
||||||
|
"Source",
|
||||||
|
"Uint32",
|
||||||
|
"Uint32N",
|
||||||
|
"Uint64",
|
||||||
|
"Uint64N",
|
||||||
|
"UintN",
|
||||||
|
"Zipf",
|
||||||
|
},
|
||||||
"mime": {
|
"mime": {
|
||||||
"AddExtensionType",
|
"AddExtensionType",
|
||||||
"BEncoding",
|
"BEncoding",
|
||||||
|
@ -4540,6 +4595,7 @@ var stdlib = map[string][]string{
|
||||||
"FS",
|
"FS",
|
||||||
"File",
|
"File",
|
||||||
"FileServer",
|
"FileServer",
|
||||||
|
"FileServerFS",
|
||||||
"FileSystem",
|
"FileSystem",
|
||||||
"Flusher",
|
"Flusher",
|
||||||
"Get",
|
"Get",
|
||||||
|
@ -4566,6 +4622,7 @@ var stdlib = map[string][]string{
|
||||||
"MethodPut",
|
"MethodPut",
|
||||||
"MethodTrace",
|
"MethodTrace",
|
||||||
"NewFileTransport",
|
"NewFileTransport",
|
||||||
|
"NewFileTransportFS",
|
||||||
"NewRequest",
|
"NewRequest",
|
||||||
"NewRequestWithContext",
|
"NewRequestWithContext",
|
||||||
"NewResponseController",
|
"NewResponseController",
|
||||||
|
@ -4599,6 +4656,7 @@ var stdlib = map[string][]string{
|
||||||
"Serve",
|
"Serve",
|
||||||
"ServeContent",
|
"ServeContent",
|
||||||
"ServeFile",
|
"ServeFile",
|
||||||
|
"ServeFileFS",
|
||||||
"ServeMux",
|
"ServeMux",
|
||||||
"ServeTLS",
|
"ServeTLS",
|
||||||
"Server",
|
"Server",
|
||||||
|
@ -5106,6 +5164,7 @@ var stdlib = map[string][]string{
|
||||||
"StructTag",
|
"StructTag",
|
||||||
"Swapper",
|
"Swapper",
|
||||||
"Type",
|
"Type",
|
||||||
|
"TypeFor",
|
||||||
"TypeOf",
|
"TypeOf",
|
||||||
"Uint",
|
"Uint",
|
||||||
"Uint16",
|
"Uint16",
|
||||||
|
@ -5342,6 +5401,7 @@ var stdlib = map[string][]string{
|
||||||
"CompactFunc",
|
"CompactFunc",
|
||||||
"Compare",
|
"Compare",
|
||||||
"CompareFunc",
|
"CompareFunc",
|
||||||
|
"Concat",
|
||||||
"Contains",
|
"Contains",
|
||||||
"ContainsFunc",
|
"ContainsFunc",
|
||||||
"Delete",
|
"Delete",
|
||||||
|
@ -10824,6 +10884,7 @@ var stdlib = map[string][]string{
|
||||||
"Value",
|
"Value",
|
||||||
},
|
},
|
||||||
"testing/slogtest": {
|
"testing/slogtest": {
|
||||||
|
"Run",
|
||||||
"TestHandler",
|
"TestHandler",
|
||||||
},
|
},
|
||||||
"text/scanner": {
|
"text/scanner": {
|
||||||
|
|
|
@ -56,16 +56,16 @@ github.com/vbatts/git-validation/rules/dco
|
||||||
github.com/vbatts/git-validation/rules/messageregexp
|
github.com/vbatts/git-validation/rules/messageregexp
|
||||||
github.com/vbatts/git-validation/rules/shortsubject
|
github.com/vbatts/git-validation/rules/shortsubject
|
||||||
github.com/vbatts/git-validation/validate
|
github.com/vbatts/git-validation/validate
|
||||||
# golang.org/x/mod v0.14.0
|
# golang.org/x/mod v0.15.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/mod/internal/lazyregexp
|
golang.org/x/mod/internal/lazyregexp
|
||||||
golang.org/x/mod/module
|
golang.org/x/mod/module
|
||||||
golang.org/x/mod/semver
|
golang.org/x/mod/semver
|
||||||
# golang.org/x/sys v0.15.0
|
# golang.org/x/sys v0.17.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/sys/unix
|
golang.org/x/sys/unix
|
||||||
golang.org/x/sys/windows
|
golang.org/x/sys/windows
|
||||||
# golang.org/x/tools v0.17.0
|
# golang.org/x/tools v0.18.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
golang.org/x/tools/cmd/goimports
|
golang.org/x/tools/cmd/goimports
|
||||||
golang.org/x/tools/go/ast/astutil
|
golang.org/x/tools/go/ast/astutil
|
||||||
|
|
Loading…
Reference in New Issue