{"id":13493527,"url":"https://github.com/jinzhu/copier","last_synced_at":"2025-09-09T20:56:48.563Z","repository":{"id":11525354,"uuid":"14008364","full_name":"jinzhu/copier","owner":"jinzhu","description":"Copier for golang, copy value from struct to struct and more","archived":false,"fork":false,"pushed_at":"2025-08-12T02:07:42.000Z","size":131,"stargazers_count":6003,"open_issues_count":75,"forks_count":495,"subscribers_count":54,"default_branch":"master","last_synced_at":"2025-09-08T19:34:22.255Z","etag":null,"topics":["copy","go","golang","golang-package"],"latest_commit_sha":null,"homepage":null,"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/jinzhu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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":["jinzhu"],"patreon":"jinzhu","open_collective":"gorm"}},"created_at":"2013-10-31T05:24:36.000Z","updated_at":"2025-09-08T10:15:05.000Z","dependencies_parsed_at":"2024-06-18T10:50:28.846Z","dependency_job_id":"8c284642-a985-4884-976f-c50dfe9948ce","html_url":"https://github.com/jinzhu/copier","commit_stats":{"total_commits":118,"total_committers":41,"mean_commits":"2.8780487804878048","dds":0.6694915254237288,"last_synced_commit":"60a1fd2bfc60689794eb2afa1bbce6faea45ffe9"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/jinzhu/copier","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzhu%2Fcopier","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzhu%2Fcopier/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzhu%2Fcopier/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzhu%2Fcopier/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jinzhu","download_url":"https://codeload.github.com/jinzhu/copier/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jinzhu%2Fcopier/sbom","scorecard":{"id":521461,"data":{"date":"2025-08-11","repo":{"name":"github.com/jinzhu/copier","commit":"23419d716847e2109305fe194ce5439061c3bc83"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.6,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":2,"reason":"3 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/jinzhu/copier/tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/jinzhu/copier/tests.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: License:0","Info: FSF or OSI recognized license: MIT License: License:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T03:07:28.832Z","repository_id":11525354,"created_at":"2025-08-20T03:07:28.832Z","updated_at":"2025-08-20T03:07:28.832Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274357333,"owners_count":25270673,"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","status":"online","status_checked_at":"2025-09-09T02:00:10.223Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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","go","golang","golang-package"],"created_at":"2024-07-31T19:01:16.162Z","updated_at":"2025-09-09T20:56:48.540Z","avatar_url":"https://github.com/jinzhu.png","language":"Go","funding_links":["https://github.com/sponsors/jinzhu","https://patreon.com/jinzhu","https://opencollective.com/gorm"],"categories":["Misc","开源类库","Go","Data Structures","Open source library","Repositories","Golang"],"sub_categories":["开发辅助包","Development Aid Package"],"readme":"# Copier\n\nI am a copier, I copy everything from one to another\n\n[![test status](https://github.com/jinzhu/copier/workflows/tests/badge.svg?branch=master \"test status\")](https://github.com/jinzhu/copier/actions)\n\n## Key Features\n\n- Field-to-field and method-to-field copying based on matching names\n- Support for copying data:\n  - From slice to slice\n  - From struct to slice\n  - From map to map\n- Field manipulation through tags:\n  - Enforce field copying with `copier:\"must\"`\n  - Override fields even when `IgnoreEmpty` is set with `copier:\"override\"`\n  - Exclude fields from being copied with `copier:\"-\"`\n\n## Getting Started\n\n### Installation\n\nTo start using Copier, install Go and run go get:\n\n```bash\ngo get -u github.com/jinzhu/copier\n```\n\n## Basic\n\nImport Copier into your application to access its copying capabilities\n\n```go\nimport \"github.com/jinzhu/copier\"\n```\n\n### Basic Copying\n\n```go\ntype User struct {\n\tName string\n\tRole string\n\tAge  int32\n}\n\nfunc (user *User) DoubleAge() int32 {\n\treturn 2 * user.Age\n}\n\ntype Employee struct {\n\tName      string\n\tAge       int32\n\tDoubleAge int32\n\tSuperRole string\n}\n\nfunc (employee *Employee) Role(role string) {\n\temployee.SuperRole = \"Super \" + role\n}\n\nfunc main() {\n\tuser := User{Name: \"Jinzhu\", Age: 18, Role: \"Admin\"}\n\temployee := Employee{}\n\n\tcopier.Copy(\u0026employee, \u0026user)\n\tfmt.Printf(\"%#v\\n\", employee)\n\t// Output: Employee{Name:\"Jinzhu\", Age:18, DoubleAge:36, SuperRole:\"Super Admin\"}\n}\n```\n\n## Tag Usage Examples\n\n### `copier:\"-\"` - Ignoring Fields\n\nFields tagged with `copier:\"-\"` are explicitly ignored by Copier during the copying process.\n\n```go\ntype Source struct {\n    Name   string\n    Secret string // We do not want this to be copied.\n}\n\ntype Target struct {\n    Name   string\n    Secret string `copier:\"-\"`\n}\n\nfunc main() {\n    source := Source{Name: \"John\", Secret: \"so_secret\"}\n    target := Target{}\n\n    copier.Copy(\u0026target, \u0026source)\n    fmt.Printf(\"Name: %s, Secret: '%s'\\n\", target.Name, target.Secret)\n    // Output: Name: John, Secret: ''\n}\n```\n\n### `copier:\"must\"` - Enforcing Field Copy\n\nThe `copier:\"must\"` tag forces a field to be copied, resulting in a panic or an error if the field cannot be copied.\n\n```go\ntype MandatorySource struct {\n\tIdentification int\n}\n\ntype MandatoryTarget struct {\n\tID int `copier:\"must\"` // This field must be copied, or it will panic/error.\n}\n\nfunc main() {\n\tsource := MandatorySource{}\n\ttarget := MandatoryTarget{ID: 10}\n\n\t// This will result in a panic or an error since ID is a must field but is empty in source.\n\tif err := copier.Copy(\u0026target, \u0026source); err != nil {\n\t\tlog.Fatal(err)\n\t}\n}\n```\n\n### `copier:\"must,nopanic\"` - Enforcing Field Copy Without Panic\n\nSimilar to `copier:\"must\"`, but Copier returns an error instead of panicking if the field is not copied.\n\n```go\ntype SafeSource struct {\n\tID string\n}\n\ntype SafeTarget struct {\n\tCode string `copier:\"must,nopanic\"` // Enforce copying without panic.\n}\n\nfunc main() {\n\tsource := SafeSource{}\n\ttarget := SafeTarget{Code: \"200\"}\n\n\tif err := copier.Copy(\u0026target, \u0026source); err != nil {\n\t\tlog.Fatalln(\"Error:\", err)\n\t}\n\t// This will not panic, but will return an error due to missing mandatory field.\n}\n```\n\n### `copier:\"override\"` - Overriding Fields with IgnoreEmpty\n\nFields tagged with `copier:\"override\"` are copied even if IgnoreEmpty is set to true in Copier options and works for nil values.\n\n```go\ntype SourceWithNil struct {\n    Details *string\n}\n\ntype TargetOverride struct {\n    Details *string `copier:\"override\"` // Even if source is nil, copy it.\n}\n\nfunc main() {\n    details := \"Important details\"\n    source := SourceWithNil{Details: nil}\n    target := TargetOverride{Details: \u0026details}\n\n    copier.CopyWithOption(\u0026target, \u0026source, copier.Option{IgnoreEmpty: true})\n    if target.Details == nil {\n        fmt.Println(\"Details field was overridden to nil.\")\n    }\n}\n```\n\n### Specifying Custom Field Names\n\nUse field tags to specify a custom field name when the source and destination field names do not match.\n\n```go\ntype SourceEmployee struct {\n    Identifier int64\n}\n\ntype TargetWorker struct {\n    ID int64 `copier:\"Identifier\"` // Map Identifier from SourceEmployee to ID in TargetWorker\n}\n\nfunc main() {\n    source := SourceEmployee{Identifier: 1001}\n    target := TargetWorker{}\n\n    copier.Copy(\u0026target, \u0026source)\n    fmt.Printf(\"Worker ID: %d\\n\", target.ID)\n    // Output: Worker ID: 1001\n}\n```\n\n## Other examples\n\n### Copy from Method to Field with Same Name\n\nIllustrates copying from a method to a field and vice versa.\n\n```go\n// Assuming User and Employee structs defined earlier with method and field respectively.\n\nfunc main() {\n    user := User{Name: \"Jinzhu\", Age: 18}\n    employee := Employee{}\n\n    copier.Copy(\u0026employee, \u0026user)\n    fmt.Printf(\"DoubleAge: %d\\n\", employee.DoubleAge)\n    // Output: DoubleAge: 36, demonstrating method to field copying.\n}\n```\n\n### Copy Struct to Slice\n\n```go\nfunc main() {\n    user := User{Name: \"Jinzhu\", Age: 18, Role: \"Admin\"}\n    var employees []Employee\n\n    copier.Copy(\u0026employees, \u0026user)\n    fmt.Printf(\"%#v\\n\", employees)\n    // Output: []Employee{{Name: \"Jinzhu\", Age: 18, DoubleAge: 36, SuperRole: \"Super Admin\"}}\n}\n```\n\n### Copy Slice to Slice\n\n```go\nfunc main() {\n    users := []User{{Name: \"Jinzhu\", Age: 18, Role: \"Admin\"}, {Name: \"jinzhu 2\", Age: 30, Role: \"Dev\"}}\n    var employees []Employee\n\n    copier.Copy(\u0026employees, \u0026users)\n    fmt.Printf(\"%#v\\n\", employees)\n    // Output: []Employee{{Name: \"Jinzhu\", Age: 18, DoubleAge: 36, SuperRole: \"Super Admin\"}, {Name: \"jinzhu 2\", Age: 30, DoubleAge: 60, SuperRole: \"Super Dev\"}}\n}\n```\n\n### Copy Map to Map\n\n```go\nfunc main() {\n    map1 := map[int]int{3: 6, 4: 8}\n    map2 := map[int32]int8{}\n\n    copier.Copy(\u0026map2, map1)\n    fmt.Printf(\"%#v\\n\", map2)\n    // Output: map[int32]int8{3:6, 4:8}\n}\n```\n\n## Complex Data Copying: Nested Structures with Slices\n\nThis example demonstrates how Copier can be used to copy data involving complex, nested structures, including slices of structs, to showcase its ability to handle intricate data copying scenarios.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/jinzhu/copier\"\n)\n\ntype Address struct {\n\tCity    string\n\tCountry string\n}\n\ntype Contact struct {\n\tEmail  string\n\tPhones []string\n}\n\ntype Employee struct {\n\tName      string\n\tAge       int32\n\tAddresses []Address\n\tContact   *Contact\n}\n\ntype Manager struct {\n\tName            string `copier:\"must\"`\n\tAge             int32  `copier:\"must,nopanic\"`\n\tManagedCities   []string\n\tContact         *Contact `copier:\"override\"`\n\tSecondaryEmails []string\n}\n\nfunc main() {\n\temployee := Employee{\n\t\tName: \"John Doe\",\n\t\tAge:  30,\n\t\tAddresses: []Address{\n\t\t\t{City: \"New York\", Country: \"USA\"},\n\t\t\t{City: \"San Francisco\", Country: \"USA\"},\n\t\t},\n\t\tContact: nil,\n\t}\n\n\tmanager := Manager{\n\t\tManagedCities: []string{\"Los Angeles\", \"Boston\"},\n\t\tContact: \u0026Contact{\n\t\t\tEmail:  \"john.doe@example.com\",\n\t\t\tPhones: []string{\"123-456-7890\", \"098-765-4321\"},\n\t\t}, // since override is set this should be overridden with nil\n\t\tSecondaryEmails: []string{\"secondary@example.com\"},\n\t}\n\n\tcopier.CopyWithOption(\u0026manager, \u0026employee, copier.Option{IgnoreEmpty: true, DeepCopy: true})\n\n\tfmt.Printf(\"Manager: %#v\\n\", manager)\n\t// Output: Manager struct showcasing copied fields from Employee,\n\t// including overridden and deeply copied nested slices.\n}\n```\n\n## Available tags\n\n| Tag                 | Description                                                                                                       |\n| ------------------- | ----------------------------------------------------------------------------------------------------------------- |\n| `copier:\"-\"`        | Explicitly ignores the field during copying.                                                                      |\n| `copier:\"must\"`     | Forces the field to be copied; Copier will panic or return an error if the field is not copied.                   |\n| `copier:\"nopanic\"`  | Copier will return an error instead of panicking.                                                                 |\n| `copier:\"override\"` | Forces the field to be copied even if `IgnoreEmpty` is set. Useful for overriding existing values with empty ones |\n| `FieldName`         | Specifies a custom field name for copying when field names do not match between structs.                          |\n\n## Contributing\n\nYou can help to make the project better, check out [http://gorm.io/contribute.html](http://gorm.io/contribute.html) for things you can do.\n\n# Author\n\n**jinzhu**\n\n- \u003chttp://github.com/jinzhu\u003e\n- \u003cwosmvp@gmail.com\u003e\n- \u003chttp://twitter.com/zhangjinzhu\u003e\n\n## License\n\nReleased under the [MIT License](https://github.com/jinzhu/copier/blob/master/License).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinzhu%2Fcopier","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjinzhu%2Fcopier","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjinzhu%2Fcopier/lists"}