arch-hs 0.1.0.0 → 0.1.1.0
raw patch · 8 files changed
+133/−79 lines, 8 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Distribution.ArchHs.Hackage: getLatestSHA256 :: Members [HackageEnv, WithMyErr] r => PackageName -> Sem r String
+ Distribution.ArchHs.PkgBuild: [_enableUusi] :: PkgBuild -> Bool
+ Distribution.ArchHs.PkgBuild: [_sha256sums] :: PkgBuild -> String
- Distribution.ArchHs.Core: cabalToPkgBuild :: Members [HackageEnv, FlagAssignmentsEnv, WithMyErr] r => SolvedPackage -> PkgList -> Sem r PkgBuild
+ Distribution.ArchHs.Core: cabalToPkgBuild :: Members [HackageEnv, FlagAssignmentsEnv, WithMyErr] r => SolvedPackage -> PkgList -> Bool -> Sem r PkgBuild
- Distribution.ArchHs.PkgBuild: PkgBuild :: String -> String -> String -> String -> String -> String -> String -> String -> Maybe String -> Bool -> PkgBuild
+ Distribution.ArchHs.PkgBuild: PkgBuild :: String -> String -> String -> String -> String -> String -> String -> String -> String -> Maybe String -> Bool -> Bool -> PkgBuild
- Distribution.ArchHs.PkgBuild: felixTemplate :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text
+ Distribution.ArchHs.PkgBuild: felixTemplate :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text
Files
- CHANGELOG.md +4/−0
- README.md +73/−55
- app/Args.hs +5/−0
- app/Main.hs +8/−5
- arch-hs.cabal +2/−2
- src/Distribution/ArchHs/Core.hs +8/−6
- src/Distribution/ArchHs/Hackage.hs +13/−5
- src/Distribution/ArchHs/PkgBuild.hs +20/−6
CHANGELOG.md view
@@ -3,6 +3,10 @@ `arch-hs` uses [PVP Versioning][1]. The changelog is available [on GitHub][2]. +## 0.1.1.0++* Add uusi option+ ## 0.1.0.0 * Support sub-libraries ([#16](https://github.com/berberman/arch-hs/issues/16))
README.md view
@@ -69,70 +69,66 @@ ## Usage Just run `arch-hs` in command line with options and a target. Here is an example:-we will create the archlinux package of `dhall-lsp-server`:+we will create the archlinux package of [accelerate](https://hackage.haskell.org/package/accelerate): ```-$ arch-hs -o "/home/berberman/Desktop/test/" dhall-lsp-server+$ arch-hs -o ~/test accelerate ...... ⓘ Recommended package order (from topological sort):-1. haskell-lsp-types-2. haskell-lsp-3. dhall-lsp-server+1. unique+2. tasty-kat+3. accelerate - ⓘ Detected flags from targets (their values will keep default unless you specify):-haskell-lsp- ⚐ demo:- description: Build the lsp-hello demo executable- default: False- isManual: False+...... - ⓘ Write file: /home/berberman/Desktop/test/dhall-lsp-server/PKGBUILD- ⓘ Write file: /home/berberman/Desktop/test/haskell-lsp/PKGBUILD- ⓘ Write file: /home/berberman/Desktop/test/haskell-lsp-types/PKGBUILD+ ⓘ Write file: /home/berberman/test/haskell-accelerate/PKGBUILD+ ⓘ Write file: /home/berberman/test/haskell-unique/PKGBUILD+ ⓘ Write file: /home/berberman/test/haskell-tasty-kat/PKGBUILD ✔ Success! ``` -This message tells us that in order to package `dhall-lsp-server`, we must package `haskell-lsp-types`-and `haskell-lsp` sequentially, because they don't present in archlinux community repo.+This message tells us that in order to package `accelerate`, we must package `unique`+and `tasty-kat` first sequentially, because `accelerate` dependens on them to build or test,+whereas they are not present in archlinux community repo. ```+$ tree ~/test /home/berberman/Desktop/test-├── dhall-lsp-server-│ └── PKGBUILD-├── haskell-lsp-│ └── PKGBUILD-└── haskell-lsp-types+├── haskell-accelerate+│ └── PKGBUILD+├── haskell-tasty-kat+│ └── PKGBUILD+└── haskell-unique └── PKGBUILD ``` -`arch-hs` will generate PKGBUILD for each packages. Let's see what we have in `./haskell-lsp/PKGBUILD`:+`arch-hs` will generate PKGBUILD for each package. Let's see what we have in `./haskell-accelerate/PKGBUILD`: ``` bash # This file was generated by arch-hs, please check it manually. # Maintainer: Your Name <youremail@domain.com> -_hkgname=haskell-lsp-pkgname=haskell-lsp-pkgver=0.22.0.0+# This file was generated by arch-hs, please check it manually.+# Maintainer: Your Name <youremail@domain.com>++_hkgname=accelerate+pkgname=haskell-accelerate+pkgver=1.3.0.0 pkgrel=1-pkgdesc="Haskell library for the Microsoft Language Server Protocol"-url="https://github.com/alanz/haskell-lsp"-license=("custom:MIT")+pkgdesc="An embedded language for accelerated array processing"+url="https://github.com/AccelerateHS/accelerate/"+license=("custom:BSD3") arch=('x86_64')-depends=('ghc-libs' 'haskell-aeson' 'haskell-async' 'haskell-attoparsec' 'haskell-data-default' 'haskell-hashable' 'haskell-lsp-types' 'haskell-hslogger' 'haskell-lens' 'haskell-network-uri' 'haskell-rope-utf16-splay' 'haskell-sorted-list' 'haskell-temporary' 'haskell-unordered-containers' 'haskell-vector')-makedepends=('ghc' 'haskell-quickcheck' 'haskell-hspec' 'haskell-hspec-discover' 'haskell-quickcheck-instances')+depends=('ghc-libs' 'haskell-ansi-terminal' 'haskell-base-orphans' 'haskell-cryptonite' 'haskell-half' 'haskell-hashable' 'haskell-hashtables' 'haskell-hedgehog' 'haskell-lens' 'haskell-prettyprinter' 'haskell-prettyprinter-ansi-terminal' 'haskell-primitive' 'haskell-tasty' 'haskell-terminal-size' 'haskell-unique' 'haskell-unordered-containers' 'haskell-vector')+makedepends=('ghc' 'haskell-doctest') source=("https://hackage.haskell.org/packages/archive/$_hkgname/$pkgver/$_hkgname-$pkgver.tar.gz")-sha256sums=('SKIP')--prepare(){- cd $_hkgname-$pkgver-}+sha256sums=('4b97161f145c81f7554679802059598587e06d49b2c153e7bafc4dd6974bad92') build() {- cd $_hkgname-$pkgver + cd $_hkgname-$pkgver runhaskell Setup configure -O --enable-shared --enable-executable-dynamic --disable-library-vanilla \ --prefix=/usr --docdir=/usr/share/doc/$pkgname --enable-tests \@@ -158,72 +154,93 @@ install -D -m744 register.sh "$pkgdir"/usr/share/haskell/register/$pkgname.sh install -D -m744 unregister.sh "$pkgdir"/usr/share/haskell/unregister/$pkgname.sh runhaskell Setup copy --destdir="$pkgdir"- install -D -m644 "LICENSE" "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"- rm -f "${pkgdir}/usr/share/doc/${pkgname}/LICENSE"+ install -D -m644 LICENSE -t "$pkgdir"/usr/share/licenses/$pkgname/+ rm -f "$pkgdir"/usr/share/doc/$pkgname/LICENSE } ``` `arch-hs` will collect the information from hackage db, and apply it into a fixed template after some processing steps including renaming, matching license, and filling out dependencies etc.-If the package doesn't have test suits, `check()` will be removed. However, packaging haven't been done so far.+However, packaging haven't been done so far. `arch-hs` may does well statically, but we should guarantee that this package can be built by ghc with the latest dependencies;-hence some patchs may be required in `prepare()`.+hence some patchs may be required in `prepare()`, such as [uusi](#Uusi). ## Options ### Output+ ```-$ arch-hs -o "/home/berberman/Desktop/test/" termonad+$ arch-hs -o ~/test TARGET ``` -This will generate a series of PKGBUILD including `termonad` with its dependencies into the output dir.+Using `-o` can generate a series of PKGBUILD including `TARGET` with its dependencies into the output dir. If you don't pass it, only dependency calculation will occur. ### Flag Assignments ```-$ arch-hs -f inline-c:gsl-example:true termonad+$ arch-hs -f TARGET:FLAG_A:true TARGET ``` -Using `-f` can pass flags, which may affect the results of rsolving. +Using `-f` can pass flags, which may affect the results of resolving. ### AUR Searching+ ```-$ arch-hs -a termonad+$ arch-hs -a TARGET ``` -Using `-a` can regard AUR as another package provider. `arch-hs` will try to search missing packages in AUR.+With `-a`, `arch-hs` will regard AUR as another package provider, and it will try to search missing packages in AUR as well. ### Skipping Components+ ```-$ arch-hs -s termonad-test termonad+$ arch-hs -s COMPONENT_A TARGET ``` -Using `-s` can force skip runnable components in dependency rsolving.+Using `-s` can force skip runnable components in dependency resolving. This is useful when a package doesn't provide flag to disable its runnables, which will be built by default but are trivial in system level packaging. Notice that this only makes sense in the lifetime of `arch-hs`, whereas generated PKGBUILD and actual build processes will not be affected. ### Extra Cabal Files ```-$ arch-hs -e /home/berberman/arch-hs/arch-hs.cabal arch-hs+$ arch-hs -e ~/TARGET/TARGET.cabal TARGET ``` -Using `-e` can include extra `.cabal` files as supplementary. Useful when the target like `arch-hs` hasn't been released to hackage. +**For Testing Purposes Only** +Using `-e` can include extra `.cabal` files as supplementary. Useful when the `TARGET` hasn't been released to hackage.+ ### Trace ```-$ arch-hs --trace termonad+$ arch-hs --trace TARGET ``` -Using `--trace` can print the process of dependency resolving into stdout.+With `--trace`, `arch-hs` can print the process of dependency resolving into stdout. ```-$ arch-hs --trace-file foo.log termonad+$ arch-hs --trace-file foo.log TARGET ``` Similar to `--trace`, but the log will be written into a file. +### Uusi++```+$ arch-hs -o ~/test --uusi TARGET+```++With `--uusi`, `arch-hs` will generate following snippet for each package:++```bash+prepare() {+ uusi $_hkgname-$pkgver/$_hkgname.cabal+}+```++See [uusi](https://hackage.haskell.org/package/uusi) for details.+ ### Help ```@@ -233,7 +250,7 @@ Usage: arch-hs [-h|--hackage PATH] [-c|--community PATH] [-o|--output PATH] [-f|--flags package_name:flag_name:true|false,...] [-s|--skip component_name,...] [-e|--extra PATH_1,...] [-a|--aur]- [--trace] [--trace-file PATH] TARGET+ [--trace] [--trace-file PATH] [--uusi] TARGET Try to reach the TARGET QAQ. Available options:@@ -255,6 +272,7 @@ --trace Print trace to stdout --trace-file PATH Path to trace file (empty means do not write trace to file)+ --uusi Splicing uusi into prepare() -h,--help Show this help text ```@@ -350,7 +368,7 @@ - [ ] **Standardized pretty printing**. -- [ ] Structuralized PKGBUILD template.+- [ ] StructuralPKGBUILD template. - [x] AUR support.
app/Args.hs view
@@ -22,6 +22,7 @@ optAur :: Bool, optStdoutTrace :: Bool, optFileTrace :: FilePath,+ optUusi :: Bool, optTarget :: PackageName } deriving stock (Show)@@ -90,6 +91,10 @@ <> metavar "PATH" <> help "Path to trace file (empty means do not write trace to file)" <> value ""+ )+ <*> switch+ ( long "uusi"+ <> help "Splicing uusi into prepare()" ) <*> argument optPackageNameReader (metavar "TARGET")
app/Main.hs view
@@ -62,8 +62,9 @@ FilePath -> Bool -> [String] ->+ Bool-> Sem r ()-app target path aurSupport skip = do+app target path aurSupport skip uusi= do (deps, ignored) <- getDependencies (fmap mkUnqualComponentName skip) Nothing target inCommunity <- isInCommunity target when inCommunity $ throw $ TargetExist target ByCommunity@@ -109,9 +110,9 @@ embed $ putStrLn . prettySolvedPkgs $ filledByBoth embed $ C.infoMessage "Recommended package order (from topological sort):"- let vertexsToBeRemoved = filledByBoth ^.. each . filtered (\case ProvidedPackage _ _ -> True; _ -> False) ^.. each . pkgName+ let vertexesToBeRemoved = filledByBoth ^.. each . filtered (\case ProvidedPackage _ _ -> True; _ -> False) ^.. each . pkgName removeSelfCycle g = foldr (\n acc -> GL.removeEdge n n acc) g $ toBePacked2 ^.. each . pkgName- newGraph = GL.induce (`notElem` vertexsToBeRemoved) deps+ newGraph = GL.induce (`notElem` vertexesToBeRemoved) deps flattened <- case G.topSort . GL.skeleton $ removeSelfCycle $ newGraph of Left c -> throw . CyclicError $ toList c Right x -> return x@@ -128,7 +129,7 @@ when (not dry) $ mapM_ ( \solved -> do- pkgBuild <- cabalToPkgBuild solved $ Set.toList ignored+ pkgBuild <- cabalToPkgBuild solved (Set.toList ignored) uusi let pName = "haskell-" <> N._pkgName pkgBuild dir = path </> pName fileName = dir </> "PKGBUILD"@@ -203,6 +204,8 @@ when optAur $ C.infoMessage "You passed -a, searching AUR may takes a long time." + when optUusi $ C.infoMessage "You passed --uusi, uusi will become makedepends of each package."+ hackage <- loadHackageDB =<< if useDefaultHackage then lookupHackagePath else return optHackagePath C.infoMessage "Loading hackage..." @@ -222,7 +225,7 @@ empty <- newIORef Set.empty - runApp newHackage community optFlags optStdoutTrace optFileTrace empty (app optTarget optOutputDir optAur optSkip) >>= \case+ runApp newHackage community optFlags optStdoutTrace optFileTrace empty (app optTarget optOutputDir optAur optSkip optUusi) >>= \case Left x -> C.errorMessage $ "Runtime Error: " <> (T.pack . show $ x) _ -> C.successMessage "Success!" )
arch-hs.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: arch-hs-version: 0.1.0.0-synopsis: A program generating PKGBUILD for hackage packages.+version: 0.1.1.0+synopsis: A program generating PKGBUILD for hackage packages description: @arch-hs@ is a command-line program, which simplifies the process of producing and maintaining haskell packages for archlinux distribution by automating the
src/Distribution/ArchHs/Core.hs view
@@ -18,7 +18,7 @@ import qualified Data.Map as Map import Data.Set (Set) import qualified Data.Set as Set-import Distribution.ArchHs.Hackage (getLatestCabal)+import Distribution.ArchHs.Hackage (getLatestCabal, getLatestSHA256) import Distribution.ArchHs.Local (ghcLibList, ignoreList) import Distribution.ArchHs.PkgBuild (PkgBuild (..), mapLicense) import Distribution.ArchHs.Types@@ -226,10 +226,11 @@ ----------------------------------------------------------------------------- -- | Generate 'PkgBuild' for a 'SolvedPackage'.-cabalToPkgBuild :: Members [HackageEnv, FlagAssignmentsEnv, WithMyErr] r => SolvedPackage -> PkgList -> Sem r PkgBuild-cabalToPkgBuild pkg ignored = do+cabalToPkgBuild :: Members [HackageEnv, FlagAssignmentsEnv, WithMyErr] r => SolvedPackage -> PkgList -> Bool -> Sem r PkgBuild+cabalToPkgBuild pkg ignored uusi = do let name = pkg ^. pkgName cabal <- packageDescription <$> (getLatestCabal name)+ _sha256sums <- (\s -> "'" <> s <> "'") <$> getLatestSHA256 name let _hkgName = pkg ^. pkgName & unPackageName rawName = toLower' _hkgName _pkgName = maybe rawName id $ stripPrefix "haskell-" rawName@@ -273,14 +274,15 @@ ) && notIgnore x )- depsToString deps = deps <&> (wrap . fixName . unPackageName . _depName) & concat+ depsToString deps = deps <&> (wrap . fixName . unPackageName . _depName) & mconcat _depends = depsToString depends- _makeDepends = depsToString makeDepends+ _makeDepends = (if uusi then " 'uusi'" else "") <> depsToString makeDepends _url = getUrl cabal- wrap s = " \'" <> s <> "\'"+ wrap s = " '" <> s <> "'" notInGHCLib x = (x ^. depName) `notElem` ghcLibList notMyself x = x ^. depName /= name notIgnore x = x ^. depName `notElem` ignored selectDepKind k x = k `elem` (x ^. depType & mapped %~ dependencyTypeToKind) _licenseFile = licenseFiles cabal ^? ix 0+ _enableUusi = uusi return PkgBuild {..}
src/Distribution/ArchHs/Hackage.hs view
@@ -13,6 +13,7 @@ getCabal, getPackageFlag, traverseHackage,+ getLatestSHA256, ) where @@ -22,7 +23,7 @@ import Data.Maybe (fromJust) import Distribution.ArchHs.Types import Distribution.ArchHs.Utils (getPkgName, getPkgVersion)-import Distribution.Hackage.DB (HackageDB, VersionData (VersionData, cabalFile), readTarball)+import Distribution.Hackage.DB (HackageDB, VersionData (VersionData, cabalFile), readTarball, tarballHashes) import Distribution.PackageDescription.Parsec (parseGenericPackageDescriptionMaybe) import Distribution.Types.Flag (Flag) import Distribution.Types.GenericPackageDescription (GenericPackageDescription, genPackageFlags, packageDescription)@@ -65,15 +66,22 @@ Just x -> return x _ -> fail $ "Failed to parse .cabal from " <> path --- | Get the latest 'GenericPackageDescription'.-getLatestCabal :: Members [HackageEnv, WithMyErr] r => PackageName -> Sem r GenericPackageDescription-getLatestCabal name = do+withLatestVersion :: Members [HackageEnv, WithMyErr] r => (VersionData -> a) -> PackageName -> Sem r a+withLatestVersion f name = do db <- ask @HackageDB case Map.lookup name db of (Just m) -> case Map.lookupMax m of- Just (_, vdata) -> return $ vdata & cabalFile+ Just (_, vdata) -> return $ f vdata Nothing -> throw $ VersionError name nullVersion Nothing -> throw $ PkgNotFound name++-- | Get the latest 'GenericPackageDescription'.+getLatestCabal :: Members [HackageEnv, WithMyErr] r => PackageName -> Sem r GenericPackageDescription+getLatestCabal = withLatestVersion cabalFile++-- | Get the latest SHA256 sum of the tarball . +getLatestSHA256 :: Members [HackageEnv, WithMyErr] r => PackageName -> Sem r String+getLatestSHA256 = withLatestVersion (\vdata -> tarballHashes vdata Map.! "sha256") -- | Get 'GenericPackageDescription' with a specific version. getCabal :: Members [HackageEnv, WithMyErr] r => PackageName -> Version -> Sem r GenericPackageDescription
src/Distribution/ArchHs/PkgBuild.hs view
@@ -21,7 +21,7 @@ import Distribution.SPDX.LicenseId import NeatInterpolation (text) --- | PkgBuild data type, representing needed informations in filling the 'felixTemplate'.+-- | PkgBuild data type, representing needed information in filling the 'felixTemplate'. data PkgBuild = PkgBuild { -- | Field @_hkgName@. _hkgName :: String,@@ -39,9 +39,13 @@ _depends :: String, -- | Array @makedepends@, which has been joined into 'String' _makeDepends :: String,+ -- | Field @sha256sums@+ _sha256sums :: String, -- | License file name _licenseFile :: Maybe String,- -- | Whether generate @check()@ bash function in PKGBUILD+ -- | Whether generate @prepare()@ bash function which calls @uusi@+ _enableUusi :: Bool,+ -- | Whether generate @check()@ bash function _enableCheck :: Bool } @@ -136,10 +140,12 @@ (pack _license) (pack _depends) (pack _makeDepends)+ (pack _sha256sums) ( case _licenseFile of Just n -> "\n" <> (installLicense $ pack n) _ -> "\n" )+ (if _enableUusi then "\n" <> uusi <> "\n\n" else "\n") (if _enableCheck then "\n" <> check <> "\n\n" else "\n") -- | Text of @check()@ function.@@ -160,9 +166,17 @@ rm -f "$$pkgdir"/usr/share/doc/$$pkgname/$licenseFile |] +uusi :: Text+uusi =+ [text|+ prepare() {+ uusi $$_hkgname-$$pkgver/$$_hkgname.cabal+ }+|]+ -- | A fixed template of haskell package in archlinux. See <https://wiki.archlinux.org/index.php/Haskell_package_guidelines Haskell package guidelines> .-felixTemplate :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text-felixTemplate hkgname pkgname pkgver pkgdesc url license depends makedepends licenseF checkF =+felixTemplate :: Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text -> Text+felixTemplate hkgname pkgname pkgver pkgdesc url license depends makedepends sha256sums licenseF uusiF checkF = [text| # This file was generated by arch-hs, please check it manually. # Maintainer: Your Name <youremail@domain.com>@@ -178,8 +192,8 @@ depends=('ghc-libs'$depends) makedepends=('ghc'$makedepends) source=("https://hackage.haskell.org/packages/archive/$$_hkgname/$$pkgver/$$_hkgname-$$pkgver.tar.gz")- sha256sums=('SKIP')-+ sha256sums=($sha256sums)+ $uusiF build() { cd $$_hkgname-$$pkgver