{"id":30504962,"url":"https://github.com/victorpopkov/go-appcast","last_synced_at":"2025-08-25T14:15:16.669Z","repository":{"id":57522773,"uuid":"90539401","full_name":"victorpopkov/go-appcast","owner":"victorpopkov","description":"Go library for working with appcasts.","archived":false,"fork":false,"pushed_at":"2018-12-21T18:44:16.000Z","size":608,"stargazers_count":5,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-06-20T06:23:16.438Z","etag":null,"topics":["appcast","github","go","golang","golang-library","sourceforge","sparkle"],"latest_commit_sha":null,"homepage":"","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/victorpopkov.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2017-05-07T14:42:45.000Z","updated_at":"2023-02-18T09:58:41.000Z","dependencies_parsed_at":"2022-09-26T18:01:24.476Z","dependency_job_id":null,"html_url":"https://github.com/victorpopkov/go-appcast","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/victorpopkov/go-appcast","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorpopkov%2Fgo-appcast","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorpopkov%2Fgo-appcast/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorpopkov%2Fgo-appcast/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorpopkov%2Fgo-appcast/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/victorpopkov","download_url":"https://codeload.github.com/victorpopkov/go-appcast/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/victorpopkov%2Fgo-appcast/sbom","scorecard":{"id":920548,"data":{"date":"2025-08-11","repo":{"name":"github.com/victorpopkov/go-appcast","commit":"c741901786aa6d509934cae9956fdc2be69ed2ec"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"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":"Code-Review","score":0,"reason":"Found 0/30 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":"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":"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":"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":"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":"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":"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":"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":"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"}}]},"last_synced_at":"2025-08-25T02:01:46.308Z","repository_id":57522773,"created_at":"2025-08-25T02:01:46.308Z","updated_at":"2025-08-25T02:01:46.308Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272077796,"owners_count":24869310,"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-08-25T02:00:12.092Z","response_time":1107,"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":["appcast","github","go","golang","golang-library","sourceforge","sparkle"],"created_at":"2025-08-25T14:15:12.579Z","updated_at":"2025-08-25T14:15:16.659Z","avatar_url":"https://github.com/victorpopkov.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-appcast\n\n[![Travis (.org)](https://img.shields.io/travis/victorpopkov/go-appcast.svg)](https://travis-ci.org/victorpopkov/go-appcast)\n[![Codecov](https://img.shields.io/codecov/c/github/victorpopkov/go-appcast.svg)](https://codecov.io/gh/victorpopkov/go-appcast)\n[![Go Report Card](https://goreportcard.com/badge/github.com/victorpopkov/go-appcast)](https://goreportcard.com/report/github.com/victorpopkov/go-appcast)\n[![GoDoc](https://godoc.org/github.com/victorpopkov/go-appcast?status.svg)](https://godoc.org/github.com/victorpopkov/go-appcast)\n\nAn extendable library which provides functionality for working with different\nappcasts. It can work in both ways: retrieve data from an already existing\nappcast (unmarshal) or generate an appcast from the provided data (marshal).\n\n- [What \"appcast\" means?](#what-appcast-means)\n- [What this library does?](#what-this-library-does)\n- [Providers](#providers)\n  - [GitHub Atom Feed](#github-atom-feed)\n  - [SourceForge RSS Feed](#sourceforge-rss-feed)\n  - [Sparkle RSS Feed](#sparkle-rss-feed)\n- [Sources](#sources)\n- [Outputs](#outputs)\n\n## What \"appcast\" means?\n\nThe word \"appcast\" is usually referred to a remote web page providing\ninformation about software updates. This kind of pages is usually created for\ndifferent software update frameworks like [Sparkle][] or generated by different\nservices that distribute applications ([GitHub][], [SourceForge][] and etc.).\n\nThere are plenty of different methods available, but originally \"appcasting\" was\nthe practice of using an [RSS enclosure][] to distribute updates and release\nnotes.\n\n## What this library does?\n\nAs you can find plenty of different ways how vendors distribute their software\nupdates it becomes pretty tedious to extract useful information from their\nappcasts. Especially, considering the idea that sometimes you would like to\ntranspile one appcast type into another or simply make changes into an already\nexisting one.\n\nHere comes this library handy. It provides the core functionality for working\nwith the supported providers in a reliable and consistent way. In addition, it\nwas designed to be extendable which enables you adding more features or extend\nthe supported providers, sources and even outputs to match your needs.\n\n### Features\n\n- [x] Designed to be extendable\n- [x] Detect release stability from the semantic version\n- [x] Different outputs to save to\n- [x] Different sources to load from\n- [x] Filter releases by stability, title, media type or download URL\n- [x] Guess the supported provider\n- [x] Sort releases by version\n- [ ] Transpilation from one provider into another\n\n## Providers\n\nOut of the box, 3 providers are supported:\n\n- [GitHub Atom Feed](#github-atom-feed)\n- [SourceForge RSS Feed](#sourceforge-rss-feed)\n- [Sparkle RSS Feed](#sparkle-rss-feed)\n\nEach provider can be used separately by explicitly importing only those packages\nyou are going to use. This is useful when you don't need any extra stuff in your\nproject and you know which appcast provider you are dealing with.\n\nIn other cases importing a single `github.com/victorpopkov/go-appcast` is the\nbest option. This will give you all the necessary functionality to work with the\nsupported providers as it will automatically detect which is used and then call\nthe appropriate methods.\n\n### GitHub Atom Feed\n\nEach project that uses [GitHub][] releases to distribute applications has its\nown Atom Feed available that can be considered as an appcast.\n\nA good example url is an [Atom](https://atom.io/) releases:\n\u003chttps://www.adium.im/sparkle/appcast-release.xml\u003e. You can find the\ncorresponding [GoDoc][] examples below:\n\n- [`import \"github.com/victorpopkov/go-appcast\"`](https://godoc.org/github.com/victorpopkov/go-appcast)\n- [`import \"github.com/victorpopkov/go-appcast/provider/github\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/github)\n\n### SourceForge RSS Feed\n\nEach project hosted on [SourceForge][] has its own releases RSS feed available\nthat can be considered to be an appcast.\n\nAs an example you can take a look at the [FileZilla](https://filezilla-project.org/)\nSourceForge releases page here: \u003chttps://sourceforge.net/projects/filezilla/rss\u003e.\nYou can find the corresponding [GoDoc][] examples below:\n\n- [`import \"github.com/victorpopkov/go-appcast\"`](https://godoc.org/github.com/victorpopkov/go-appcast)\n- [`import \"github.com/victorpopkov/go-appcast/provider/sourceforge\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/sourceforge)\n\n### Sparkle RSS Feed\n\nAppcasts, created by the [Sparkle Framework][]. Originally, Sparkle was created\nto distribute software updates for macOS applications. However, for Windows,\nthere is a [WinSparkle](https://winsparkle.org/) framework which uses the same\n[RSS enclosure][] technique to distribute updates and release notes.\n\nA good example is how the [Adium](https://adium.im/) distributes software\nupdates: \u003chttps://www.adium.im/sparkle/appcast-release.xml\u003e. You can find the\ncorresponding [GoDoc][] examples below:\n\n- [`import \"github.com/victorpopkov/go-appcast\"`](https://godoc.org/github.com/victorpopkov/go-appcast)\n- [`import \"github.com/victorpopkov/go-appcast/provider/sparkle\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/sparkle)\n\n## Sources\n\nOut of the box, 2 sources are supported:\n\n- [`source.Local`](#sourcelocal) (load from the local file)\n- [`source.Remote`](#sourceremote) (load from the remote location)\n\nThis means that you have by default 2 options from where an appcast can be\nloaded. You can just choose the appropriate one from the `source` package or\ncreate your own.\n\nYou can find a [GoDoc][] standalone package example here:\n[`import \"github.com/victorpopkov/go-appcast/source\"`](https://godoc.org/github.com/victorpopkov/go-appcast/source).\nIn addition, by digging into the [\"Providers\"](#providers) you can see how to\nuse them alongside with an appcast in their examples:\n\n- [`import \"github.com/victorpopkov/go-appcast/provider/github\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/github)\n- [`import \"github.com/victorpopkov/go-appcast/provider/sourceforge\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/sourceforge)\n- [`import \"github.com/victorpopkov/go-appcast/provider/sparkle\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/sparkle)\n\n### `source.Remote`\n\nThis was designed to retrieve an appcast data from the remote location by URL.\nIt should cover most use cases when the appcast is available remotely.\n\nFor convenience purposes an `Appcast.LoadFromRemoteSource` can be used when\nusing the default `appcast` package. It sets the `Appcast` to use the\n`source.Remote`, loads the source and unmarshals it.\n\n### `source.Local`\n\nThis was designed to retrieve an appcast data from the local file by path.\n\nFor convenience purposes an `Appcast.LoadFromLocalSource` can be used when using\nthe default `appcast` package. It sets the `Appcast` to use the `source.Local`,\nloads the source and unmarshals it.\n\n## Outputs\n\nOut of the box, only a single `output.Local` is available to save an appcast to\nthe local file.\n\nJust like the [\"Sources\"](#sources), outputs are designed in the same way\nmeaning that you can extend the list of the supported outputs by creating your\nown.\n\nYou can find a [GoDoc][] standalone package example here:\n[`import \"github.com/victorpopkov/go-appcast/output\"`](https://godoc.org/github.com/victorpopkov/go-appcast/output).\nIn addition, by digging into the [\"Providers\"](#providers) you can see how to\nuse them alongside with an appcast in their \"Marshal\" examples:\n\n- [`import \"github.com/victorpopkov/go-appcast/provider/github\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/github)\n- [`import \"github.com/victorpopkov/go-appcast/provider/sourceforge\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/sourceforge)\n- [`import \"github.com/victorpopkov/go-appcast/provider/sparkle\"`](https://godoc.org/github.com/victorpopkov/go-appcast/provider/sparkle)\n\n## License\n\nReleased under the [MIT License](https://opensource.org/licenses/MIT).\n\n[github]: https://github.com/\n[godoc]: https://godoc.org/\n[rss enclosure]: https://en.wikipedia.org/wiki/RSS_enclosure\n[sourceforge]: https://sourceforge.net/\n[sparkle framework]: https://sparkle-project.org/\n[sparkle]: https://sparkle-project.org/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictorpopkov%2Fgo-appcast","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvictorpopkov%2Fgo-appcast","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvictorpopkov%2Fgo-appcast/lists"}