{"id":13412792,"url":"https://github.com/otiai10/copy","last_synced_at":"2025-05-14T04:07:27.610Z","repository":{"id":24621440,"uuid":"102069185","full_name":"otiai10/copy","owner":"otiai10","description":"Go copy directory recursively","archived":false,"fork":false,"pushed_at":"2025-01-05T09:31:15.000Z","size":230,"stargazers_count":754,"open_issues_count":20,"forks_count":115,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-05-14T02:18:37.307Z","etag":null,"topics":["copy","directories","directory","files","folder","folders","go","golang","recursive"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/otiai10/copy","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/otiai10.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["otiai10"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2017-09-01T03:18:56.000Z","updated_at":"2025-05-06T05:27:27.000Z","dependencies_parsed_at":"2024-02-08T01:43:47.840Z","dependency_job_id":"1f24ed71-d09c-4578-b039-79a60e195445","html_url":"https://github.com/otiai10/copy","commit_stats":{"total_commits":218,"total_committers":35,"mean_commits":6.228571428571429,"dds":"0.45871559633027525","last_synced_commit":"49b0b590f1e1dce6302b9015a46ea0de5d93c78f"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Fcopy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Fcopy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Fcopy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/otiai10%2Fcopy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/otiai10","download_url":"https://codeload.github.com/otiai10/copy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254069476,"owners_count":22009557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["copy","directories","directory","files","folder","folders","go","golang","recursive"],"created_at":"2024-07-30T20:01:29.257Z","updated_at":"2025-05-14T04:07:27.562Z","avatar_url":"https://github.com/otiai10.png","language":"Go","funding_links":["https://github.com/sponsors/otiai10"],"categories":["开源类库","Go","File Handling","Open source library","文件处理","Files","Relational Databases","文件处理`处理文件和文件系统操作的库`"],"sub_categories":["文件/存储","Search and Analytic Databases","Files/Storage","Advanced Console UIs","检索及分析资料库","SQL 查询语句构建库"],"readme":"# copy\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/otiai10/copy.svg)](https://pkg.go.dev/github.com/otiai10/copy)\n[![Actions Status](https://github.com/otiai10/copy/workflows/Go/badge.svg)](https://github.com/otiai10/copy/actions)\n[![codecov](https://codecov.io/gh/otiai10/copy/branch/main/graph/badge.svg)](https://codecov.io/gh/otiai10/copy)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/otiai10/copy/blob/main/LICENSE)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fotiai10%2Fcopy.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fotiai10%2Fcopy?ref=badge_shield)\n[![CodeQL](https://github.com/otiai10/copy/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/codeql-analysis.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/otiai10/copy)](https://goreportcard.com/report/github.com/otiai10/copy)\n[![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/otiai10/copy?sort=semver)](https://pkg.go.dev/github.com/otiai10/copy)\n[![Docker Test](https://github.com/otiai10/copy/actions/workflows/docker-test.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/docker-test.yml)\n[![Vagrant Test](https://github.com/otiai10/copy/actions/workflows/vagrant-test.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/vagrant-test.yml)\n[![GopherJS](https://github.com/otiai10/copy/actions/workflows/gopherjs.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/gopherjs.yml)\n[![Go WASM](https://github.com/otiai10/copy/actions/workflows/wasm.yml/badge.svg)](https://github.com/otiai10/copy/actions/workflows/wasm.yml)\n\n`copy` copies directories recursively.\n\n# Example Usage\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\tcp \"github.com/otiai10/copy\"\n)\n\nfunc main() {\n\terr := cp.Copy(\"your/src\", \"your/dest\")\n\tfmt.Println(err) // nil\n}\n```\n\n# Advanced Usage\n\n```go\n// Options specifies optional actions on copying.\ntype Options struct {\n\n\t// OnSymlink can specify what to do on symlink\n\tOnSymlink func(src string) SymlinkAction\n\n\t// OnDirExists can specify what to do when there is a directory already existing in destination.\n\tOnDirExists func(src, dest string) DirExistsAction\n\n\t// OnError can let users decide how to handle errors (e.g., you can suppress specific error).\n\tOnError func(src, dest, string, err error) error\n\n\t// Skip can specify which files should be skipped\n\tSkip func(srcinfo os.FileInfo, src, dest string) (bool, error)\n\n\t// RenameDestination can rename destination.\n\t// If not set, nil, it does nothing.\n\tRenameDestination func(src, dest string) (string, error)\n\n\t// PermissionControl can control permission of\n\t// every entry.\n\t// When you want to add permission 0222, do like\n\t//\n\t//\t\tPermissionControl = AddPermission(0222)\n\t//\n\t// or if you even don't want to touch permission,\n\t//\n\t//\t\tPermissionControl = DoNothing\n\t//\n\t// By default, PermissionControl = PreservePermission\n\tPermissionControl PermissionControlFunc\n\n\t// Sync file after copy.\n\t// Useful in case when file must be on the disk\n\t// (in case crash happens, for example),\n\t// at the expense of some performance penalty\n\tSync bool\n\n\t// Preserve the atime and the mtime of the entries\n\t// On linux we can preserve only up to 1 millisecond accuracy\n\tPreserveTimes bool\n\n\t// Preserve the uid and the gid of all entries.\n\tPreserveOwner bool\n\n\t// The byte size of the buffer to use for copying files.\n\t// If zero, the internal default buffer of 32KB is used.\n\t// See https://golang.org/pkg/io/#CopyBuffer for more information.\n\tCopyBufferSize uint\n\n\t// If you want to add some limitation on reading src file,\n\t// you can wrap the src and provide new reader,\n\t// such as `RateLimitReader` in the test case.\n\tWrapReader func(src io.Reader) io.Reader\n\n\t// If given, copy.Copy refers to this fs.FS instead of the OS filesystem.\n\t// e.g., You can use embed.FS to copy files from embedded filesystem.\n\tFS fs.FS\n\n\t// NumOfWorkers represents the number of workers used for\n\t// concurrent copying contents of directories.\n\t// If 0 or 1, it does not use goroutine for copying directories.\n\t// Please refer to https://pkg.go.dev/golang.org/x/sync/semaphore for more details.\n\tNumOfWorkers int64\n\n\t// PreferConcurrent is a function to determine whether or not\n\t// to use goroutine for copying contents of directories.\n\t// If PreferConcurrent is nil, which is default, it does concurrent\n\t// copying for all directories.\n\t// If NumOfWorkers is 0 or 1, this function will be ignored.\n\tPreferConcurrent func(srcdir, destdir string) (bool, error)\n}\n```\n\n```go\n// For example...\nopt := Options{\n\tSkip: func(info os.FileInfo, src, dest string) (bool, error) {\n\t\treturn strings.HasSuffix(src, \".git\"), nil\n\t},\n}\nerr := Copy(\"your/directory\", \"your/directory.copy\", opt)\n```\n\n# Issues\n\n- https://github.com/otiai10/copy/issues\n\n\n## License\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fotiai10%2Fcopy.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fotiai10%2Fcopy?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fotiai10%2Fcopy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fotiai10%2Fcopy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fotiai10%2Fcopy/lists"}