-
Notifications
You must be signed in to change notification settings - Fork 585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for appcast generation #1057
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
a503b57
Add support for appcast generation
coolya 649ff6b
add optional version and signature
coolya fd27f7f
appcast: add missing fields
coolya 6d79512
make length int64 for better interop with System.IO.FileInfo
coolya 8e419fd
Add docs
coolya File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/// Contains code to configure FAKE for Appcast handling | ||
module Fake.Appcast | ||
open System.Xml | ||
open System.Xml.Linq | ||
|
||
|
||
//private XMLHelper inspired by https://nbevans.wordpress.com/2015/04/15/super-skinny-xml-document-generation-with-f/ | ||
let private XDeclaration version encoding standalone = XDeclaration(version, encoding, standalone) | ||
let private XName expandedName = XName.Get(expandedName) | ||
let private XDocument xdecl content = XDocument(xdecl, content |> Seq.map (fun v -> v :> obj) |> Seq.toArray) | ||
let private XElement expandedName content = XElement(XName expandedName, content |> Seq.map (fun v -> v :> obj) |> Seq.toArray) :> obj | ||
let private XAttribute expandedName value = XAttribute(XName expandedName, value) :> obj | ||
let private XAttributeXName expandedName value = Linq.XAttribute(expandedName, value) :> obj | ||
|
||
/// Sparkel namespace used for RSS extension | ||
let private sparkle = XNamespace.Get("http://www.andymatuschak.org/xml-namespaces/sparkle") | ||
|
||
/// Mime type of the download file | ||
type MimeType = | ||
/// Octetstream use for exe or zip files | ||
| OctetStream | ||
/// Custom mimetype | ||
| Custom of string | ||
|
||
/// Download details for the appcast | ||
type AppcastItem = { | ||
/// The name of the update | ||
title : string; | ||
/// Date when update is published | ||
pubdate : System.DateTime; | ||
/// URI where the update files are found | ||
url : System.Uri; | ||
/// Machine readable version number used to determine if an update is available by the client (should follow semver) | ||
version : string; | ||
/// Optional human readable version number. This will be shown to the user if present otherwise | ||
/// the technical version number will be used | ||
shortVersion : string option; | ||
/// Mime type of the update file, usualy octetstream | ||
mimetype : MimeType | ||
/// Optional DSA signature for the archive. It is recommended to use this if the app itself is not signed | ||
dsaSignature : string option; | ||
/// Optional miminal system version for the update | ||
minimumSystemVersion : string option; | ||
/// Length of the file in bytes | ||
length : int64; | ||
} | ||
|
||
/// Configuration data for the appcast | ||
type Appcast = { | ||
/// A titel, usually the app name | ||
title : string; | ||
/// Short description | ||
description : string; | ||
/// Language of your app | ||
language : string; | ||
/// Updates published to client, can habe multiple updates e.g. for different OS versions | ||
items : AppcastItem list; | ||
} | ||
|
||
/// writes an appcast to a file | ||
/// ##Parameters | ||
/// | ||
/// - `path` - The file where the appcast should be written | ||
/// - `cast` - The appcast to write | ||
/// ##Sample | ||
/// // This target creates the app cast for our app. I contains two version 1.X and 2.X while 2.X requires at least OS X 10.10 Yosemite. | ||
/// Target "CreateAppcast" (fun _ -> | ||
/// let server = "https://example.com/files/" | ||
/// let fileLength file = | ||
/// let info = new System.IO.FileInfo(file) | ||
/// info.Length | ||
/// | ||
/// let latestSize = fileLength "build/download-2.0.1.zip" | ||
/// let legacySize = fileLength "build/download-1.1.4.zip" | ||
/// | ||
/// { | ||
/// title = "My Awesome App" | ||
/// description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus." | ||
/// language = "en" | ||
/// items = [ | ||
/// { | ||
/// title = "Hawk Nickel Greyhound" | ||
/// pubdate = System.DateTime.Now | ||
/// url = new System.Uri(server + "download-2.0.1.zip") | ||
/// version = "2014" // This our internal build number | ||
/// shortVersion = Some("2.0.1") //This is what we show to the user | ||
/// mimetype = OctetStream | ||
/// minimumSystemVersion = Some("10.10") | ||
/// length = latestSize | ||
/// dsaSignature = None | ||
/// }; | ||
/// { | ||
/// title = "Sparrow Platinum Beagle" | ||
/// pubdate = System.DateTime.Now | ||
/// url = new System.Uri(server + "download-1.1.4.zip") | ||
/// version = "1142" // This our internal build number | ||
/// shortVersion = Some("1.1.4") //This is what we show to the user | ||
/// mimetype = OctetStream | ||
/// length = legacySize | ||
/// minimumSystemVersion = None | ||
/// dsaSignature = None | ||
/// } | ||
/// ] | ||
/// } |> writeAppcast "build/updates.xml" | ||
/// ) | ||
let writeAppcast (path : string) (cast : Appcast) = | ||
let toXml (cast : Appcast) = | ||
let mtToString mimetype = | ||
match mimetype with | ||
| OctetStream -> "application/octet-stream" | ||
| Custom(s) -> s | ||
let choose a b = | ||
match a with | ||
| Some(c) -> c | ||
| None -> b | ||
let appendSome option consequence content = | ||
match option with | ||
| Some(data) -> (consequence data) :: content | ||
| None -> content | ||
|
||
|
||
let item (e : AppcastItem) = | ||
let appendMinimumVersion = appendSome e.minimumSystemVersion (fun d -> XAttributeXName (sparkle + "minimumSystemVersion") d) | ||
let appendSig = appendSome e.dsaSignature (fun d -> XAttributeXName (sparkle + "dsaSignature") d) | ||
|
||
XElement "item" [ | ||
XElement "title" e.title | ||
XElement "pubDate" (e.pubdate.ToString("r")) | ||
XElement "enclosure" ([ | ||
XAttribute "url" e.url | ||
XAttributeXName (sparkle + "version") e.version | ||
XAttribute "type" (mtToString e.mimetype) | ||
XAttribute "length" e.length | ||
XAttributeXName (sparkle + "shortVersionString") (choose e.shortVersion e.version) | ||
] | ||
|> appendMinimumVersion | ||
|> appendSig) | ||
] | ||
|
||
let doc = XDocument (XDeclaration "1.0" "UTF-8" "no") [ | ||
XElement "rss" [ | ||
XAttribute "version" "2.0" | ||
XAttributeXName (XNamespace.Xmlns + "sparkle") "http://www.andymatuschak.org/xml-namespaces/sparkle" | ||
XAttributeXName (XNamespace.Xmlns + "dc") "http://purl.org/dc/elements/1.1/" | ||
XElement "channel" ([ | ||
XElement "title" cast.title | ||
XElement "description" cast.description | ||
XElement "language" cast.language] | ||
@ List.map item cast.items) | ||
] | ||
] | ||
doc | ||
let xml = toXml cast | ||
use writer = XmlWriter.Create(path) | ||
xml.Save(writer) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we have a little more docs. like a sample or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like this or is it to complex?