jenkinsPlugins2nix (empty) → 0.1.0.0
raw patch · 10 files changed
+641/−0 lines, 10 filesdep +ansi-wl-pprintdep +attoparsecdep +basesetup-changed
Dependencies added: ansi-wl-pprint, attoparsec, base, bytestring, containers, cryptohash, data-fix, hnix, http-conduit, jenkinsPlugins2nix, mtl, tasty-hspec, text, zip-archive
Files
- LICENSE +30/−0
- README.md +18/−0
- Setup.hs +2/−0
- app/Main.hs +53/−0
- jenkinsPlugins2nix.cabal +61/−0
- src/Nix/JenkinsPlugins2Nix.hs +131/−0
- src/Nix/JenkinsPlugins2Nix/Parser.hs +145/−0
- src/Nix/JenkinsPlugins2Nix/Types.hs +92/−0
- test/Nix/JenkinsPlugins2Nix/Tests/Parser.hs +101/−0
- test/Spec.hs +8/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Mateusz Kowalczyk (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Mateusz Kowalczyk nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,18 @@+# jenkinsPlugins2nix++```+jenkinsPlugins2nix: PLUGIN_NAME{:PLUGIN_VERSION} [PLUGIN_NAME{:PLUGIN_VERSION} ...]+```++Along with recent nixpkgs, you can then do the following.++```+jenkinsPlugins2nix github-api > plugins.nix++```++and in your `configuration.nix`:++```+services.jenkins.plugins = pkgs.callPackage plugins.nix {};+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,53 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module : Nix.JenkinsPlugins2Nix.Types+-- Copyright : (c) 2017 Mateusz Kowalczyk+-- License : BSD3+--+-- @jenkinsPlugins2nix@ entry point.+module Main (main) where++import Data.Monoid ((<>))+import qualified Data.Text as Text+import Nix.JenkinsPlugins2Nix+import Nix.JenkinsPlugins2Nix.Types+import System.Environment+import System.Exit+import System.IO+import qualified Text.PrettyPrint.ANSI.Leijen as Pretty++usage :: Handle -> IO ()+usage h = do+ pName <- getProgName+ hPutStrLn h $+ pName <> ": PLUGIN_NAME{:PLUGIN_VERSION} [PLUGIN_NAME{:PLUGIN_VERSION} ...]"++main :: IO ()+main = do+ getArgs >>= \case+ [] -> do+ usage stderr+ exitFailure+ [v] | v == "-h" || v == "--help" -> do+ usage stdout+ exitSuccess+ plugins -> do+ mkExprsFor (map parseRequestedPlugin plugins) >>= \case+ Left err -> do+ hPutStrLn stderr err+ exitFailure+ Right p -> do+ Pretty.putDoc p+ exitSuccess+ where+ parseRequestedPlugin :: String -> RequestedPlugin+ parseRequestedPlugin p = case break (== ':') p of+ (n, ':' : ver) -> RequestedPlugin+ { requested_name = Text.pack n+ , requested_version = Just (Text.pack ver)+ }+ _ -> RequestedPlugin+ { requested_name = Text.pack p+ , requested_version = Nothing+ }
+ jenkinsPlugins2nix.cabal view
@@ -0,0 +1,61 @@+name: jenkinsPlugins2nix+version: 0.1.0.0+synopsis: Generate nix for Jenkins plugins.+description: Generate nix for Jenkins plugins.+homepage: https://github.com/Fuuzetsu/jenkinsPlugins2nix#readme+license: BSD3+license-file: LICENSE+author: Mateusz Kowalczyk+maintainer: fuuzetsu@fuuzetsu.com+copyright: 2017 Mateusz Kowalczyk+category: Nix+build-type: Simple+extra-source-files: README.md+cabal-version: >=1.10++library+ hs-source-dirs: src+ exposed-modules: Nix.JenkinsPlugins2Nix+ Nix.JenkinsPlugins2Nix.Parser+ Nix.JenkinsPlugins2Nix.Types+ build-depends: base >= 4.7 && < 5+ , ansi-wl-pprint+ , attoparsec+ , bytestring+ , containers+ , cryptohash+ , data-fix+ , hnix+ , http-conduit+ , mtl+ , text+ , zip-archive+ default-language: Haskell2010+ ghc-options: -Wall++executable jenkinsPlugins2nix+ hs-source-dirs: app+ main-is: Main.hs+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall+ build-depends: base+ , ansi-wl-pprint+ , jenkinsPlugins2nix+ , text+ default-language: Haskell2010++test-suite jenkinsPlugins2nix-test+ type: exitcode-stdio-1.0+ hs-source-dirs: test+ main-is: Spec.hs+ other-modules: Nix.JenkinsPlugins2Nix.Tests.Parser+ build-depends: base+ , containers+ , jenkinsPlugins2nix+ , tasty-hspec+ , text+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall+ default-language: Haskell2010++source-repository head+ type: git+ location: https://github.com/Fuuzetsu/jenkinsPlugins2nix
+ src/Nix/JenkinsPlugins2Nix.hs view
@@ -0,0 +1,131 @@+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module : Nix.JenkinsPlugins2Nix.Types+-- Copyright : (c) 2017 Mateusz Kowalczyk+-- License : BSD3+--+-- Main library entry point.+module Nix.JenkinsPlugins2Nix where++import qualified Codec.Archive.Zip as Zip+import Control.Monad (foldM)+import qualified Control.Monad.Except as MTL+import qualified Crypto.Hash as Hash+import qualified Data.ByteString.Lazy as BSL+import Data.Map.Strict (Map)+import qualified Data.Map.Strict as Map+import Data.Monoid ((<>))+import Data.Text (Text)+import qualified Data.Text as Text+import qualified Data.Text.Encoding as Text+import qualified Data.Text.IO as Text+import qualified Network.HTTP.Simple as HTTP+import qualified Nix.Expr as Nix+import qualified Nix.JenkinsPlugins2Nix.Parser as Parser+import Nix.JenkinsPlugins2Nix.Types+import qualified Nix.Pretty as Nix+import System.IO (stderr)+import qualified Text.PrettyPrint.ANSI.Leijen as Pretty+import Text.Printf (printf)++-- | Get the download URL of the plugin we're looking for.+getPluginUrl :: RequestedPlugin -> Text+getPluginUrl (RequestedPlugin { requested_name = n, requested_version = Just v })+ = Text.pack+ $ printf "https://updates.jenkins-ci.org/download/plugins/%s/%s/%s.hpi"+ (Text.unpack n) (Text.unpack v) (Text.unpack n)+getPluginUrl (RequestedPlugin { requested_name = n, requested_version = Nothing })+ = Text.pack+ $ printf "https://updates.jenkins-ci.org/latest/%s.hpi"+ (Text.unpack n)++-- | Download a plugin from 'getPluginUrl'.+downloadPlugin :: RequestedPlugin -> IO (Either String Plugin)+downloadPlugin p = do+ let fullUrl = getPluginUrl p+ Text.hPutStrLn stderr $ "Downloading " <> fullUrl+ req <- HTTP.parseRequest $ Text.unpack fullUrl+ archiveLBS <- HTTP.getResponseBody <$> HTTP.httpLBS req+ let manifestFileText = fmap (Text.decodeUtf8 . BSL.toStrict . Zip.fromEntry)+ $ Zip.findEntryByPath "META-INF/MANIFEST.MF"+ $ Zip.toArchive archiveLBS+ case manifestFileText of+ Nothing -> return $ Left "Could not find manifest file in the archive."+ Just t -> return $! case Parser.runParseManifest t of+ Left err -> Left err+ Right manifest' -> Right $! Plugin+ -- We have to account for user not specifying the version.+ -- If they haven't, we downloaded the latest version and do+ -- not have a URL pointing at static resource. We do+ -- however have the version of the package now so we can+ -- reconstruct the URL.+ { download_url = getPluginUrl $+ p { requested_version = Just $! plugin_version manifest' }+ , sha256 = Hash.hashlazy archiveLBS+ , manifest = manifest'+ }++-- | Download the given plugin as well as recursively download its dependencies.+downloadPluginsRecursive :: Map Text Plugin -- ^ Already downloaded plugins.+ -> RequestedPlugin -- ^ Plugins we're asked to download.+ -> MTL.ExceptT String IO (Map Text Plugin)+downloadPluginsRecursive m p = if Map.member (requested_name p) m+ then return m+ else do+ plugin <- MTL.ExceptT $ downloadPlugin p+ foldM (\m' p' -> downloadPluginsRecursive m' $+ RequestedPlugin { requested_name = plugin_dependency_name p'+ , requested_version = Just $ plugin_dependency_version p'+ })+ (Map.insert (requested_name p) plugin m)+ (plugin_dependencies $ manifest plugin)++-- | Pretty-print nix expression for all the given plugins and their+-- dependencies that the user asked for.+mkExprsFor :: [RequestedPlugin]+ -> IO (Either String Pretty.Doc)+mkExprsFor ps = do+ eplugins <- MTL.runExceptT $ do+ plugins <- foldM downloadPluginsRecursive Map.empty ps+ return $ Map.elems plugins+ return $! case eplugins of+ Left err -> Left err+ Right plugins ->+ let args = Nix.mkParamset exprs+ res = Nix.mkNonRecSet $ map formatPlugin plugins+ mkJenkinsPlugin = Nix.bindTo "mkJenkinsPlugin" $+ Nix.mkFunction (Nix.mkParamset+ [ ("name", Nothing)+ , ("src", Nothing)+ ]) $+ Nix.mkApp (Nix.mkSym "stdenv.mkDerivation") $ Nix.mkNonRecSet+ [ Nix.inherit [ Nix.StaticKey "name"+ , Nix.StaticKey "src" ]+ , "phases" Nix.$= Nix.mkStr "installPhase"+ , "installPhase" Nix.$= Nix.mkStr "cp $src $out"+ ]+ in return $ Nix.prettyNix+ $ Nix.mkFunction args+ $ Nix.mkLets [mkJenkinsPlugin] res++ where+ fetchurl :: Plugin -> Nix.NExpr+ fetchurl p = Nix.mkApp (Nix.mkSym "fetchurl") $+ Nix.mkNonRecSet [ "url" Nix.$= Nix.mkUri (download_url p)+ , "sha256" Nix.$= Nix.mkStr (Text.pack . show $ sha256 p)+ ]++ mkBody :: Plugin -> Nix.NExpr+ mkBody p = Nix.mkApp (Nix.mkSym "mkJenkinsPlugin") $+ Nix.mkNonRecSet $ [ "name" Nix.$= Nix.mkStr (short_name $ manifest p)+ , "src" Nix.$= fetchurl p+ ]++ formatPlugin :: Plugin -> Nix.Binding Nix.NExpr+ formatPlugin p = short_name (manifest p) Nix.$= mkBody p++ exprs :: [(Text, Maybe Nix.NExpr)]+ exprs =+ [ ("stdenv", Nothing)+ , ("fetchurl", Nothing)+ ]
+ src/Nix/JenkinsPlugins2Nix/Parser.hs view
@@ -0,0 +1,145 @@+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module : Nix.JenkinsPlugins2Nix.Types+-- Copyright : (c) 2017 Mateusz Kowalczyk+-- License : BSD3+--+-- Parsers.+module Nix.JenkinsPlugins2Nix.Parser+ ( parseManifest+ , runParseManifest+ ) where++import Control.Applicative+import Control.Monad (void)+import qualified Data.Attoparsec.Text as A+import Data.Either (either)+import Data.Map.Strict (Map)+import qualified Data.Map.Strict as Map+import Data.Monoid ((<>))+import Data.Set (Set)+import qualified Data.Set as Set+import Data.Text (Text)+import qualified Data.Text as Text+import Nix.JenkinsPlugins2Nix.Types++-- | Run parser on manifest file contents.+runParseManifest :: Text -> Either String Manifest+runParseManifest = A.parseOnly parseManifest++-- | 'Manifest' parser.+parseManifest :: A.Parser Manifest+parseManifest = do+ kvs <- kvMap+ let getKey :: Text -> Either String Text+ getKey k = case Map.lookup k kvs of+ Nothing -> Left $ "Could not find " <> Text.unpack k <> " in " <> show kvs+ Just v -> Right v++ getKeyParsing :: Text -> A.Parser a -> Either String a+ getKeyParsing k p = getKey k >>= A.parseOnly p++ eManifest :: Either String Manifest+ eManifest = do+ manifest_version' <- getKey "Manifest-Version"+ archiver_version' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Archiver-Version"+ created_by' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Created-By"+ built_by' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Built-By"+ build_jdk' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Build-Jdk"+ extension_name' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Extension-Name"+ specification_title' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Specification-Title"+ implementation_title' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Implementation-Title"+ implementation_version' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Implementation-Version"+ group_id' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Group-Id"+ short_name' <- getKey "Short-Name"+ long_name' <- getKey "Long-Name"+ url' <- getKey "Url"+ plugin_version' <- getKey "Plugin-Version"+ hudson_version' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Hudson-Version"+ jenkins_version' <- either (\_ -> Right Nothing) (return . Just) $+ getKey "Jenkins-Version"+ plugin_dependencies' <- either (\_ -> Right Set.empty) return $+ getKeyParsing "Plugin-Dependencies" parsePluginDependencies+ plugin_developers' <- either (\_ -> Right Set.empty) return $+ getKeyParsing "Plugin-Developers" parsePluginDevelopers+ return $! Manifest+ { manifest_version = manifest_version'+ , archiver_version = archiver_version'+ , created_by = created_by'+ , built_by = built_by'+ , build_jdk = build_jdk'+ , extension_name = extension_name'+ , specification_title = specification_title'+ , implementation_title = implementation_title'+ , implementation_version = implementation_version'+ , group_id = group_id'+ , short_name = short_name'+ , long_name = long_name'+ , url = url'+ , plugin_version = plugin_version'+ , hudson_version = hudson_version'+ , jenkins_version = jenkins_version'+ , plugin_dependencies = plugin_dependencies'+ , plugin_developers = plugin_developers'+ }+ case eManifest of+ Left err -> fail err+ Right m -> return m+ where+ parsePluginDevelopers :: A.Parser (Set Text)+ parsePluginDevelopers = Set.fromList . Text.splitOn "," <$> A.takeText++ parsePluginDependencies :: A.Parser (Set PluginDependency)+ parsePluginDependencies =+ let plugin = do+ name <- A.takeWhile1 (/= ':') <* A.char ':'+ version <- A.takeWhile1 (\c -> c /= ',' && c /= ';')+ resolution <- A.peekChar >>= \case+ -- end of input+ Nothing -> return Mandatory+ -- next dependency+ Just ',' -> A.char ',' *> return Mandatory+ -- specifier+ Just ';' -> do+ _ <- A.string ";resolution:="+ A.takeWhile1 (/= ',') >>= \case+ "optional" -> return Optional+ res' -> fail $ "Don't know how to parse resolution: " <> Text.unpack res'+ Just c -> fail $ "plugin: expected , or ; but got: " <> [c]++ -- Consume trailing comma if any+ void (A.char ',') <|> return ()+ return $! PluginDependency+ { plugin_dependency_name = name+ , plugin_dependency_version = version+ , plugin_dependency_resolution = resolution+ }+ in Set.fromList <$> many plugin++ -- Lines in manifest can span multiple file lines as long as they+ -- are indented with a space on next physical line.+ kvEntry :: A.Parser (Text, Text)+ kvEntry = do+ key <- A.takeWhile1 (/= ':')+ A.anyChar *> A.skipSpace+ let restOfLine = A.takeTill A.isEndOfLine <* (A.endOfLine <|> return ())+ indentedLine = A.peekChar' >>= \case+ ' ' -> A.skipSpace *> restOfLine+ _ -> fail "indentedLine doesn't start with a space"++ valueLines <- (:) <$> restOfLine <*> many indentedLine+ return $! (key, Text.concat valueLines)++ kvMap :: A.Parser (Map Text Text)+ kvMap = Map.fromList <$> many kvEntry
+ src/Nix/JenkinsPlugins2Nix/Types.hs view
@@ -0,0 +1,92 @@+{-# LANGUAGE StrictData #-}+-- |+-- Module : Nix.JenkinsPlugins2Nix.Types+-- Copyright : (c) 2017 Mateusz Kowalczyk+-- License : BSD3+--+-- Types used through-out jenkinsPlugins2nix+module Nix.JenkinsPlugins2Nix.Types+ ( Manifest(..)+ , Plugin(..)+ , PluginDependency(..)+ , PluginResolution(..)+ , RequestedPlugin(..)+ ) where++import qualified Crypto.Hash as Hash+import Data.Set (Set)+import Data.Text (Text)++-- | Plugin that user requested on the command line.+data RequestedPlugin = RequestedPlugin+ { -- | Name of the plugin.+ requested_name :: !Text+ -- | Possibly a specified version. If version not present, latest+ -- version is downloaded then pinned.+ , requested_version :: !(Maybe Text)+ } deriving (Show, Eq, Ord)++-- | Plugin resolution. Determines optional plugins.+data PluginResolution = Mandatory | Optional+ deriving (Show, Eq, Ord)++-- | A dependency on another plugin.+data PluginDependency = PluginDependency+ { -- | Is the dependency optional?+ plugin_dependency_resolution :: !PluginResolution+ -- | Name of the dependency.+ , plugin_dependency_name :: !Text+ -- | Version of the dependency.+ , plugin_dependency_version :: !Text+ } deriving (Show, Eq, Ord)++-- | All the information we need about the plugin to generate a nix+-- expression.+data Plugin = Plugin+ { -- | Download location of the plugin.+ download_url :: !Text+ -- | Checksum.+ , sha256 :: !(Hash.Digest Hash.SHA256)+ -- | Manifest information of the plugin.+ , manifest :: !Manifest+ } deriving (Show, Eq, Ord)++-- | Plugin meta-data.+data Manifest = Manifest+ { -- | @Manifest-Version@.+ manifest_version :: !Text+ -- | @Archiver-Version@.+ , archiver_version :: !(Maybe Text)+ -- | @Created-By@.+ , created_by :: !(Maybe Text)+ -- | @Built-By@.+ , built_by :: !(Maybe Text)+ -- | @Build-Jdk@.+ , build_jdk :: !(Maybe Text)+ -- | @Extension-Name@.+ , extension_name :: !(Maybe Text)+ -- | @Specification-Title@.+ , specification_title :: !(Maybe Text)+ -- | @Implementation-Title@.+ , implementation_title :: !(Maybe Text)+ -- | @Implementation-Version@.+ , implementation_version :: !(Maybe Text)+ -- | @Group-Id@.+ , group_id :: !(Maybe Text)+ -- | @Short-Name@.+ , short_name :: !Text+ -- | @Long-Name@.+ , long_name :: !Text+ -- | @Url@.+ , url :: !Text+ -- | @Plugin-Version@.+ , plugin_version :: !Text+ -- | @Hudson-Version@.+ , hudson_version :: !(Maybe Text)+ -- | @Jenkins-Version@.+ , jenkins_version :: !(Maybe Text)+ -- | @Plugin-Dependencies@.+ , plugin_dependencies :: !(Set PluginDependency)+ -- | @Plugin-Developers@.+ , plugin_developers :: !(Set Text)+ } deriving (Show, Eq, Ord)
+ test/Nix/JenkinsPlugins2Nix/Tests/Parser.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE OverloadedStrings #-}+-- |+-- Module : Nix.JenkinsPlugins2Nix.Types+-- Copyright : (c) 2017 Mateusz Kowalczyk+-- License : BSD3+--+-- Parser tests.+module Nix.JenkinsPlugins2Nix.Tests.Parser (spec) where++import qualified Data.Set as Set+import qualified Data.Text as Text+import Nix.JenkinsPlugins2Nix.Parser (runParseManifest)+import Nix.JenkinsPlugins2Nix.Types+import qualified Test.Tasty.Hspec as Hspec++spec :: Hspec.Spec+spec = Hspec.describe "parser spec" $ do+ Hspec.it "parser github-pullrequest manifest" githubPr++githubPr :: Hspec.Expectation+githubPr = Right expected `Hspec.shouldBe` runParseManifest githubPrManifestText+ where+ pluginDependencies :: Set.Set PluginDependency+ pluginDependencies = Set.fromList+ [ PluginDependency { plugin_dependency_resolution = Mandatory+ , plugin_dependency_name = "github"+ , plugin_dependency_version = "1.22.1" }+ , PluginDependency { plugin_dependency_resolution = Mandatory+ , plugin_dependency_name = "workflow-step-api"+ , plugin_dependency_version = "1.14" }+ , PluginDependency { plugin_dependency_resolution = Optional+ , plugin_dependency_name = "block-queued-job"+ , plugin_dependency_version = "0.2.0" }+ , PluginDependency { plugin_dependency_resolution = Optional+ , plugin_dependency_name = "email-ext"+ , plugin_dependency_version = "2.38.2" }+ , PluginDependency { plugin_dependency_resolution = Mandatory+ , plugin_dependency_name = "github-api"+ , plugin_dependency_version = "1.80" }+ , PluginDependency { plugin_dependency_resolution = Optional+ , plugin_dependency_name = "job-dsl"+ , plugin_dependency_version = "1.38" }+ , PluginDependency { plugin_dependency_resolution = Optional+ , plugin_dependency_name = "jucies"+ , plugin_dependency_version = "0.2.1" }+ , PluginDependency { plugin_dependency_resolution = Mandatory+ , plugin_dependency_name = "matrix-project"+ , plugin_dependency_version = "1.6" }+ , PluginDependency { plugin_dependency_resolution = Optional+ , plugin_dependency_name = "token-macro"+ , plugin_dependency_version = "1.10" }+ ]++ expected :: Manifest+ expected = Manifest+ { manifest_version = "1.0"+ , archiver_version = Just "Plexus Archiver"+ , created_by = Just "Apache Maven"+ , built_by = Just "integer"+ , build_jdk = Just "1.8.0_112"+ , extension_name = Just "github-pullrequest"+ , specification_title = Just "GitHub Integration Plugin for Jenkins"+ , implementation_title = Just "github-pullrequest"+ , implementation_version = Just "0.1.0-rc24"+ , group_id = Just "org.jenkins-ci.plugins"+ , short_name = "github-pullrequest"+ , long_name = "GitHub Integration Plugin"+ , url = "https://wiki.jenkins-ci.org/display/JENKINS/GitHub+Integration+Plugin"+ , plugin_version = "0.1.0-rc24"+ , hudson_version = Just "1.625.3"+ , jenkins_version = Just "1.625.3"+ , plugin_dependencies = pluginDependencies+ , plugin_developers = Set.fromList ["Kanstantsin Shautsou:KostyaSha:"]+ }++githubPrManifestText :: Text.Text+githubPrManifestText = Text.intercalate "\r\n"+ [ "Manifest-Version: 1.0"+ , "Archiver-Version: Plexus Archiver"+ , "Created-By: Apache Maven"+ , "Built-By: integer"+ , "Build-Jdk: 1.8.0_112"+ , "Extension-Name: github-pullrequest"+ , "Specification-Title: GitHub Integration Plugin for Jenkins"+ , "Implementation-Title: github-pullrequest"+ , "Implementation-Version: 0.1.0-rc24"+ , "Group-Id: org.jenkins-ci.plugins"+ , "Short-Name: github-pullrequest"+ , "Long-Name: GitHub Integration Plugin"+ , "Url: https://wiki.jenkins-ci.org/display/JENKINS/GitHub+Integration+Pl"+ , " ugin"+ , "Plugin-Version: 0.1.0-rc24"+ , "Hudson-Version: 1.625.3"+ , "Jenkins-Version: 1.625.3"+ , "Plugin-Dependencies: github:1.22.1,workflow-step-api:1.14,block-queued"+ , " -job:0.2.0;resolution:=optional,email-ext:2.38.2;resolution:=optional"+ , " ,github-api:1.80,job-dsl:1.38;resolution:=optional,jucies:0.2.1;resol"+ , " ution:=optional,matrix-project:1.6,token-macro:1.10;resolution:=optio"+ , " nal"+ , "Plugin-Developers: Kanstantsin Shautsou:KostyaSha:"+ ]
+ test/Spec.hs view
@@ -0,0 +1,8 @@+module Main where++import qualified Nix.JenkinsPlugins2Nix.Tests.Parser as Parser+import qualified Test.Tasty.Hspec as Hspec++main :: IO ()+main = Hspec.hspec $ do+ Parser.spec