Add module with an info file parser
This commit is contained in:
parent
f4b7883cf2
commit
d5df676df7
61
Rakefile
61
Rakefile
@ -92,61 +92,6 @@ module SlackBuilder
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class UniversalCtags < Updater
|
|
||||||
def update(version)
|
|
||||||
package = create_package version
|
|
||||||
|
|
||||||
uri = "https://github.com/universal-ctags/ctags/archive/#{version}/ctags-#{version}.tar.gz"
|
|
||||||
tarball = "slackbuilds/development/universal-ctags/ctags-#{version}.tar.gz"
|
|
||||||
checksum = SlackBuilder.download URI(uri), tarball
|
|
||||||
download = "https://download.dlackware.com/hosted-sources/universal-ctags/ctags-#{version}.tar.gz"
|
|
||||||
|
|
||||||
write_info package, downloads: [Download.new(download, checksum)]
|
|
||||||
update_slackbuild_version 'development/universal-ctags', version
|
|
||||||
sh 'scp', tarball, "#{CONFIG[:remote_path]}/universal-ctags"
|
|
||||||
|
|
||||||
commit 'development/universal-ctags', version
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def create_package(version)
|
|
||||||
Package.new 'development/universal-ctags',
|
|
||||||
version: version,
|
|
||||||
homepage: 'https://ctags.io/',
|
|
||||||
requires: ['%README%']
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Composer < Updater
|
|
||||||
def update(version)
|
|
||||||
package = Package.new 'development/composer',
|
|
||||||
version: version,
|
|
||||||
homepage: 'https://getcomposer.org/'
|
|
||||||
|
|
||||||
uri = "https://getcomposer.org/download/#{version}/composer.phar"
|
|
||||||
checksum = SlackBuilder.download URI(uri), 'slackbuilds/development/composer/composer.phar'
|
|
||||||
write_info package, downloads: [Download.new(uri, checksum)]
|
|
||||||
update_slackbuild_version 'development/composer', version
|
|
||||||
|
|
||||||
commit 'development/composer', version
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class JitsiMeetDesktop < Updater
|
|
||||||
def update(version)
|
|
||||||
package = Package.new 'network/jitsi-meet-desktop',
|
|
||||||
version: version,
|
|
||||||
homepage: 'https://jitsi.org/'
|
|
||||||
uri = "https://github.com/jitsi/jitsi-meet-electron/releases/download/v#{version}/jitsi-meet-x86_64.AppImage"
|
|
||||||
checksum = SlackBuilder.download URI(uri), 'slackbuilds/network/jitsi-meet-desktop/jitsi-meet-x86_64.AppImage'
|
|
||||||
|
|
||||||
write_info package, downloads: [Download.new(uri, checksum, is64: true)]
|
|
||||||
update_slackbuild_version 'network/jitsi-meet-desktop', version
|
|
||||||
commit 'network/jitsi-meet-desktop', version
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class PHP < Updater
|
class PHP < Updater
|
||||||
def update(version)
|
def update(version)
|
||||||
package = Package.new 'development/php82',
|
package = Package.new 'development/php82',
|
||||||
@ -167,15 +112,9 @@ module SlackBuilder
|
|||||||
end
|
end
|
||||||
|
|
||||||
AUTO_UPDATABLE = {
|
AUTO_UPDATABLE = {
|
||||||
'universal-ctags' => [SlackBuilder::GitHub.new('universal-ctags', 'ctags'), SlackBuilder::UniversalCtags.new],
|
|
||||||
'composer' => [SlackBuilder::Packagist.new('composer', 'composer'), SlackBuilder::Composer.new],
|
|
||||||
'php82' => [SlackBuilder::GitHub.new('php', 'php-src', 'php'), SlackBuilder::PHP.new],
|
'php82' => [SlackBuilder::GitHub.new('php', 'php-src', 'php'), SlackBuilder::PHP.new],
|
||||||
'rdiff-backup' => [SlackBuilder::GitHub.new('rdiff-backup', 'rdiff-backup', 'rdiff-backup')],
|
'rdiff-backup' => [SlackBuilder::GitHub.new('rdiff-backup', 'rdiff-backup', 'rdiff-backup')],
|
||||||
'librsync' => [SlackBuilder::GitHub.new('librsync', 'librsync')],
|
'librsync' => [SlackBuilder::GitHub.new('librsync', 'librsync')],
|
||||||
'jitsi-meet-desktop' => [
|
|
||||||
SlackBuilder::GitHub.new('jitsi', 'jitsi-meet-electron'),
|
|
||||||
SlackBuilder::JitsiMeetDesktop.new
|
|
||||||
],
|
|
||||||
'dmd' => [SlackBuilder::LatestText.new('https://downloads.dlang.org/releases/LATEST')]
|
'dmd' => [SlackBuilder::LatestText.new('https://downloads.dlang.org/releases/LATEST')]
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
|
21
app/Main.hs
21
app/Main.hs
@ -70,6 +70,25 @@ autoUpdatable =
|
|||||||
, requires = mempty
|
, requires = mempty
|
||||||
, reupload = False
|
, reupload = False
|
||||||
}
|
}
|
||||||
|
, Package
|
||||||
|
{ latest =
|
||||||
|
let ghArguments = GhArguments
|
||||||
|
{ owner = "jitsi"
|
||||||
|
, name = "jitsi-meet-electron"
|
||||||
|
, transform = Nothing
|
||||||
|
}
|
||||||
|
latest' = latestGitHub ghArguments $ Text.stripPrefix "v"
|
||||||
|
template = Package.DownloadTemplate
|
||||||
|
$ Package.StaticPlaceholder "https://github.com/jitsi/jitsi-meet-electron/releases/download/v"
|
||||||
|
:| Package.VersionPlaceholder
|
||||||
|
: [Package.StaticPlaceholder "/jitsi-meet-x86_64.AppImage"]
|
||||||
|
in Package.Updater latest' template
|
||||||
|
, category = "network"
|
||||||
|
, name = "jitsi-meet-desktop"
|
||||||
|
, homepage = Just [uri|https://jitsi.org/|]
|
||||||
|
, requires = mempty
|
||||||
|
, reupload = False
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
up2Date :: SlackBuilderT ()
|
up2Date :: SlackBuilderT ()
|
||||||
@ -134,8 +153,6 @@ main = do
|
|||||||
Text.IO.putStrLn $ fromMaybe "" latestVersion
|
Text.IO.putStrLn $ fromMaybe "" latestVersion
|
||||||
where
|
where
|
||||||
executeCommand = \case
|
executeCommand = \case
|
||||||
PackagistCommand packagistArguments ->
|
|
||||||
latestPackagist packagistArguments
|
|
||||||
TextCommand textArguments -> latestText textArguments
|
TextCommand textArguments -> latestText textArguments
|
||||||
GhCommand ghArguments@GhArguments{ transform }
|
GhCommand ghArguments@GhArguments{ transform }
|
||||||
-> latestGitHub ghArguments $ chooseTransformFunction transform
|
-> latestGitHub ghArguments $ chooseTransformFunction transform
|
||||||
|
@ -20,8 +20,7 @@ import Options.Applicative
|
|||||||
)
|
)
|
||||||
|
|
||||||
data SlackBuilderCommand
|
data SlackBuilderCommand
|
||||||
= PackagistCommand PackagistArguments
|
= TextCommand TextArguments
|
||||||
| TextCommand TextArguments
|
|
||||||
| GhCommand GhArguments
|
| GhCommand GhArguments
|
||||||
| SlackBuildCommand Text Text
|
| SlackBuildCommand Text Text
|
||||||
| CommitCommand Text Text
|
| CommitCommand Text Text
|
||||||
@ -47,11 +46,6 @@ data GhArguments = GhArguments
|
|||||||
newtype TextArguments = TextArguments Text
|
newtype TextArguments = TextArguments Text
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
packagistArguments :: Parser PackagistArguments
|
|
||||||
packagistArguments = PackagistArguments
|
|
||||||
<$> argument str (metavar "VENDOR")
|
|
||||||
<*> argument str (metavar"NAME")
|
|
||||||
|
|
||||||
textArguments :: Parser TextArguments
|
textArguments :: Parser TextArguments
|
||||||
textArguments = TextArguments <$> argument str (metavar "URL")
|
textArguments = TextArguments <$> argument str (metavar "URL")
|
||||||
|
|
||||||
@ -66,8 +60,7 @@ slackBuilderParser = info slackBuilderCommand fullDesc
|
|||||||
|
|
||||||
slackBuilderCommand :: Parser SlackBuilderCommand
|
slackBuilderCommand :: Parser SlackBuilderCommand
|
||||||
slackBuilderCommand = subparser
|
slackBuilderCommand = subparser
|
||||||
$ command "packagist" (info (PackagistCommand <$> packagistArguments) mempty)
|
$ command "text" (info (TextCommand <$> textArguments) mempty)
|
||||||
<> command "text" (info (TextCommand <$> textArguments) mempty)
|
|
||||||
<> command "github" (info (GhCommand <$> ghArguments) mempty)
|
<> command "github" (info (GhCommand <$> ghArguments) mempty)
|
||||||
<> command "slackbuild" (info slackBuildCommand mempty)
|
<> command "slackbuild" (info slackBuildCommand mempty)
|
||||||
<> command "commit" (info commitCommand mempty)
|
<> command "commit" (info commitCommand mempty)
|
||||||
|
156
lib/SlackBuilder/Info.hs
Normal file
156
lib/SlackBuilder/Info.hs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
module SlackBuilder.Info
|
||||||
|
( PackageInfo(..)
|
||||||
|
, generate
|
||||||
|
, parseInfoFile
|
||||||
|
, update
|
||||||
|
, updateDownloadVersion
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad.Combinators (sepBy)
|
||||||
|
import qualified Data.ByteArray as ByteArray
|
||||||
|
import Data.ByteString (ByteString)
|
||||||
|
import qualified Data.ByteString as ByteString
|
||||||
|
import qualified Data.ByteString.Char8 as Char8
|
||||||
|
import qualified Data.List.NonEmpty as NonEmpty
|
||||||
|
import Data.Maybe (mapMaybe)
|
||||||
|
import Data.Text (Text)
|
||||||
|
import qualified Data.Text as Text
|
||||||
|
import qualified Data.Text.Encoding as Text
|
||||||
|
import qualified Data.Text.Lazy as Lazy.Text
|
||||||
|
import qualified Data.Text.Lazy.Builder as Text.Builder
|
||||||
|
import qualified Data.Text.Lazy.Builder as Text (Builder)
|
||||||
|
import Crypto.Hash (Digest, MD5, digestFromByteString)
|
||||||
|
import Data.Void (Void)
|
||||||
|
import Data.Word (Word8)
|
||||||
|
import Numeric (readHex, showHex)
|
||||||
|
import Text.Megaparsec (Parsec, count, eof, takeWhile1P)
|
||||||
|
import Text.Megaparsec.Byte (space, string, hexDigitChar)
|
||||||
|
import Text.URI
|
||||||
|
( Authority(..)
|
||||||
|
, URI(..)
|
||||||
|
, mkPathPiece
|
||||||
|
, parserBs
|
||||||
|
, render
|
||||||
|
, unRText
|
||||||
|
)
|
||||||
|
|
||||||
|
type GenParser = Parsec Void ByteString
|
||||||
|
|
||||||
|
data PackageInfo = PackageInfo
|
||||||
|
{ pkgname :: String
|
||||||
|
, version :: Text
|
||||||
|
, homepage :: Text
|
||||||
|
, downloads :: [URI]
|
||||||
|
, checksums :: [Digest MD5]
|
||||||
|
} deriving (Eq, Show)
|
||||||
|
|
||||||
|
variableEntry :: ByteString -> GenParser ByteString
|
||||||
|
variableEntry variable = string (Char8.append variable "=\"")
|
||||||
|
*> takeWhile1P Nothing (0x22 /=)
|
||||||
|
<* string "\"\n"
|
||||||
|
|
||||||
|
variableSeparator :: GenParser ()
|
||||||
|
variableSeparator = string " \\" *> space
|
||||||
|
|
||||||
|
packageDownloads :: GenParser [URI]
|
||||||
|
packageDownloads = string "DOWNLOAD=\""
|
||||||
|
*> sepBy parserBs variableSeparator
|
||||||
|
<* string "\"\n"
|
||||||
|
|
||||||
|
hexDigit :: GenParser Word8
|
||||||
|
hexDigit =
|
||||||
|
let digitPair = count 2 hexDigitChar
|
||||||
|
in fst . head . readHex . fmap (toEnum . fromIntegral) <$> digitPair
|
||||||
|
|
||||||
|
packageChecksum :: GenParser ByteString
|
||||||
|
packageChecksum = ByteString.pack <$> count 16 hexDigit
|
||||||
|
|
||||||
|
packageChecksums :: GenParser [ByteString]
|
||||||
|
packageChecksums = string "MD5SUM=\""
|
||||||
|
*> sepBy packageChecksum variableSeparator
|
||||||
|
<* string "\"\n"
|
||||||
|
|
||||||
|
parseInfoFile :: GenParser PackageInfo
|
||||||
|
parseInfoFile = PackageInfo
|
||||||
|
<$> (Char8.unpack <$> variableEntry "PKGNAM")
|
||||||
|
<*> (Text.decodeUtf8 <$> variableEntry "VERSION")
|
||||||
|
<*> (Text.decodeUtf8 <$> variableEntry "HOMEPAGE")
|
||||||
|
<*> packageDownloads
|
||||||
|
<*> (mapMaybe digestFromByteString <$> packageChecksums)
|
||||||
|
<* eof
|
||||||
|
|
||||||
|
updateDownloadVersion :: PackageInfo -> Text -> Maybe String -> [URI]
|
||||||
|
updateDownloadVersion package toVersion gnomeVersion
|
||||||
|
= updateDownload (version package) toVersion gnomeVersion
|
||||||
|
<$> downloads package
|
||||||
|
|
||||||
|
updateDownload :: Text -> Text -> Maybe String -> URI -> URI
|
||||||
|
updateDownload fromVersion toVersion gnomeVersion
|
||||||
|
= updateCoreVersion fromVersion toVersion gnomeVersion
|
||||||
|
. updatePackageVersion fromVersion toVersion gnomeVersion
|
||||||
|
|
||||||
|
updatePackageVersion :: Text -> Text -> Maybe String -> URI -> URI
|
||||||
|
updatePackageVersion fromVersion toVersion _gnomeVersion download = download
|
||||||
|
{ uriPath = uriPath download >>= traverse (traverse updatePathPiece)
|
||||||
|
}
|
||||||
|
where
|
||||||
|
updatePathPiece = mkPathPiece
|
||||||
|
. Text.replace fromMajor toMajor
|
||||||
|
. Text.replace fromVersion toVersion
|
||||||
|
. unRText
|
||||||
|
fromMajor = major fromVersion
|
||||||
|
toMajor = major toVersion
|
||||||
|
|
||||||
|
major :: Text -> Text
|
||||||
|
major = Text.intercalate "." . take 2 . Text.splitOn "."
|
||||||
|
|
||||||
|
updateCoreVersion :: Text -> Text -> Maybe String -> URI -> URI
|
||||||
|
updateCoreVersion _fromVersion _toVersion (Just gnomeVersion) download
|
||||||
|
| Just (False, pathPieces) <- uriPath download
|
||||||
|
, (beforeCore, afterCore) <- NonEmpty.break (comparePathPiece "core") pathPieces
|
||||||
|
, _ : _ : _ : sources : afterSources <- afterCore
|
||||||
|
, comparePathPiece "sources" sources && not (null afterSources)
|
||||||
|
, Right Authority{..} <- uriAuthority download
|
||||||
|
, ".gnome.org" `Text.isSuffixOf` unRText authHost
|
||||||
|
, Nothing <- authPort =
|
||||||
|
download { uriPath = buildPath beforeCore afterSources }
|
||||||
|
where
|
||||||
|
comparePathPiece this that = Just that == mkPathPiece this
|
||||||
|
buildPath beforeCore afterSources = do
|
||||||
|
core <- mkPathPiece "core"
|
||||||
|
let textGnomeVersion = Text.pack gnomeVersion
|
||||||
|
minorGnomeVersion <- mkPathPiece $ major textGnomeVersion
|
||||||
|
patchGnomeVersion <- mkPathPiece textGnomeVersion
|
||||||
|
sources <- mkPathPiece "sources"
|
||||||
|
let afterCore = core : minorGnomeVersion : patchGnomeVersion : sources : afterSources
|
||||||
|
(False,) <$> NonEmpty.nonEmpty (beforeCore ++ afterCore)
|
||||||
|
updateCoreVersion _ _ _ download = download
|
||||||
|
|
||||||
|
update :: PackageInfo -> Text -> [URI] -> [Digest MD5] -> PackageInfo
|
||||||
|
update old toVersion downloads' checksums' = old
|
||||||
|
{ version = toVersion
|
||||||
|
, downloads = downloads'
|
||||||
|
, checksums = checksums'
|
||||||
|
}
|
||||||
|
|
||||||
|
generate :: PackageInfo -> Text
|
||||||
|
generate pkg = Lazy.Text.toStrict $ Text.Builder.toLazyText builder
|
||||||
|
where
|
||||||
|
digestToText = Text.pack . foldr hexAppender "" . ByteArray.unpack
|
||||||
|
hexAppender x acc
|
||||||
|
| x > 15 = showHex x acc
|
||||||
|
| otherwise = '0' : showHex x acc
|
||||||
|
builder = "PKGNAM=\"" <> Text.Builder.fromString (pkgname pkg) <> "\"\n"
|
||||||
|
<> "VERSION=\"" <> Text.Builder.fromText (version pkg) <> "\"\n"
|
||||||
|
<> "HOMEPAGE=\"" <> Text.Builder.fromText (homepage pkg) <> "\"\n"
|
||||||
|
<> generateMultiEntry "DOWNLOAD" (render <$> downloads pkg)
|
||||||
|
<> generateMultiEntry "MD5SUM" (digestToText <$> checksums pkg)
|
||||||
|
|
||||||
|
generateMultiEntry :: Text -> [Text] -> Text.Builder
|
||||||
|
generateMultiEntry name entries = Text.Builder.fromText name
|
||||||
|
<> "=\""
|
||||||
|
<> Text.Builder.fromText (Text.intercalate separator entries)
|
||||||
|
<> "\"\n"
|
||||||
|
where
|
||||||
|
padLength = Text.length name + 2
|
||||||
|
separator = " \\\n" <> Text.replicate padLength " "
|
@ -35,20 +35,6 @@ module SlackBuilder
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Request the latest version from the packagist API.
|
|
||||||
class Packagist < Repository
|
|
||||||
def initialize(vendor, name)
|
|
||||||
super()
|
|
||||||
|
|
||||||
@vendor = vendor
|
|
||||||
@name = name
|
|
||||||
end
|
|
||||||
|
|
||||||
def latest
|
|
||||||
`./bin/slackbuilder packagist #{@vendor} #{@name}`.strip
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Reads a remote LATEST file.
|
# Reads a remote LATEST file.
|
||||||
class LatestText < Repository
|
class LatestText < Repository
|
||||||
def initialize(latest_url)
|
def initialize(latest_url)
|
||||||
|
@ -18,9 +18,13 @@ extra-source-files: CHANGELOG.md
|
|||||||
common dependencies
|
common dependencies
|
||||||
build-depends:
|
build-depends:
|
||||||
base ^>= 4.16.4.0,
|
base ^>= 4.16.4.0,
|
||||||
|
bytestring ^>= 0.11.0,
|
||||||
cryptonite >= 0.30,
|
cryptonite >= 0.30,
|
||||||
filepath ^>= 1.4.2,
|
filepath ^>= 1.4.2,
|
||||||
|
megaparsec ^>= 9.5,
|
||||||
modern-uri ^>= 0.3.6,
|
modern-uri ^>= 0.3.6,
|
||||||
|
memory ^>= 0.18,
|
||||||
|
parser-combinators ^>= 1.3,
|
||||||
text ^>= 2.0,
|
text ^>= 2.0,
|
||||||
tomland ^>= 1.3.3,
|
tomland ^>= 1.3.3,
|
||||||
transformers ^>= 0.5.6
|
transformers ^>= 0.5.6
|
||||||
@ -28,18 +32,21 @@ common dependencies
|
|||||||
default-extensions:
|
default-extensions:
|
||||||
DataKinds
|
DataKinds
|
||||||
DuplicateRecordFields
|
DuplicateRecordFields
|
||||||
|
ExplicitForAll
|
||||||
LambdaCase
|
LambdaCase
|
||||||
NamedFieldPuns
|
NamedFieldPuns
|
||||||
OverloadedStrings
|
OverloadedStrings
|
||||||
RecordWildCards
|
RecordWildCards
|
||||||
QuasiQuotes
|
QuasiQuotes
|
||||||
TemplateHaskell
|
TemplateHaskell
|
||||||
|
TupleSections
|
||||||
TypeApplications
|
TypeApplications
|
||||||
|
|
||||||
library
|
library
|
||||||
import: dependencies
|
import: dependencies
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
SlackBuilder.Config
|
SlackBuilder.Config
|
||||||
|
SlackBuilder.Info
|
||||||
SlackBuilder.Package
|
SlackBuilder.Package
|
||||||
SlackBuilder.Trans
|
SlackBuilder.Trans
|
||||||
hs-source-dirs: lib
|
hs-source-dirs: lib
|
||||||
@ -58,7 +65,6 @@ executable slackbuilder
|
|||||||
SlackBuilder.Updater
|
SlackBuilder.Updater
|
||||||
build-depends:
|
build-depends:
|
||||||
aeson ^>= 2.2.0,
|
aeson ^>= 2.2.0,
|
||||||
bytestring ^>= 0.11.0,
|
|
||||||
conduit ^>= 1.3.5,
|
conduit ^>= 1.3.5,
|
||||||
http-client ^>= 0.7,
|
http-client ^>= 0.7,
|
||||||
optparse-applicative ^>= 0.18.1,
|
optparse-applicative ^>= 0.18.1,
|
||||||
@ -77,10 +83,12 @@ test-suite slackbuilder-test
|
|||||||
main-is: Spec.hs
|
main-is: Spec.hs
|
||||||
|
|
||||||
other-modules:
|
other-modules:
|
||||||
|
SlackBuilder.InfoSpec
|
||||||
SlackBuilder.PackageSpec
|
SlackBuilder.PackageSpec
|
||||||
hs-source-dirs: tests
|
hs-source-dirs: tests
|
||||||
build-depends:
|
build-depends:
|
||||||
hspec >= 2.10.9 && < 2.12,
|
hspec >= 2.10.9 && < 2.12,
|
||||||
|
hspec-megaparsec ^>= 2.2,
|
||||||
slackbuilder
|
slackbuilder
|
||||||
|
|
||||||
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
|
ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
|
||||||
|
139
tests/SlackBuilder/InfoSpec.hs
Normal file
139
tests/SlackBuilder/InfoSpec.hs
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
module SlackBuilder.InfoSpec
|
||||||
|
( spec
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Crypto.Hash (Digest, MD5, digestFromByteString)
|
||||||
|
import qualified Data.ByteString as ByteString
|
||||||
|
import Data.ByteString.Char8 (ByteString)
|
||||||
|
import Data.Maybe (maybeToList)
|
||||||
|
import qualified Data.Text.Encoding as Text
|
||||||
|
import Data.Void (Void)
|
||||||
|
import SlackBuilder.Info
|
||||||
|
import Test.Hspec (Spec, describe, it, shouldBe)
|
||||||
|
import Test.Hspec.Megaparsec (parseSatisfies, shouldSucceedOn)
|
||||||
|
import Text.Megaparsec (parse)
|
||||||
|
import Text.Megaparsec.Error (ParseErrorBundle)
|
||||||
|
import Text.URI (mkURI)
|
||||||
|
|
||||||
|
parseInfoFile'
|
||||||
|
:: ByteString
|
||||||
|
-> Either (ParseErrorBundle ByteString Void) PackageInfo
|
||||||
|
parseInfoFile' = parse parseInfoFile ""
|
||||||
|
|
||||||
|
infoDownload0 :: ByteString
|
||||||
|
infoDownload0 = "PKGNAM=\"pkgnam\"\n\
|
||||||
|
\VERSION=\"1.2.3\"\n\
|
||||||
|
\HOMEPAGE=\"homepage\"\n\
|
||||||
|
\DOWNLOAD=\"\"\n\
|
||||||
|
\MD5SUM=\"\"\n"
|
||||||
|
|
||||||
|
infoDownload1 :: ByteString
|
||||||
|
infoDownload1 = "PKGNAM=\"pkgnam\"\n\
|
||||||
|
\VERSION=\"1.2.3\"\n\
|
||||||
|
\HOMEPAGE=\"homepage\"\n\
|
||||||
|
\DOWNLOAD=\"https://dlackware.com/download.tar.gz\"\n\
|
||||||
|
\MD5SUM=\"0102030405060708090a0b0c0d0e0f10\"\n"
|
||||||
|
|
||||||
|
maybeToDoubleList :: forall a. Maybe a -> [a]
|
||||||
|
maybeToDoubleList xs = [y | x <- maybeToList xs, y <- [x, x]]
|
||||||
|
|
||||||
|
checksumSample :: [Digest MD5]
|
||||||
|
checksumSample = maybeToList $ digestFromByteString (ByteString.pack [1 .. 16])
|
||||||
|
|
||||||
|
spec :: Spec
|
||||||
|
spec = do
|
||||||
|
describe "parseInfoFile" $ do
|
||||||
|
it "returns package on a valid input" $
|
||||||
|
parseInfoFile' `shouldSucceedOn` infoDownload1
|
||||||
|
|
||||||
|
it "returns an array with one element if one download is given" $
|
||||||
|
let condition = (== 1) . length . checksums
|
||||||
|
in parseInfoFile' infoDownload1 `parseSatisfies` condition
|
||||||
|
|
||||||
|
it "translates checksum characters into the binary format" $
|
||||||
|
let expected = "0102030405060708090a0b0c0d0e0f10"
|
||||||
|
condition = (== expected) . show . head . checksums
|
||||||
|
in parseInfoFile' infoDownload1 `parseSatisfies` condition
|
||||||
|
|
||||||
|
it "accepts an empty downloads list" $
|
||||||
|
parseInfoFile' `shouldSucceedOn` infoDownload0
|
||||||
|
|
||||||
|
describe "generate" $ do
|
||||||
|
it "generates an .info file without downloads" $
|
||||||
|
let given = PackageInfo "pkgnam" "1.2.3" "homepage" [] []
|
||||||
|
in generate given `shouldBe` Text.decodeUtf8 infoDownload0
|
||||||
|
|
||||||
|
it "splits multiple downloads into multiple lines" $
|
||||||
|
let downloads' = maybeToDoubleList
|
||||||
|
$ mkURI "https://dlackware.com/download.tar.gz"
|
||||||
|
checksums' = maybeToDoubleList
|
||||||
|
$ digestFromByteString (ByteString.pack [1.. 16])
|
||||||
|
given = PackageInfo
|
||||||
|
"pkgnam" "1.2.3" "homepage" downloads' checksums'
|
||||||
|
expected = "PKGNAM=\"pkgnam\"\n\
|
||||||
|
\VERSION=\"1.2.3\"\n\
|
||||||
|
\HOMEPAGE=\"homepage\"\n\
|
||||||
|
\DOWNLOAD=\"https://dlackware.com/download.tar.gz \\\n\
|
||||||
|
\ https://dlackware.com/download.tar.gz\"\n\
|
||||||
|
\MD5SUM=\"0102030405060708090a0b0c0d0e0f10 \\\n\
|
||||||
|
\ 0102030405060708090a0b0c0d0e0f10\"\n"
|
||||||
|
in generate given `shouldBe` expected
|
||||||
|
|
||||||
|
it "prints the checksum as a sequence of hexadecimal numbers" $
|
||||||
|
let downloads' = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/download.tar.gz"
|
||||||
|
given = PackageInfo
|
||||||
|
"pkgnam" "1.2.3" "homepage" downloads' checksumSample
|
||||||
|
in generate given `shouldBe` Text.decodeUtf8 infoDownload1
|
||||||
|
|
||||||
|
describe "updateDownloadVersion" $ do
|
||||||
|
it "replaces the version" $
|
||||||
|
let downloads' = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/download-1.2.3.tar.gz"
|
||||||
|
testPackage = PackageInfo
|
||||||
|
"pkgnam" "1.2.3" "homepage" downloads' checksumSample
|
||||||
|
expected = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/download-2.3.4.tar.gz"
|
||||||
|
actual = updateDownloadVersion testPackage "2.3.4" Nothing
|
||||||
|
in actual `shouldBe` expected
|
||||||
|
|
||||||
|
it "updates the major version" $
|
||||||
|
let downloads' = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/1.2/download.tar.gz"
|
||||||
|
testPackage = PackageInfo
|
||||||
|
"pkgnam" "1.2.3" "homepage" downloads' checksumSample
|
||||||
|
expected = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/2.3/download.tar.gz"
|
||||||
|
actual = updateDownloadVersion testPackage "2.3.4" Nothing
|
||||||
|
in actual `shouldBe` expected
|
||||||
|
|
||||||
|
it "updates gnome version" $
|
||||||
|
let downloads' = maybeToList
|
||||||
|
$ mkURI "https://download.gnome.org/core/3.36/3.36.0/sources/gnome-calendar-3.36.0.tar.xz"
|
||||||
|
testPackage = PackageInfo
|
||||||
|
"gnome-calendar" "3.36.0" "https://wiki.gnome.org/Core/Calendar" downloads' checksumSample
|
||||||
|
expected = maybeToList
|
||||||
|
$ mkURI "https://download.gnome.org/core/3.36/3.36.4/sources/gnome-calendar-3.36.2.tar.xz"
|
||||||
|
actual = updateDownloadVersion testPackage "3.36.2" $ Just "3.36.4"
|
||||||
|
in actual `shouldBe` expected
|
||||||
|
|
||||||
|
it "updates versions without a patch number" $
|
||||||
|
let downloads' = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/gnome-contacts-3.36.tar.xz"
|
||||||
|
testPackage = PackageInfo
|
||||||
|
"gnome-contacts" "3.36" "homepage" downloads' checksumSample
|
||||||
|
expected = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/gnome-contacts-3.36.2.tar.xz"
|
||||||
|
actual = updateDownloadVersion testPackage "3.36.2" Nothing
|
||||||
|
in actual `shouldBe` expected
|
||||||
|
|
||||||
|
describe "update" $
|
||||||
|
it "replaces the version" $
|
||||||
|
let downloads' = maybeToList
|
||||||
|
$ mkURI "https://dlackware.com/1.2/download.tar.gz"
|
||||||
|
testPackage = PackageInfo
|
||||||
|
"pkgnam" "1.2.3" "homepage" downloads' checksumSample
|
||||||
|
expected = PackageInfo
|
||||||
|
"pkgnam" "2.3.4" "homepage" downloads' checksumSample
|
||||||
|
given = update testPackage "2.3.4" downloads' checksumSample
|
||||||
|
in given `shouldBe` expected
|
Loading…
Reference in New Issue
Block a user