本文整理汇总了Golang中github.com/hanwen/go-fuse/internal/testutil.TempDir函数的典型用法代码示例。如果您正苦于以下问题:Golang TempDir函数的具体用法?Golang TempDir怎么用?Golang TempDir使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了TempDir函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: setupFAttrTest
func setupFAttrTest(t *testing.T, fs pathfs.FileSystem) (dir string, clean func()) {
dir = testutil.TempDir()
nfs := pathfs.NewPathNodeFs(fs, nil)
opts := nodefs.NewOptions()
opts.Debug = testutil.VerboseTest()
state, _, err := nodefs.MountRoot(dir, nfs.Root(), opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go state.Serve()
if err := state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
clean = func() {
if err := state.Unmount(); err != nil {
t.Errorf("cleanup: Unmount: %v", err)
} else {
os.RemoveAll(dir)
}
}
if state.KernelSettings().Flags&fuse.CAP_FILE_OPS == 0 {
clean()
t.Skip("Mount does not support file operations")
}
return dir, clean
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:31,代码来源:fsetattr_test.go
示例2: NewNotifyTest
func NewNotifyTest(t *testing.T) *NotifyTest {
me := &NotifyTest{}
me.fs = newNotifyFs()
me.dir = testutil.TempDir()
entryTtl := 100 * time.Millisecond
opts := &nodefs.Options{
EntryTimeout: entryTtl,
AttrTimeout: entryTtl,
NegativeTimeout: entryTtl,
Debug: testutil.VerboseTest(),
}
me.pathfs = pathfs.NewPathNodeFs(me.fs, nil)
var err error
me.state, me.connector, err = nodefs.MountRoot(me.dir, me.pathfs.Root(), opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go me.state.Serve()
if err := me.state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
return me
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:25,代码来源:notify_linux_test.go
示例3: TestOriginalIsSymlink
func TestOriginalIsSymlink(t *testing.T) {
tmpDir := testutil.TempDir()
defer os.RemoveAll(tmpDir)
orig := tmpDir + "/orig"
err := os.Mkdir(orig, 0755)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
link := tmpDir + "/link"
mnt := tmpDir + "/mnt"
if err := os.Mkdir(mnt, 0755); err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
if err := os.Symlink("orig", link); err != nil {
t.Fatalf("Symlink failed: %v", err)
}
fs := pathfs.NewLoopbackFileSystem(link)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := nodefs.MountRoot(mnt, nfs.Root(), nil)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
defer state.Unmount()
go state.Serve()
if err := state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
if _, err := os.Lstat(mnt); err != nil {
t.Fatalf("Lstat failed: %v", err)
}
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:34,代码来源:loopback_test.go
示例4: setupCacheTest
func setupCacheTest(t *testing.T) (string, *pathfs.PathNodeFs, func()) {
dir := testutil.TempDir()
os.Mkdir(dir+"/mnt", 0755)
os.Mkdir(dir+"/orig", 0755)
fs := &cacheFs{
pathfs.NewLoopbackFileSystem(dir + "/orig"),
}
pfs := pathfs.NewPathNodeFs(fs, &pathfs.PathNodeFsOptions{Debug: testutil.VerboseTest()})
opts := nodefs.NewOptions()
opts.Debug = testutil.VerboseTest()
state, _, err := nodefs.MountRoot(dir+"/mnt", pfs.Root(), opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go state.Serve()
if err := state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
return dir, pfs, func() {
err := state.Unmount()
if err == nil {
os.RemoveAll(dir)
}
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:27,代码来源:cache_test.go
示例5: TestDefaultXAttr
func TestDefaultXAttr(t *testing.T) {
dir := testutil.TempDir()
defer os.RemoveAll(dir)
root := &xattrNode{
Node: nodefs.NewDefaultNode(),
}
opts := nodefs.NewOptions()
opts.Debug = testutil.VerboseTest()
s, _, err := nodefs.MountRoot(dir, root, opts)
if err != nil {
t.Fatalf("MountRoot: %v", err)
}
go s.Serve()
if err := s.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
defer s.Unmount()
var data [1024]byte
sz, err := syscall.Getxattr(filepath.Join(dir, "child"), "attr", data[:])
if err != nil {
t.Fatalf("Getxattr: %v", err)
} else if val := string(data[:sz]); val != "value" {
t.Fatalf("got %v, want 'value'", val)
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:29,代码来源:xattr_test.go
示例6: TestLiveness
func TestLiveness(t *testing.T) {
dir := testutil.TempDir()
defer os.RemoveAll(dir)
root := nodefs.NewDefaultNode()
s, _, err := nodefs.MountRoot(dir, root, nil)
if err != nil {
t.Fatalf("MountRoot: %v", err)
}
go s.Serve()
if err := s.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
defer s.Unmount()
if _, err := ioutil.ReadDir(dir); err != nil {
t.Fatalf("ReadDir: %v", err)
}
// We previously encountered a sitation where a finalizer would close our fd out from under us. Try to force both finalizers to run and object destruction to complete.
runtime.GC()
runtime.GC()
if _, err := ioutil.ReadDir(dir); err != nil {
t.Fatalf("ReadDir: %v", err)
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:26,代码来源:mount_test.go
示例7: TestNonseekable
func TestNonseekable(t *testing.T) {
fs := &nonseekFs{FileSystem: pathfs.NewDefaultFileSystem()}
fs.Length = 200 * 1024
dir := testutil.TempDir()
defer os.RemoveAll(dir)
nfs := pathfs.NewPathNodeFs(fs, nil)
opts := nodefs.NewOptions()
opts.Debug = testutil.VerboseTest()
state, _, err := nodefs.MountRoot(dir, nfs.Root(), opts)
if err != nil {
t.Fatalf("failed: %v", err)
}
defer state.Unmount()
go state.Serve()
if err := state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
f, err := os.Open(dir + "/file")
if err != nil {
t.Fatalf("failed: %v", err)
}
defer f.Close()
b := make([]byte, 200)
n, err := f.ReadAt(b, 20)
if err == nil || n > 0 {
t.Errorf("file was opened nonseekable, but seek successful")
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:32,代码来源:cache_test.go
示例8: TestDefaultNodeMount
func TestDefaultNodeMount(t *testing.T) {
dir := testutil.TempDir()
defer os.RemoveAll(dir)
root := nodefs.NewDefaultNode()
s, conn, err := nodefs.MountRoot(dir, root, nil)
if err != nil {
t.Fatalf("MountRoot: %v", err)
}
go s.Serve()
if err := s.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
defer s.Unmount()
if err := conn.Mount(root.Inode(), "sub", nodefs.NewDefaultNode(), nil); !err.Ok() {
t.Fatalf("Mount: %v", err)
}
if entries, err := ioutil.ReadDir(dir); err != nil {
t.Fatalf("ReadDir: %v", err)
} else if len(entries) != 1 {
t.Fatalf("got %d entries", len(entries))
} else if entries[0].Name() != "sub" {
t.Fatalf("got %q, want %q", entries[0].Name(), "sub")
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:26,代码来源:mount_test.go
示例9: setup
func setup(t *testing.T) (workdir string, server *fuse.Server, cleanup func()) {
wd := testutil.TempDir()
err := os.Mkdir(wd+"/mnt", 0700)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
err = os.Mkdir(wd+"/store", 0700)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
os.Mkdir(wd+"/ro", 0700)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
WriteFile(t, wd+"/ro/file1", "file1")
WriteFile(t, wd+"/ro/file2", "file2")
fs := NewAutoUnionFs(wd+"/store", testAOpts)
nfs := pathfs.NewPathNodeFs(fs, nil)
state, _, err := nodefs.MountRoot(wd+"/mnt", nfs.Root(), &testAOpts.Options)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go state.Serve()
state.WaitMount()
return wd, state, func() {
state.Unmount()
os.RemoveAll(wd)
}
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:34,代码来源:autounion_test.go
示例10: defaultReadTest
func defaultReadTest(t *testing.T) (root string, cleanup func()) {
fs := &DefaultReadFS{
FileSystem: pathfs.NewDefaultFileSystem(),
size: 22,
}
var err error
dir := testutil.TempDir()
pathfs := pathfs.NewPathNodeFs(fs, nil)
opts := nodefs.NewOptions()
opts.Debug = testutil.VerboseTest()
state, _, err := nodefs.MountRoot(dir, pathfs.Root(), opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go state.Serve()
if err := state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
return dir, func() {
state.Unmount()
os.Remove(dir)
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:25,代码来源:defaultread_test.go
示例11: BenchmarkCFuseThreadedStat
func BenchmarkCFuseThreadedStat(b *testing.B) {
b.StopTimer()
wd, _ := os.Getwd()
fileList := wd + "/testpaths.txt"
lines := ReadLines(fileList)
unique := map[string]int{}
for _, l := range lines {
unique[l] = 1
dir, _ := filepath.Split(l)
for dir != "/" && dir != "" {
unique[dir] = 1
dir = filepath.Clean(dir)
dir, _ = filepath.Split(dir)
}
}
out := []string{}
for k := range unique {
out = append(out, k)
}
f, err := ioutil.TempFile("", "")
if err != nil {
b.Fatalf("failed: %v", err)
}
sort.Strings(out)
for _, k := range out {
f.Write([]byte(fmt.Sprintf("/%s\n", k)))
}
f.Close()
mountPoint := testutil.TempDir()
cmd := exec.Command(wd+"/cstatfs",
"-o",
"entry_timeout=0.0,attr_timeout=0.0,ac_attr_timeout=0.0,negative_timeout=0.0",
mountPoint)
cmd.Env = append(os.Environ(),
fmt.Sprintf("STATFS_INPUT=%s", f.Name()))
cmd.Start()
bin, err := exec.LookPath("fusermount")
if err != nil {
b.Fatalf("failed: %v", err)
}
stop := exec.Command(bin, "-u", mountPoint)
if err != nil {
b.Fatalf("failed: %v", err)
}
defer stop.Run()
time.Sleep(100 * time.Millisecond)
os.Lstat(mountPoint)
threads := runtime.GOMAXPROCS(0)
if err := TestingBOnePass(b, threads, fileList, mountPoint); err != nil {
log.Fatalf("TestingBOnePass %v", err)
}
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:58,代码来源:stat_test.go
示例12: setupUfs
// Creates a temporary dir "wd" with 3 directories:
// mnt ... overlayed (unionfs) mount
// rw .... modifiable data
// ro .... read-only data
func setupUfs(t *testing.T) (wd string, cleanup func()) {
// Make sure system setting does not affect test.
syscall.Umask(0)
wd = testutil.TempDir()
err := os.Mkdir(wd+"/mnt", 0700)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
err = os.Mkdir(wd+"/rw", 0700)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
os.Mkdir(wd+"/ro", 0700)
if err != nil {
t.Fatalf("Mkdir failed: %v", err)
}
var fses []pathfs.FileSystem
fses = append(fses, pathfs.NewLoopbackFileSystem(wd+"/rw"))
fses = append(fses,
NewCachingFileSystem(pathfs.NewLoopbackFileSystem(wd+"/ro"), 0))
ufs, err := NewUnionFs(fses, testOpts)
if err != nil {
t.Fatalf("NewUnionFs: %v", err)
}
// We configure timeouts are smaller, so we can check for
// UnionFs's cache consistency.
opts := &nodefs.Options{
EntryTimeout: entryTtl / 2,
AttrTimeout: entryTtl / 2,
NegativeTimeout: entryTtl / 2,
PortableInodes: true,
Debug: testutil.VerboseTest(),
}
pathfs := pathfs.NewPathNodeFs(ufs,
&pathfs.PathNodeFsOptions{ClientInodes: true,
Debug: opts.Debug,
})
state, _, err := nodefs.MountRoot(wd+"/mnt", pathfs.Root(), opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go state.Serve()
state.WaitMount()
return wd, func() {
err := state.Unmount()
if err != nil {
return
}
setRecursiveWritable(t, wd, true)
os.RemoveAll(wd)
}
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:62,代码来源:unionfs_test.go
示例13: TestCopyFile
func TestCopyFile(t *testing.T) {
d1 := testutil.TempDir()
defer os.RemoveAll(d1)
d2 := testutil.TempDir()
defer os.RemoveAll(d2)
fs1 := NewLoopbackFileSystem(d1)
fs2 := NewLoopbackFileSystem(d2)
content1 := "blabla"
err := ioutil.WriteFile(d1+"/file", []byte(content1), 0644)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
code := CopyFile(fs1, fs2, "file", "file", nil)
if !code.Ok() {
t.Fatal("Unexpected ret code", code)
}
data, err := ioutil.ReadFile(d2 + "/file")
if content1 != string(data) {
t.Fatal("Unexpected content", string(data))
}
content2 := "foobar"
err = ioutil.WriteFile(d2+"/file", []byte(content2), 0644)
if err != nil {
t.Fatalf("WriteFile failed: %v", err)
}
// Copy back: should overwrite.
code = CopyFile(fs2, fs1, "file", "file", nil)
if !code.Ok() {
t.Fatal("Unexpected ret code", code)
}
data, err = ioutil.ReadFile(d1 + "/file")
if content2 != string(data) {
t.Fatal("Unexpected content", string(data))
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:45,代码来源:copy_test.go
示例14: TestDefaultNodeGetAttr
func TestDefaultNodeGetAttr(t *testing.T) {
dir := testutil.TempDir()
defer os.RemoveAll(dir)
opts := &nodefs.Options{
// Note: defaultNode.GetAttr() calling file.GetAttr() is only useful if
// AttrTimeout is zero.
// See https://github.com/JonathonReinhart/gitlab-fuse/issues/2
Owner: fuse.CurrentOwner(),
}
root := nodefs.NewDefaultNode()
s, _, err := nodefs.MountRoot(dir, root, opts)
if err != nil {
t.Fatalf("MountRoot: %v", err)
}
go s.Serve()
if err := s.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
defer s.Unmount()
// Attach another custom node type
root.Inode().NewChild("foo", false, &myNode{
Node: nodefs.NewDefaultNode(),
content: []byte("success"),
})
filepath := path.Join(dir, "foo")
// NewDefaultNode() should provide for stat that indicates 0-byte regular file
fi, err := os.Stat(filepath)
if err != nil {
t.Fatalf("Stat: %v", err)
}
if mode := (fi.Mode() & os.ModeType); mode != 0 {
// Mode() & ModeType should be zero for regular files
t.Fatalf("Unexpected mode: %#o", mode)
}
if size := fi.Size(); size != 0 {
t.Fatalf("Unexpected size: %d", size)
}
// But when we open the file, we should get the content
content, err := ioutil.ReadFile(filepath)
if err != nil {
t.Fatalf("ReadFile: %v", err)
}
if string(content) != "success" {
t.Fatalf("Unexpected content: %v", content)
}
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:52,代码来源:defaultnode_test.go
示例15: NewTestCase
// Create and mount filesystem.
func NewTestCase(t *testing.T) *testCase {
tc := &testCase{}
tc.tester = t
// Make sure system setting does not affect test.
syscall.Umask(0)
const name string = "hello.txt"
const subdir string = "subdir"
var err error
tc.tmpDir = testutil.TempDir()
tc.orig = tc.tmpDir + "/orig"
tc.mnt = tc.tmpDir + "/mnt"
tc.Mkdir(tc.orig, 0700)
tc.Mkdir(tc.mnt, 0700)
tc.mountFile = filepath.Join(tc.mnt, name)
tc.mountSubdir = filepath.Join(tc.mnt, subdir)
tc.origFile = filepath.Join(tc.orig, name)
tc.origSubdir = filepath.Join(tc.orig, subdir)
var pfs pathfs.FileSystem
pfs = pathfs.NewLoopbackFileSystem(tc.orig)
pfs = pathfs.NewLockingFileSystem(pfs)
tc.pathFs = pathfs.NewPathNodeFs(pfs, &pathfs.PathNodeFsOptions{
ClientInodes: true})
tc.connector = nodefs.NewFileSystemConnector(tc.pathFs.Root(),
&nodefs.Options{
EntryTimeout: testTtl,
AttrTimeout: testTtl,
NegativeTimeout: 0.0,
Debug: testutil.VerboseTest(),
})
tc.state, err = fuse.NewServer(
fuse.NewRawFileSystem(tc.connector.RawFS()), tc.mnt, &fuse.MountOptions{
SingleThreaded: true,
Debug: testutil.VerboseTest(),
})
if err != nil {
t.Fatal("NewServer:", err)
}
go tc.state.Serve()
if err := tc.state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
return tc
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:52,代码来源:loopback_test.go
示例16: xattrTestCase
func xattrTestCase(t *testing.T, nm string, m map[string][]byte) (mountPoint string, cleanup func()) {
xfs := NewXAttrFs(nm, m)
mountPoint = testutil.TempDir()
nfs := NewPathNodeFs(xfs, nil)
state, _, err := nodefs.MountRoot(mountPoint, nfs.Root(),
&nodefs.Options{Debug: VerboseTest()})
if err != nil {
t.Fatalf("MountRoot failed: %v", err)
}
go state.Serve()
return mountPoint, func() {
state.Unmount()
os.RemoveAll(mountPoint)
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:17,代码来源:xattr_test.go
示例17: TestGetAttrRace
func TestGetAttrRace(t *testing.T) {
dir := testutil.TempDir()
defer os.RemoveAll(dir)
os.Mkdir(dir+"/mnt", 0755)
os.Mkdir(dir+"/orig", 0755)
fs := pathfs.NewLoopbackFileSystem(dir + "/orig")
pfs := pathfs.NewPathNodeFs(fs, &pathfs.PathNodeFsOptions{Debug: testutil.VerboseTest()})
state, _, err := nodefs.MountRoot(dir+"/mnt", pfs.Root(),
&nodefs.Options{Debug: testutil.VerboseTest()})
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go state.Serve()
if err := state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
defer state.Unmount()
var wg sync.WaitGroup
n := 100
wg.Add(n)
var statErr error
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
fn := dir + "/mnt/file"
err := ioutil.WriteFile(fn, []byte{42}, 0644)
if err != nil {
statErr = err
return
}
_, err = os.Lstat(fn)
if err != nil {
statErr = err
}
}()
}
wg.Wait()
if statErr != nil {
t.Error(statErr)
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:45,代码来源:cache_test.go
示例18: setupOwnerTest
func setupOwnerTest(t *testing.T, opts *nodefs.Options) (workdir string, cleanup func()) {
wd := testutil.TempDir()
fs := &ownerFs{NewDefaultFileSystem()}
nfs := NewPathNodeFs(fs, nil)
state, _, err := nodefs.MountRoot(wd, nfs.Root(), opts)
if err != nil {
t.Fatalf("MountNodeFileSystem failed: %v", err)
}
go state.Serve()
if err := state.WaitMount(); err != nil {
t.Fatal("WaitMount", err)
}
return wd, func() {
state.Unmount()
os.RemoveAll(wd)
}
}
开发者ID:jszwedko,项目名称:ec2-metadatafs,代码行数:18,代码来源:owner_test.go
示例19: setupZipfs
func setupZipfs(t *testing.T) (mountPoint string, cleanup func()) {
root, err := NewArchiveFileSystem(testZipFile())
if err != nil {
t.Fatalf("NewArchiveFileSystem failed: %v", err)
}
mountPoint = testutil.TempDir()
state, _, err := nodefs.MountRoot(mountPoint, root, &nodefs.Options{
Debug: testutil.VerboseTest(),
})
go state.Serve()
state.WaitMount()
return mountPoint, func() {
state.Unmount()
os.RemoveAll(mountPoint)
}
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:19,代码来源:zipfs_test.go
示例20: TestCachingFs
func TestCachingFs(t *testing.T) {
wd := testutil.TempDir()
defer os.RemoveAll(wd)
fs := pathfs.NewLoopbackFileSystem(wd)
cfs := NewCachingFileSystem(fs, 0)
os.Mkdir(wd+"/orig", 0755)
fi, code := cfs.GetAttr("orig", nil)
if !code.Ok() {
t.Fatal("GetAttr failure", code)
}
if !fi.IsDir() {
t.Error("unexpected attr", fi)
}
os.Symlink("orig", wd+"/symlink")
val, code := cfs.Readlink("symlink", nil)
if val != "orig" {
t.Error("unexpected readlink", val)
}
if !code.Ok() {
t.Error("code !ok ", code)
}
stream, code := cfs.OpenDir("", nil)
if !code.Ok() {
t.Fatal("Readdir fail", code)
}
results := make(map[string]uint32)
for _, v := range stream {
results[v.Name] = v.Mode &^ 07777
}
expected := map[string]uint32{
"symlink": syscall.S_IFLNK,
"orig": fuse.S_IFDIR,
}
if !modeMapEq(results, expected) {
t.Error("Unexpected readdir result", results, expected)
}
}
开发者ID:rfjakob,项目名称:go-fuse,代码行数:43,代码来源:cachingfs_test.go
注:本文中的github.com/hanwen/go-fuse/internal/testutil.TempDir函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论