{"id":36848845,"url":"https://github.com/justwatchcom/goat","last_synced_at":"2026-01-12T14:35:44.664Z","repository":{"id":57487267,"uuid":"45600099","full_name":"justwatchcom/goat","owner":"justwatchcom","description":"generate soap requests for Go at runtime","archived":false,"fork":false,"pushed_at":"2016-04-07T12:07:38.000Z","size":37,"stargazers_count":126,"open_issues_count":3,"forks_count":14,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-09-29T06:39:34.253Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/justwatchcom.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}},"created_at":"2015-11-05T09:11:01.000Z","updated_at":"2024-08-24T11:04:01.000Z","dependencies_parsed_at":"2022-09-01T23:02:10.539Z","dependency_job_id":null,"html_url":"https://github.com/justwatchcom/goat","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/justwatchcom/goat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justwatchcom%2Fgoat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justwatchcom%2Fgoat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justwatchcom%2Fgoat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justwatchcom%2Fgoat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/justwatchcom","download_url":"https://codeload.github.com/justwatchcom/goat/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/justwatchcom%2Fgoat/sbom","scorecard":{"id":544479,"data":{"date":"2025-08-11","repo":{"name":"github.com/justwatchcom/goat","commit":"1e20fa9d4f49fcbe40fa79b4848ee4a40da2861d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","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":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"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":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","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":-1,"reason":"no dependencies found","details":null,"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":"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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Code-Review","score":0,"reason":"Found 0/12 approved changesets -- score normalized to 0","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":"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":"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":"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":"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":"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":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: 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":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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"}}]},"last_synced_at":"2025-08-20T09:08:24.127Z","repository_id":57487267,"created_at":"2025-08-20T09:08:24.127Z","updated_at":"2025-08-20T09:08:24.127Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28340402,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2026-01-12T14:35:43.894Z","updated_at":"2026-01-12T14:35:44.638Z","avatar_url":"https://github.com/justwatchcom.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# goat\nGenerate SOAP requests for Go at runtime\n\n# Approach\nIn my opinion, there are two main approaches for writing a soap client for Go\n(any language):\n\n1. generate native code from the WSDL withouth reflection\n2. parse the WSDL at runtime and offer a general interface which then generates the requests and parses the responses\n\nThis library tries to combine the best from both approaches:\n\n1. load WSDL at runtime, generate the requests from a parameter set and\n2. generate structs to parse the responses into and work with them in a native way\n\n# Motivation\nREST is on the way, and all the services at JustWatch are REST APIs. But we need\nto talk to the Adwords API, which is a SOAP api. Since there're no plans to change\nthis, I started changing the way how SOAP is handled in Go. The status quo is,\nthat XML in general is not as nice as handling JSON, but it is still possible.\n\nThen there are some libraries around, which auto-generate code from a wsdl.\nI prefer having native go-structs over using map[string]interface{}. Even if it\nwould compile all the time, putting the structs together still is a hazzle\nbecause of the different name spaces and so on. I don't want to care about all\npossible fields and their name spaces and if I have as many elements in a\nsequence as there should be (\"minOccurs\" and \"maxOccurs\"). I just want to pass\nthe parameter fields and a library cares for putting them in the right order and\nvalidating them.\n\nBack to the Adwords API: there are some nice-ish libraries around, I only had a\nlook at the Python library: There it is like it is meant to be: name the service,\nit gets downloaded and parsed by [suds](https://pypi.python.org/pypi/suds) and\nthe you just pass a dictionary with fields. Not so much code, and the library\n(suds) knows what to do.\n\nAs long there is reflection in Go, this should be possible.\n\n## Personal motivation\nBack in university, we learned M68k Assembler (which I'm very happy about).\nThere was a Windows program we used to execute the asm code with, but I wasn't happy\nabout it. I wasn't happy about the UX and that we had to use Windows (I was a software-hippie\nback then ;-).\n\nSo then I tried to create my own interpreter written in Java using GTK bindings.\nAt the end, it helped me get to know Java, its standard library and Assembler.\nAnd since it was in a very early semester, it helped me a lot by solving coding tasks\nfaster than the majority.\n\nBut on the other hand, I didn't have something to replace that Windows program with.\n\nThis project should also be something like the described one:\n\n- learn XML and XSD / WSDL (and SOAP)\n- make it easier to handle WSDLs in Go (for me)\n\nSo even if this project does not work out at the end, it may help the one or the other\nto handle SOAP in Go a little bit more efficient.\n\n# Solution\nThis Library is forked from [wsdl-go](https://code.google.com/p/wsdl-go/). In the\nfuture, it should take out a lot of stuff from the auto-generating stuff to only\nhave the structs. The wsdl and the xsd packages will take care about generating\nthe requests.\n\n# Status\n\n- [x] support for generating basic requests\n- [x] some Adwords API Endpoints still work (for get Requests)\n- [ ] attributes\n- [ ] validation (\"minOccurs\" and \"maxOccurs\")\n- [ ] boil down code generation stuff\n- [ ] retrieving of xsd schemes not already in the WSDL\n- [ ] make the already working parts *nice* and *tested*\n- [ ] use structs with proper xml tags for parameters, not map[string]interface{} (for simpler use of attributes)\n\n# Example\n\n```go\n    c := makeNewOAuthHTTPClient()\n\n    ws = goat.NewWebservice(c, map[string]interface{}{\n        \"RequestHeader/clientCustomerId\": \"CLIENT_CUSTOMER_ID\",\n        \"RequestHeader/developerToken\":   \"DEVELOPER_TOKEN\",\n        \"RequestHeader/userAgent\":        \"a random header\",\n        \"RequestHeader/validateOnly\":     true,\n        \"RequestHeader/partialFailure\":   false,\n    })\n\n    err := ws.AddServices(\"https://adwords.google.com/api/adwords/mcm/v201509/ManagedCustomerService?wsdl\")\n    if err != nil {\n        panic(err)\n    }\n\n    resp := struct {\n        XMLName     xml.Name `xml:\"getResponse\"`\n        GetResponse struct {\n            XMLName         xml.Name `xml:\"rval\"`\n            TotalNumEntries int      `xml:\"totalNumEntries\"`\n            PageType        string   `xml:\"Page.Type\"`\n            Entries         []struct {\n                XMLName          xml.Name `xml:\"entries\"`\n                AccountLabels    string   `xml:\"accountLabels\"`\n                CanManageClients bool     `xml:\"canManageClients\"`\n                CompanyName      string   `xml:\"companyName\"`\n                CurrencyCode     string   `xml:\"currencyCode\"`\n                CustomerId       string   `xml:\"customerId\"`\n                DateTimeZone     string   `xml:\"dateTimeZone\"`\n                Name             string   `xml:\"name\"`\n                TestAccount      bool     `xml:\"testAccount\"`\n            } `xml:\"entries\"`\n        }\n    }{}\n    err = ws.Do(\"ManagedCustomerService\", \"get\", \u0026resp, map[string]interface{}{\n        \"get/serviceSelector/fields\": []string{\n            \"AccountLabels\",\n            \"CanManageClients\",\n            \"CompanyName\",\n            \"CurrencyCode\",\n            \"CustomerId\",\n            \"DateTimeZone\",\n            \"Name\",\n            \"TestAccount\",\n        },\n    })\n    if err != nil {\n        panic(err)\n    }\n    // work with resp\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustwatchcom%2Fgoat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjustwatchcom%2Fgoat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjustwatchcom%2Fgoat/lists"}