github-release 1.0.4 → 1.0.5
raw patch · 10 files changed
+175/−295 lines, 10 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
Files
- CHANGELOG.markdown +0/−7
- LICENSE.markdown +1/−1
- README.markdown +0/−64
- executables/github-release.hs +5/−0
- github-release.cabal +18/−24
- library/GitHubRelease.hs +151/−0
- package.yaml +0/−42
- source/executable/Main.hs +0/−5
- source/library/GitHubRelease.hs +0/−151
- stack.yaml +0/−1
− CHANGELOG.markdown
@@ -1,7 +0,0 @@-# Change log--GitHub Release uses [Semantic Versioning][].-The change log is available through the [releases on GitHub][].--[Semantic Versioning]: http://semver.org/spec/v2.0.0.html-[releases on GitHub]: https://github.com/tfausak/github-release/releases
LICENSE.markdown view
@@ -1,6 +1,6 @@ # [The MIT License (MIT)][] -Copyright (c) 2016 Taylor Fausak+Copyright (c) 2017 Taylor Fausak Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in
− README.markdown
@@ -1,64 +0,0 @@-# [GitHub Release][]--[![Version badge][]][version]-[![Build badge][]][build]-[![Windows build badge][]][windows build]--GitHub Release is a command-line utility for uploading files to GitHub-releases.--The recommended way to get GitHub Release is to download [the latest release][]-for your operating system. These releases are, of course, added with GitHub-Release itself.--Once you've got it, run it like so:--``` sh-github-release upload \- --token '...' \- --owner 'someone' \- --repo 'something' \- --tag '1.2.3' \- --file 'path/to/example.tgz' \- --name 'example-1.2.3.tgz'-```--You can generate a token on the [personal access tokens][] page of your-personal settings. The `file` option is the path to the local file you want to-upload. The `name` option is what the file should be called on the GitHub-release.--GitHub Release is written in Haskell. If you want to build it yourself or use-it in your project, you'll want to get [Stack][]. Once you've done that, you-can install and use it from the command line.--``` sh-stack --resolver nightly install github-release-stack exec -- github release upload # as above ...-```--Or you can use it from Haskell.--``` hs-import qualified GitHubRelease-GitHubRelease.upload- "..." -- token- "someone" -- owner- "something" -- repo- "1.2.3" -- tag- "path/to/example.tgz" -- file- "example-1.2.3.tgz" -- name-```--Inspired by <https://github.com/aktau/github-release>.--[GitHub Release]: https://github.com/tfausak/github-release-[Version badge]: https://www.stackage.org/package/github-release/badge/nightly?label=version-[version]: https://www.stackage.org/package/github-release-[Build badge]: https://travis-ci.org/tfausak/github-release.svg-[build]: https://travis-ci.org/tfausak/github-release-[Windows build badge]: https://ci.appveyor.com/api/projects/status/github/tfausak/github-release?svg=true-[windows build]: https://ci.appveyor.com/project/TaylorFausak/github-release-[the latest release]: https://github.com/tfausak/github-release/releases/latest-[personal access tokens]: https://github.com/settings/tokens-[Stack]: http://docs.haskellstack.org/en/stable/README/
+ executables/github-release.hs view
@@ -0,0 +1,5 @@+module Main+ ( module GitHubRelease+ ) where++import GitHubRelease (main)
github-release.cabal view
@@ -3,9 +3,9 @@ -- see: https://github.com/sol/hpack name: github-release-version: 1.0.4+version: 1.0.5 synopsis: Upload files to GitHub releases.-description: GitHub Release is a command-line utility for uploading files to GitHub releases.+description: GitHub Release uploads files to GitHub releases. category: Utility homepage: https://github.com/tfausak/github-release#readme bug-reports: https://github.com/tfausak/github-release/issues@@ -15,32 +15,26 @@ build-type: Simple cabal-version: >= 1.10 -extra-source-files:- CHANGELOG.markdown- package.yaml- README.markdown- stack.yaml- source-repository head type: git location: https://github.com/tfausak/github-release library hs-source-dirs:- source/library+ library ghc-options: -Wall build-depends:- aeson >=0.9 && <1.3- , base >=4.8.2 && <4.11- , bytestring >=0.10.6 && <0.11- , http-client >=0.4.30 && <0.6- , http-client-tls >=0.2.4 && <0.4- , http-types >=0.9 && <0.10- , mime-types >=0.1 && <0.2- , optparse-generic >=1.1 && <1.3- , text >=1.2.2 && <1.3- , unordered-containers >=0.2.5 && <0.3- , uri-templater >=0.2 && <0.3+ base >= 4.8.2 && < 4.11+ , aeson >= 0.9 && < 1.3+ , bytestring >= 0.10.6 && < 0.11+ , http-client >= 0.4.30 && < 0.6+ , http-client-tls >= 0.2.4 && < 0.4+ , http-types >= 0.9 && < 0.10+ , mime-types >= 0.1 && < 0.2+ , optparse-generic >= 1.1 && < 1.3+ , text >= 1.2.2 && < 1.3+ , unordered-containers >= 0.2.5 && < 0.3+ , uri-templater >= 0.2 && < 0.3 exposed-modules: GitHubRelease other-modules:@@ -48,11 +42,11 @@ default-language: Haskell2010 executable github-release- main-is: Main.hs+ main-is: github-release.hs hs-source-dirs:- source/executable- ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N+ executables+ ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N build-depends:- base+ base >= 4.8.2 && < 4.11 , github-release default-language: Haskell2010
+ library/GitHubRelease.hs view
@@ -0,0 +1,151 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}++module GitHubRelease where++import Options.Generic (type (<?>))++import qualified Data.Aeson as Aeson+import qualified Data.ByteString.Char8 as BS8+import qualified Data.ByteString.Lazy as BSL+import qualified Data.HashMap.Strict as HashMap+import qualified Data.Text as Text+import qualified Data.Version as Version+import qualified GHC.Generics as Generics+import qualified Network.HTTP.Client as Client+import qualified Network.HTTP.Client.TLS as TLS+import qualified Network.HTTP.Types as HTTP+import qualified Network.Mime as MIME+import qualified Network.URI.Template as Template+import qualified Network.URI.Template.Types as Template+import qualified Options.Generic as Options+import qualified Paths_github_release as This+import qualified System.IO as IO+import qualified Text.Printf as Printf++data Command+ = Upload { file :: FilePath <?> "The path to the local file to upload."+ , name :: String <?> "The name to give the file on the release."+ , owner :: String <?> "The GitHub owner, either a user or organization."+ , repo :: String <?> "The GitHub repository name."+ , tag :: String <?> "The tag name."+ , token :: String <?> "Your OAuth2 token."}+ | Version+ deriving (Generics.Generic, Show)++instance Options.ParseRecord Command++main :: IO ()+main = do+ command <- Options.getRecord (Text.pack "Upload a file to a GitHub release.")+ runCommand command++runCommand :: Command -> IO ()+runCommand command =+ case command of+ Upload aFile aName anOwner aRepo aTag aToken ->+ upload+ (Options.unHelpful aToken)+ (Options.unHelpful anOwner)+ (Options.unHelpful aRepo)+ (Options.unHelpful aTag)+ (Options.unHelpful aFile)+ (Options.unHelpful aName)+ Version -> putStrLn versionString++upload :: String -> String -> String -> String -> FilePath -> String -> IO ()+upload aToken anOwner aRepo aTag aFile aName = do+ manager <- Client.newManager TLS.tlsManagerSettings+ uploadUrl <- getUploadUrl manager aToken anOwner aRepo aTag+ response <- uploadFile manager uploadUrl aToken aFile aName+ case HTTP.statusCode (Client.responseStatus response) of+ 201 -> pure ()+ _ -> do+ IO.hPrint IO.stderr response+ BSL.hPutStr IO.stderr (Client.responseBody response)+ fail "Failed to upload file to release!"++getUploadUrl+ :: Client.Manager+ -> String+ -> String+ -> String+ -> String+ -> IO Template.UriTemplate+getUploadUrl manager aToken anOwner aRepo aTag = do+ (Right json) <- getTag manager aToken anOwner aRepo aTag+ let (Just (Aeson.String text)) = HashMap.lookup (Text.pack "upload_url") json+ let uploadUrl = Text.unpack text+ let (Right template) = Template.parseTemplate uploadUrl+ pure template++getTag+ :: Client.Manager+ -> String+ -> String+ -> String+ -> String+ -> IO (Either String Aeson.Object)+getTag manager aToken anOwner aRepo aTag = do+ let format = "https://api.github.com/repos/%s/%s/releases/tags/%s"+ let url = Printf.printf format anOwner aRepo aTag+ initialRequest <- Client.parseUrlThrow url+ let request =+ initialRequest+ {Client.requestHeaders = [authorizationHeader aToken, userAgentHeader]}+ response <- Client.httpLbs request manager+ let body = Client.responseBody response+ let json = Aeson.eitherDecode body+ return json++authorizationHeader :: String -> HTTP.Header+authorizationHeader aToken =+ (HTTP.hAuthorization, BS8.pack (Printf.printf "token %s" aToken))++userAgentHeader :: HTTP.Header+userAgentHeader = (HTTP.hUserAgent, BS8.pack userAgent)++userAgent :: String+userAgent = Printf.printf "%s/%s-%s" "tfausak" "github-release" versionString++versionString :: String+versionString = Version.showVersion This.version++uploadFile+ :: Client.Manager+ -> Template.UriTemplate+ -> String+ -> FilePath+ -> String+ -> IO (Client.Response BSL.ByteString)+uploadFile manager template aToken aFile aName = do+ contents <- BSL.readFile aFile+ let body = Client.RequestBodyLBS contents+ uploadBody manager template aToken body aName++uploadBody+ :: Client.Manager+ -> Template.UriTemplate+ -> String+ -> Client.RequestBody+ -> String+ -> IO (Client.Response BSL.ByteString)+uploadBody manager template aToken body aName = do+ let url =+ Template.render+ template+ [("name", Template.WrappedValue (Template.Single aName))]+ initialRequest <- Client.parseUrlThrow url+ let request =+ initialRequest+ { Client.method = BS8.pack "POST"+ , Client.requestBody = body+ , Client.requestHeaders =+ [ authorizationHeader aToken+ , (HTTP.hContentType, MIME.defaultMimeLookup (Text.pack aName))+ , userAgentHeader+ ]+ }+ Client.httpLbs request manager
− package.yaml
@@ -1,42 +0,0 @@-category: Utility-description: GitHub Release is a command-line utility for uploading files to GitHub- releases.-executables:- github-release:- dependencies:- - base- - github-release- ghc-options:- - -threaded- - -rtsopts- - -with-rtsopts=-N- main: Main.hs- source-dirs: source/executable-extra-source-files:-- CHANGELOG.markdown-- package.yaml-- README.markdown-- stack.yaml-ghc-options: -Wall-github: tfausak/github-release-library:- dependencies:- - aeson >=0.9 && <1.3- - base >=4.8.2 && <4.11- - bytestring >=0.10.6 && <0.11- - http-client >=0.4.30 && <0.6- - http-client-tls >=0.2.4 && <0.4- - http-types >=0.9 && <0.10- - mime-types >=0.1 && <0.2- - optparse-generic >=1.1 && <1.3- - text >=1.2.2 && <1.3- - unordered-containers >=0.2.5 && <0.3- - uri-templater >=0.2 && <0.3- other-modules: Paths_github_release- source-dirs: source/library-license: MIT-license-file: LICENSE.markdown-maintainer: Taylor Fausak-name: github-release-synopsis: Upload files to GitHub releases.-version: '1.0.4'
− source/executable/Main.hs
@@ -1,5 +0,0 @@-module Main- ( module GitHubRelease- ) where--import GitHubRelease (main)
− source/library/GitHubRelease.hs
@@ -1,151 +0,0 @@-{-# LANGUAGE DataKinds #-}-{-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeOperators #-}--module GitHubRelease where--import Options.Generic (type (<?>))--import qualified Data.Aeson as Aeson-import qualified Data.ByteString.Char8 as BS8-import qualified Data.ByteString.Lazy as BSL-import qualified Data.HashMap.Strict as HashMap-import qualified Data.Text as Text-import qualified Data.Version as Version-import qualified GHC.Generics as Generics-import qualified Network.HTTP.Client as Client-import qualified Network.HTTP.Client.TLS as TLS-import qualified Network.HTTP.Types as HTTP-import qualified Network.Mime as MIME-import qualified Network.URI.Template as Template-import qualified Network.URI.Template.Types as Template-import qualified Options.Generic as Options-import qualified Paths_github_release as This-import qualified System.IO as IO-import qualified Text.Printf as Printf--data Command- = Upload { file :: FilePath <?> "The path to the local file to upload."- , name :: String <?> "The name to give the file on the release."- , owner :: String <?> "The GitHub owner, either a user or organization."- , repo :: String <?> "The GitHub repository name."- , tag :: String <?> "The tag name."- , token :: String <?> "Your OAuth2 token."}- | Version- deriving (Generics.Generic, Show)--instance Options.ParseRecord Command--main :: IO ()-main = do- command <- Options.getRecord (Text.pack "Upload a file to a GitHub release.")- runCommand command--runCommand :: Command -> IO ()-runCommand command =- case command of- Upload aFile aName anOwner aRepo aTag aToken ->- upload- (Options.unHelpful aToken)- (Options.unHelpful anOwner)- (Options.unHelpful aRepo)- (Options.unHelpful aTag)- (Options.unHelpful aFile)- (Options.unHelpful aName)- Version -> putStrLn versionString--upload :: String -> String -> String -> String -> FilePath -> String -> IO ()-upload aToken anOwner aRepo aTag aFile aName = do- manager <- Client.newManager TLS.tlsManagerSettings- uploadUrl <- getUploadUrl manager aToken anOwner aRepo aTag- response <- uploadFile manager uploadUrl aToken aFile aName- case HTTP.statusCode (Client.responseStatus response) of- 201 -> pure ()- _ -> do- IO.hPrint IO.stderr response- BSL.hPutStr IO.stderr (Client.responseBody response)- fail "Failed to upload file to release!"--getUploadUrl- :: Client.Manager- -> String- -> String- -> String- -> String- -> IO Template.UriTemplate-getUploadUrl manager aToken anOwner aRepo aTag = do- (Right json) <- getTag manager aToken anOwner aRepo aTag- let (Just (Aeson.String text)) = HashMap.lookup (Text.pack "upload_url") json- let uploadUrl = Text.unpack text- let (Right template) = Template.parseTemplate uploadUrl- pure template--getTag- :: Client.Manager- -> String- -> String- -> String- -> String- -> IO (Either String Aeson.Object)-getTag manager aToken anOwner aRepo aTag = do- let format = "https://api.github.com/repos/%s/%s/releases/tags/%s"- let url = Printf.printf format anOwner aRepo aTag- initialRequest <- Client.parseUrlThrow url- let request =- initialRequest- {Client.requestHeaders = [authorizationHeader aToken, userAgentHeader]}- response <- Client.httpLbs request manager- let body = Client.responseBody response- let json = Aeson.eitherDecode body- return json--authorizationHeader :: String -> HTTP.Header-authorizationHeader aToken =- (HTTP.hAuthorization, BS8.pack (Printf.printf "token %s" aToken))--userAgentHeader :: HTTP.Header-userAgentHeader = (HTTP.hUserAgent, BS8.pack userAgent)--userAgent :: String-userAgent = Printf.printf "%s/%s-%s" "tfausak" "github-release" versionString--versionString :: String-versionString = Version.showVersion This.version--uploadFile- :: Client.Manager- -> Template.UriTemplate- -> String- -> FilePath- -> String- -> IO (Client.Response BSL.ByteString)-uploadFile manager template aToken aFile aName = do- contents <- BSL.readFile aFile- let body = Client.RequestBodyLBS contents- uploadBody manager template aToken body aName--uploadBody- :: Client.Manager- -> Template.UriTemplate- -> String- -> Client.RequestBody- -> String- -> IO (Client.Response BSL.ByteString)-uploadBody manager template aToken body aName = do- let url =- Template.render- template- [("name", Template.WrappedValue (Template.Single aName))]- initialRequest <- Client.parseUrlThrow url- let request =- initialRequest- { Client.method = BS8.pack "POST"- , Client.requestBody = body- , Client.requestHeaders =- [ authorizationHeader aToken- , (HTTP.hContentType, MIME.defaultMimeLookup (Text.pack aName))- , userAgentHeader- ]- }- Client.httpLbs request manager
− stack.yaml
@@ -1,1 +0,0 @@-resolver: lts-8.0