mirror of
https://github.com/input-output-hk/foliage.git
synced 2024-09-11 20:27:09 +03:00
Merge branch 'main' into dont-autogenerate-keys
This commit is contained in:
commit
add45abbb2
10
.github/workflows/nix.yml
vendored
10
.github/workflows/nix.yml
vendored
@ -12,18 +12,16 @@ jobs:
|
||||
- ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- uses: cachix/install-nix-action@v17
|
||||
- uses: cachix/install-nix-action@v20
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
trusted-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
|
||||
substituters = https://cache.iog.io https://cache.nixos.org
|
||||
|
||||
- uses: cachix/cachix-action@v10
|
||||
- uses: cachix/cachix-action@v12
|
||||
with:
|
||||
name: foliage
|
||||
authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}'
|
||||
|
||||
- run: nix build
|
||||
- run: nix build --accept-flake-config
|
||||
|
27
.github/workflows/update-flake-lock.yml
vendored
Normal file
27
.github/workflows/update-flake-lock.yml
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
name: update-flake-lock
|
||||
|
||||
on:
|
||||
workflow_dispatch: # allows manual triggering
|
||||
schedule:
|
||||
- cron: '0 0 * * 0' # runs weekly on Sunday at 00:00
|
||||
|
||||
jobs:
|
||||
lockfile:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@v19
|
||||
with:
|
||||
extra_nix_config: |
|
||||
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Update flake.lock
|
||||
uses: DeterminateSystems/update-flake-lock@v16
|
||||
with:
|
||||
pr-title: "Update flake.lock" # Title of PR to be created
|
||||
pr-labels: | # Labels to be set on the PR
|
||||
dependencies
|
||||
automated
|
||||
- name: Print PR number
|
||||
run: echo Opened pull request ${{ steps.update.outputs.pull-request-number }}.
|
12
README.md
12
README.md
@ -273,6 +273,18 @@ metadata file `<package>/<version>/meta.toml` includes the option
|
||||
`force-version = true`, then the version in the package cabal file will be
|
||||
overwritten with `<version>`. Notice this is done after applying patches.
|
||||
|
||||
# Accessing private repositories
|
||||
|
||||
Foliage uses curl to fetch remote assets. If you need to access private
|
||||
repositories you can use one of the following methods.
|
||||
|
||||
- You can instruct curl to use a netrc file.
|
||||
- Add netrc-optional to ~/.curlrc (see [here](https://curl.se/docs/manpage.html#-K) for the places curl looks in).
|
||||
- Add the relevant credentials to ~/.netrc
|
||||
- You can also add the credentials directly to curl's configuration, e.g.
|
||||
- Add `user = "USERNAME:PASSWORD"` to .curlrc in the current directly
|
||||
- Set `CURL_HOME=$PWD`
|
||||
|
||||
## Author
|
||||
|
||||
- Andrea Bedini (@andreabedini)
|
||||
|
@ -18,7 +18,7 @@ module Distribution.PackageDescription.FieldGrammar.Copy
|
||||
where
|
||||
|
||||
import Distribution.CabalSpecVersion
|
||||
import qualified Distribution.Compat.CharParsing as P
|
||||
import Distribution.Compat.CharParsing qualified as P
|
||||
import Distribution.Compat.Newtype (Newtype, pack', unpack')
|
||||
import Distribution.Compat.Prelude
|
||||
import Distribution.Compiler (CompilerFlavor (..))
|
||||
@ -29,8 +29,8 @@ import Distribution.PackageDescription
|
||||
import Distribution.PackageDescription.FieldGrammar hiding (packageDescriptionFieldGrammar)
|
||||
import Distribution.Parsec
|
||||
import Distribution.Pretty (Pretty (..), showToken)
|
||||
import qualified Distribution.SPDX as SPDX
|
||||
import qualified Distribution.Types.Lens as L
|
||||
import Distribution.SPDX qualified as SPDX
|
||||
import Distribution.Types.Lens qualified as L
|
||||
import Distribution.Utils.Path
|
||||
import Distribution.Version (Version, VersionRange)
|
||||
import Prelude ()
|
||||
|
@ -2,14 +2,14 @@
|
||||
|
||||
module Distribution.Types.Orphans where
|
||||
|
||||
import Data.Aeson (ToJSON (toJSON))
|
||||
import Development.Shake.Classes (Hashable)
|
||||
import Distribution.Pretty (prettyShow)
|
||||
import Distribution.Types.PackageId (PackageIdentifier)
|
||||
import Distribution.Types.PackageName (PackageName)
|
||||
import Distribution.Types.Version (Version)
|
||||
import Distribution.Types.VersionRange (VersionRange)
|
||||
import Distribution.Utils.ShortText (ShortText)
|
||||
import Data.Aeson (ToJSON (toJSON))
|
||||
import Distribution.Pretty (prettyShow)
|
||||
|
||||
instance ToJSON PackageIdentifier where
|
||||
toJSON = toJSON . prettyShow
|
||||
|
@ -6,29 +6,32 @@ module Foliage.CmdBuild (cmdBuild) where
|
||||
import Codec.Archive.Tar qualified as Tar
|
||||
import Codec.Archive.Tar.Entry qualified as Tar
|
||||
import Codec.Compression.GZip qualified as GZip
|
||||
import Control.Monad (unless, when)
|
||||
import Control.Monad (unless, void, when)
|
||||
import Data.Aeson qualified as Aeson
|
||||
import Data.ByteString qualified as BS
|
||||
import Data.ByteString.Lazy qualified as BL
|
||||
import Data.ByteString.Lazy qualified as BSL
|
||||
import Data.Foldable (for_)
|
||||
import Data.List (sortOn)
|
||||
import Data.Maybe (fromMaybe)
|
||||
import Data.Text qualified as T
|
||||
import Data.Traversable (for)
|
||||
import Development.Shake
|
||||
import Development.Shake.FilePath
|
||||
import Distribution.Package
|
||||
import Distribution.Parsec (simpleParsec)
|
||||
import Distribution.Pretty (prettyShow)
|
||||
import Foliage.HackageSecurity hiding (ToJSON, toJSON)
|
||||
import Foliage.Meta
|
||||
import Foliage.Meta.Aeson ()
|
||||
import Foliage.Options
|
||||
import Foliage.Pages
|
||||
import Foliage.PrepareSdist
|
||||
import Foliage.PrepareSource (addPrepareSourceRule, prepareSource)
|
||||
import Foliage.PreparePackageVersion (PreparedPackageVersion (..), preparePackageVersion)
|
||||
import Foliage.PrepareSdist (addPrepareSdistRule)
|
||||
import Foliage.PrepareSource (addPrepareSourceRule)
|
||||
import Foliage.RemoteAsset (addFetchRemoteAssetRule)
|
||||
import Foliage.Shake
|
||||
import Foliage.Time qualified as Time
|
||||
import Hackage.Security.Util.Path (castRoot, toFilePath)
|
||||
import Network.URI (URI (uriPath, uriQuery, uriScheme), nullURI)
|
||||
import System.Directory (createDirectoryIfMissing)
|
||||
|
||||
cmdBuild :: BuildOptions -> IO ()
|
||||
cmdBuild buildOptions = do
|
||||
@ -45,7 +48,8 @@ cmdBuild buildOptions = do
|
||||
opts =
|
||||
shakeOptions
|
||||
{ shakeFiles = cacheDir,
|
||||
shakeVerbosity = Verbose
|
||||
shakeVerbosity = Verbose,
|
||||
shakeThreads = buildOptsNumThreads buildOptions
|
||||
}
|
||||
|
||||
buildAction :: BuildOptions -> Action ()
|
||||
@ -55,7 +59,8 @@ buildAction
|
||||
buildOptsCurrentTime = mCurrentTime,
|
||||
buildOptsExpireSignaturesOn = mExpireSignaturesOn,
|
||||
buildOptsInputDir = inputDir,
|
||||
buildOptsOutputDir = outputDir
|
||||
buildOptsOutputDir = outputDir,
|
||||
buildOptsWriteMetadata = doWritePackageMeta
|
||||
} = do
|
||||
outputDirRoot <- liftIO $ makeAbsolute (fromFilePath outputDir)
|
||||
|
||||
@ -94,54 +99,47 @@ buildAction
|
||||
|
||||
makeAllPackageVersionsPage currentTime outputDir packageVersions
|
||||
|
||||
for_ packageVersions $ makePackageVersionPage inputDir outputDir
|
||||
when doWritePackageMeta $
|
||||
makeMetadataFile outputDir packageVersions
|
||||
|
||||
for_ packageVersions $ \pkgMeta@PackageVersionMeta {pkgId} -> do
|
||||
void $ forP packageVersions $ makePackageVersionPage outputDir
|
||||
|
||||
void $ forP packageVersions $ \PreparedPackageVersion {pkgId, cabalFilePath} -> do
|
||||
let PackageIdentifier {pkgName, pkgVersion} = pkgId
|
||||
cabalFilePath <- maybe (originalCabalFile pkgMeta) pure (revisedCabalFile inputDir pkgMeta)
|
||||
copyFileChanged cabalFilePath (outputDir </> "index" </> prettyShow pkgName </> prettyShow pkgVersion </> prettyShow pkgName <.> "cabal")
|
||||
|
||||
cabalEntries <-
|
||||
foldMap
|
||||
( \pkgMeta@PackageVersionMeta {pkgId, pkgSpec} -> do
|
||||
let PackageVersionSpec {packageVersionTimestamp, packageVersionRevisions} = pkgSpec
|
||||
|
||||
( \PreparedPackageVersion {pkgId, pkgTimestamp, originalCabalFilePath, cabalFileRevisions} -> do
|
||||
-- original cabal file, with its timestamp (if specified)
|
||||
cabalFilePath <- originalCabalFile pkgMeta
|
||||
let cabalFileTimestamp = fromMaybe currentTime packageVersionTimestamp
|
||||
cf <- prepareIndexPkgCabal pkgId cabalFileTimestamp cabalFilePath
|
||||
let cabalFileTimestamp = fromMaybe currentTime pkgTimestamp
|
||||
cf <- prepareIndexPkgCabal pkgId cabalFileTimestamp originalCabalFilePath
|
||||
|
||||
-- all revised cabal files, with their timestamp
|
||||
revcf <-
|
||||
for packageVersionRevisions $
|
||||
\RevisionSpec {revisionTimestamp, revisionNumber} ->
|
||||
prepareIndexPkgCabal
|
||||
pkgId
|
||||
revisionTimestamp
|
||||
(cabalFileRevisionPath inputDir pkgId revisionNumber)
|
||||
revcf <- for cabalFileRevisions $ uncurry (prepareIndexPkgCabal pkgId)
|
||||
|
||||
return $ cf : revcf
|
||||
)
|
||||
packageVersions
|
||||
|
||||
targetKeys <- maybeReadKeysAt "target"
|
||||
|
||||
metadataEntries <-
|
||||
for packageVersions $ \pkg@PackageVersionMeta {pkgId, pkgSpec} -> do
|
||||
forP packageVersions $ \ppv@PreparedPackageVersion {pkgId, pkgTimestamp} -> do
|
||||
let PackageIdentifier {pkgName, pkgVersion} = pkgId
|
||||
let PackageVersionSpec {packageVersionTimestamp} = pkgSpec
|
||||
targets <- prepareIndexPkgMetadata expiryTime pkg
|
||||
targets <- prepareIndexPkgMetadata expiryTime ppv
|
||||
let path = outputDir </> "index" </> prettyShow pkgName </> prettyShow pkgVersion </> "package.json"
|
||||
liftIO $ BL.writeFile path $ renderSignedJSON targetKeys targets
|
||||
return $
|
||||
pure $
|
||||
mkTarEntry
|
||||
(renderSignedJSON targetKeys targets)
|
||||
(IndexPkgMetadata pkgId)
|
||||
(fromMaybe currentTime packageVersionTimestamp)
|
||||
(fromMaybe currentTime pkgTimestamp)
|
||||
|
||||
let tarContents = Tar.write $ sortOn Tar.entryTime (cabalEntries ++ metadataEntries)
|
||||
traced "Writing index" $ do
|
||||
BSL.writeFile (anchorPath outputDirRoot repoLayoutIndexTar) tarContents
|
||||
BSL.writeFile (anchorPath outputDirRoot repoLayoutIndexTarGz) $ GZip.compress tarContents
|
||||
BL.writeFile (anchorPath outputDirRoot repoLayoutIndexTar) tarContents
|
||||
BL.writeFile (anchorPath outputDirRoot repoLayoutIndexTarGz) $ GZip.compress tarContents
|
||||
|
||||
privateKeysRoot <- maybeReadKeysAt "root"
|
||||
privateKeysTarget <- maybeReadKeysAt "target"
|
||||
@ -226,58 +224,66 @@ buildAction
|
||||
timestampInfoSnapshot = snapshotInfo
|
||||
}
|
||||
|
||||
getPackageVersions :: FilePath -> Action [PackageVersionMeta]
|
||||
makeMetadataFile :: FilePath -> [PreparedPackageVersion] -> Action ()
|
||||
makeMetadataFile outputDir packageVersions = traced "writing metadata" $ do
|
||||
createDirectoryIfMissing True (outputDir </> "foliage")
|
||||
Aeson.encodeFile
|
||||
(outputDir </> "foliage" </> "packages.json")
|
||||
(map encodePackageVersion packageVersions)
|
||||
where
|
||||
encodePackageVersion
|
||||
PreparedPackageVersion
|
||||
{ pkgId = PackageIdentifier {pkgName, pkgVersion},
|
||||
pkgTimestamp,
|
||||
pkgVersionForce,
|
||||
pkgVersionSource
|
||||
} =
|
||||
Aeson.object
|
||||
( [ "pkg-name" Aeson..= pkgName,
|
||||
"pkg-version" Aeson..= pkgVersion,
|
||||
"url" Aeson..= sourceUrl pkgVersionSource
|
||||
]
|
||||
++ ["forced-version" Aeson..= True | pkgVersionForce]
|
||||
++ (case pkgTimestamp of Nothing -> []; Just t -> ["timestamp" Aeson..= t])
|
||||
)
|
||||
|
||||
sourceUrl :: PackageVersionSource -> URI
|
||||
sourceUrl (TarballSource uri Nothing) = uri
|
||||
sourceUrl (TarballSource uri (Just subdir)) = uri {uriQuery = "?dir=" ++ subdir}
|
||||
sourceUrl (GitHubSource repo rev Nothing) =
|
||||
nullURI
|
||||
{ uriScheme = "github:",
|
||||
uriPath = T.unpack (unGitHubRepo repo) </> T.unpack (unGitHubRev rev)
|
||||
}
|
||||
sourceUrl (GitHubSource repo rev (Just subdir)) =
|
||||
nullURI
|
||||
{ uriScheme = "github:",
|
||||
uriPath = T.unpack (unGitHubRepo repo) </> T.unpack (unGitHubRev rev),
|
||||
uriQuery = "?dir=" ++ subdir
|
||||
}
|
||||
|
||||
getPackageVersions :: FilePath -> Action [PreparedPackageVersion]
|
||||
getPackageVersions inputDir = do
|
||||
metaFiles <- getDirectoryFiles inputDir ["*/*/meta.toml"]
|
||||
|
||||
when (null metaFiles) $ do
|
||||
putError $
|
||||
error $
|
||||
unlines
|
||||
[ "We could not find any package metadata file (i.e. _sources/<name>/<version>/meta.toml)",
|
||||
"Make sure you are passing the right input directory. The default input directory is _sources"
|
||||
]
|
||||
fail "no package metadata found"
|
||||
|
||||
for metaFiles $ \metaFile -> do
|
||||
let [pkgName, pkgVersion, _] = splitDirectories metaFile
|
||||
let Just name = simpleParsec pkgName
|
||||
let Just version = simpleParsec pkgVersion
|
||||
let pkgId = PackageIdentifier name version
|
||||
|
||||
pkgSpec <-
|
||||
readPackageVersionSpec' (inputDir </> metaFile) >>= \case
|
||||
PackageVersionSpec {packageVersionRevisions, packageVersionTimestamp = Nothing}
|
||||
| not (null packageVersionRevisions) -> do
|
||||
putError $
|
||||
unlines
|
||||
[ inputDir </> metaFile <> " has cabal file revisions but the original package has no timestamp.",
|
||||
"This combination doesn't make sense. Either add a timestamp on the original package or remove the revisions"
|
||||
]
|
||||
fail "invalid package metadata"
|
||||
PackageVersionSpec {packageVersionRevisions, packageVersionTimestamp = Just pkgTs}
|
||||
| any ((< pkgTs) . revisionTimestamp) packageVersionRevisions -> do
|
||||
putError $
|
||||
unlines
|
||||
[ inputDir </> metaFile <> " has a revision with timestamp earlier than the package itself.",
|
||||
"Adjust the timestamps so that all revisions come after the original package"
|
||||
]
|
||||
fail "invalid package metadata"
|
||||
meta ->
|
||||
return meta
|
||||
|
||||
return $ PackageVersionMeta pkgId pkgSpec
|
||||
forP metaFiles $ preparePackageVersion inputDir
|
||||
|
||||
prepareIndexPkgCabal :: PackageId -> UTCTime -> FilePath -> Action Tar.Entry
|
||||
prepareIndexPkgCabal pkgId timestamp filePath = do
|
||||
need [filePath]
|
||||
contents <- liftIO $ BSL.readFile filePath
|
||||
return $ mkTarEntry contents (IndexPkgCabal pkgId) timestamp
|
||||
contents <- liftIO $ BS.readFile filePath
|
||||
pure $ mkTarEntry (BL.fromStrict contents) (IndexPkgCabal pkgId) timestamp
|
||||
|
||||
prepareIndexPkgMetadata :: Maybe UTCTime -> PackageVersionMeta -> Action Targets
|
||||
prepareIndexPkgMetadata expiryTime PackageVersionMeta {pkgId, pkgSpec} = do
|
||||
srcDir <- prepareSource pkgId pkgSpec
|
||||
sdist <- prepareSdist srcDir
|
||||
targetFileInfo <- computeFileInfoSimple' sdist
|
||||
prepareIndexPkgMetadata :: Maybe UTCTime -> PreparedPackageVersion -> Action Targets
|
||||
prepareIndexPkgMetadata expiryTime PreparedPackageVersion {pkgId, sdistPath} = do
|
||||
targetFileInfo <- liftIO $ computeFileInfoSimple sdistPath
|
||||
let packagePath = repoLayoutPkgTarGz hackageRepoLayout pkgId
|
||||
return
|
||||
Targets
|
||||
@ -287,7 +293,7 @@ prepareIndexPkgMetadata expiryTime PackageVersionMeta {pkgId, pkgSpec} = do
|
||||
targetsDelegations = Nothing
|
||||
}
|
||||
|
||||
mkTarEntry :: BSL.ByteString -> IndexFile dec -> UTCTime -> Tar.Entry
|
||||
mkTarEntry :: BL.ByteString -> IndexFile dec -> UTCTime -> Tar.Entry
|
||||
mkTarEntry contents indexFile timestamp =
|
||||
(Tar.fileEntry tarPath contents)
|
||||
{ Tar.entryTime = floor $ Time.utcTimeToPOSIXSeconds timestamp,
|
||||
@ -300,8 +306,11 @@ mkTarEntry contents indexFile timestamp =
|
||||
}
|
||||
}
|
||||
where
|
||||
tarPath = case Tar.toTarPath False indexPath of
|
||||
Left e -> error $ "Invalid tar path " ++ indexPath ++ "(" ++ e ++ ")"
|
||||
Right tp -> tp
|
||||
|
||||
indexPath = toFilePath $ castRoot $ indexFileToPath hackageIndexLayout indexFile
|
||||
Right tarPath = Tar.toTarPath False indexPath
|
||||
|
||||
anchorPath :: Path Absolute -> (RepoLayout -> RepoPath) -> FilePath
|
||||
anchorPath outputDirRoot p =
|
||||
|
@ -1,3 +1,5 @@
|
||||
{-# LANGUAGE ViewPatterns #-}
|
||||
|
||||
module Foliage.CmdImportIndex
|
||||
( cmdImportIndex,
|
||||
)
|
||||
|
@ -13,7 +13,6 @@ module Foliage.Meta
|
||||
packageMetaEntryTimestamp,
|
||||
readPackageMeta,
|
||||
writePackageMeta,
|
||||
PackageVersionMeta (PackageVersionMeta, pkgId, pkgSpec),
|
||||
packageVersionTimestamp,
|
||||
packageVersionSource,
|
||||
packageVersionRevisions,
|
||||
@ -32,8 +31,6 @@ module Foliage.Meta
|
||||
UTCTime,
|
||||
latestRevisionNumber,
|
||||
consolidateRanges,
|
||||
cabalFileRevisionPath,
|
||||
revisedCabalFile,
|
||||
)
|
||||
where
|
||||
|
||||
@ -50,8 +47,6 @@ import Distribution.Aeson ()
|
||||
import Distribution.Parsec (simpleParsec)
|
||||
import Distribution.Pretty (prettyShow)
|
||||
import Distribution.Types.Orphans ()
|
||||
import Distribution.Types.PackageId (PackageIdentifier (..))
|
||||
import Distribution.Types.PackageName (unPackageName)
|
||||
import Distribution.Types.Version (Version)
|
||||
import Distribution.Types.VersionRange (VersionRange, anyVersion, intersectVersionRanges, notThisVersion)
|
||||
import Distribution.Version (isAnyVersion, isNoVersion, simplifyVersionRange)
|
||||
@ -59,7 +54,6 @@ import Foliage.Time (UTCTime)
|
||||
import GHC.Generics (Generic)
|
||||
import Network.URI (URI, parseURI)
|
||||
import Network.URI.Orphans ()
|
||||
import System.FilePath ((<.>), (</>))
|
||||
import Toml (TomlCodec, (.=))
|
||||
import Toml qualified
|
||||
|
||||
@ -86,14 +80,18 @@ writePackageMeta fp a = void $ Toml.encodeToFile packageMetaCodec fp a
|
||||
packageMetaCodec :: TomlCodec PackageMeta
|
||||
packageMetaCodec =
|
||||
PackageMeta
|
||||
<$> Toml.list packageMetaEntryCodec "entries" .= packageMetaEntries
|
||||
<$> Toml.list packageMetaEntryCodec "entries"
|
||||
.= packageMetaEntries
|
||||
|
||||
packageMetaEntryCodec :: TomlCodec PackageMetaEntry
|
||||
packageMetaEntryCodec =
|
||||
PackageMetaEntry
|
||||
<$> timeCodec "timestamp" .= packageMetaEntryTimestamp
|
||||
<*> Toml.arrayOf _VersionRange "preferred-versions" .= packageMetaEntryPreferred
|
||||
<*> Toml.arrayOf _Version "deprecated-versions" .= packageMetaEntryDeprecated
|
||||
<$> timeCodec "timestamp"
|
||||
.= packageMetaEntryTimestamp
|
||||
<*> Toml.arrayOf _VersionRange "preferred-versions"
|
||||
.= packageMetaEntryPreferred
|
||||
<*> Toml.arrayOf _Version "deprecated-versions"
|
||||
.= packageMetaEntryDeprecated
|
||||
|
||||
_Version :: Toml.TomlBiMap Version Toml.AnyValue
|
||||
_Version = Toml._TextBy showVersion parseVersion
|
||||
@ -185,10 +183,14 @@ data PackageVersionSpec = PackageVersionSpec
|
||||
sourceMetaCodec :: TomlCodec PackageVersionSpec
|
||||
sourceMetaCodec =
|
||||
PackageVersionSpec
|
||||
<$> Toml.dioptional (timeCodec "timestamp") .= packageVersionTimestamp
|
||||
<*> packageSourceCodec .= packageVersionSource
|
||||
<*> Toml.list revisionMetaCodec "revisions" .= packageVersionRevisions
|
||||
<*> withDefault False (Toml.bool "force-version") .= packageVersionForce
|
||||
<$> Toml.dioptional (timeCodec "timestamp")
|
||||
.= packageVersionTimestamp
|
||||
<*> packageSourceCodec
|
||||
.= packageVersionSource
|
||||
<*> Toml.list revisionMetaCodec "revisions"
|
||||
.= packageVersionRevisions
|
||||
<*> withDefault False (Toml.bool "force-version")
|
||||
.= packageVersionForce
|
||||
|
||||
readPackageVersionSpec :: FilePath -> IO PackageVersionSpec
|
||||
readPackageVersionSpec = Toml.decodeFile sourceMetaCodec
|
||||
@ -206,8 +208,10 @@ data RevisionSpec = RevisionSpec
|
||||
revisionMetaCodec :: TomlCodec RevisionSpec
|
||||
revisionMetaCodec =
|
||||
RevisionSpec
|
||||
<$> timeCodec "timestamp" .= revisionTimestamp
|
||||
<*> Toml.int "number" .= revisionNumber
|
||||
<$> timeCodec "timestamp"
|
||||
.= revisionTimestamp
|
||||
<*> Toml.int "number"
|
||||
.= revisionNumber
|
||||
|
||||
timeCodec :: Toml.Key -> TomlCodec UTCTime
|
||||
timeCodec key = Toml.dimap (utcToZonedTime utc) zonedTimeToUTC $ Toml.zonedTime key
|
||||
@ -231,18 +235,3 @@ consolidateRanges PackageMetaEntry {packageMetaEntryPreferred, packageMetaEntryD
|
||||
range =
|
||||
simplifyVersionRange $
|
||||
foldr intersectVersionRanges anyVersion (map notThisVersion packageMetaEntryDeprecated ++ packageMetaEntryPreferred)
|
||||
|
||||
data PackageVersionMeta = PackageVersionMeta
|
||||
{ pkgId :: PackageIdentifier,
|
||||
pkgSpec :: PackageVersionSpec
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
deriving (Generic)
|
||||
|
||||
cabalFileRevisionPath :: FilePath -> PackageIdentifier -> Int -> FilePath
|
||||
cabalFileRevisionPath inputDir PackageIdentifier {pkgName, pkgVersion} revisionNumber =
|
||||
inputDir </> unPackageName pkgName </> prettyShow pkgVersion </> "revisions" </> show revisionNumber <.> "cabal"
|
||||
|
||||
revisedCabalFile :: FilePath -> PackageVersionMeta -> Maybe FilePath
|
||||
revisedCabalFile inputDir PackageVersionMeta {pkgId, pkgSpec} = do
|
||||
cabalFileRevisionPath inputDir pkgId <$> latestRevisionNumber pkgSpec
|
||||
|
@ -1,13 +1,13 @@
|
||||
{-# LANGUAGE DerivingVia #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
{-# LANGUAGE StandaloneDeriving #-}
|
||||
{-# OPTIONS_GHC -Wno-orphans #-}
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
|
||||
module Foliage.Meta.Aeson where
|
||||
|
||||
import Distribution.Types.Orphans ()
|
||||
import Data.Aeson
|
||||
import Data.Text
|
||||
import Distribution.Types.Orphans ()
|
||||
import Foliage.Meta
|
||||
import Foliage.Utils.Aeson
|
||||
import Network.URI (URI)
|
||||
@ -20,8 +20,6 @@ deriving via MyAesonEncoding RevisionSpec instance ToJSON RevisionSpec
|
||||
|
||||
deriving via MyAesonEncoding PackageVersionSpec instance ToJSON PackageVersionSpec
|
||||
|
||||
deriving via MyAesonEncoding PackageVersionMeta instance ToJSON PackageVersionMeta
|
||||
|
||||
deriving via Text instance ToJSON GitHubRepo
|
||||
|
||||
deriving via Text instance ToJSON GitHubRev
|
||||
@ -30,8 +28,8 @@ instance ToJSON PackageVersionSource where
|
||||
toJSON =
|
||||
genericToJSON
|
||||
defaultOptions
|
||||
{ sumEncoding = ObjectWithSingleField
|
||||
, omitNothingFields = True
|
||||
{ sumEncoding = ObjectWithSingleField,
|
||||
omitNothingFields = True
|
||||
}
|
||||
|
||||
instance ToJSON URI where
|
||||
|
@ -51,7 +51,9 @@ data BuildOptions = BuildOptions
|
||||
buildOptsCurrentTime :: Maybe UTCTime,
|
||||
buildOptsExpireSignaturesOn :: Maybe UTCTime,
|
||||
buildOptsInputDir :: FilePath,
|
||||
buildOptsOutputDir :: FilePath
|
||||
buildOptsOutputDir :: FilePath,
|
||||
buildOptsNumThreads :: Int,
|
||||
buildOptsWriteMetadata :: Bool
|
||||
}
|
||||
|
||||
buildCommand :: Parser Command
|
||||
@ -90,6 +92,20 @@ buildCommand =
|
||||
<> showDefault
|
||||
<> value "_repo"
|
||||
)
|
||||
<*> option
|
||||
auto
|
||||
( long "num-jobs"
|
||||
<> short 'j'
|
||||
<> metavar "JOBS"
|
||||
<> help "Number of jobs to run in parallel, 0 is 'all available cores'"
|
||||
<> showDefault
|
||||
<> value 1
|
||||
)
|
||||
<*> switch
|
||||
( long "write-metadata"
|
||||
<> help "Write metadata in the output-directory"
|
||||
<> showDefault
|
||||
)
|
||||
)
|
||||
where
|
||||
signOpts =
|
||||
|
@ -15,10 +15,11 @@ module Foliage.Pages
|
||||
where
|
||||
|
||||
import Data.Aeson (KeyValue ((.=)), ToJSON, object)
|
||||
import Data.Function (on)
|
||||
import Data.List (groupBy, sortOn)
|
||||
import Data.Function (on, (&))
|
||||
import Data.List (sortOn)
|
||||
import Data.List.NonEmpty qualified as NE
|
||||
import Data.Maybe (fromMaybe, listToMaybe)
|
||||
import Data.Ord (Down (Down))
|
||||
import Data.Ord (Down (Down), comparing)
|
||||
import Data.Text.Lazy.IO.Utf8 qualified as TL
|
||||
import Data.Time (UTCTime)
|
||||
import Data.Time.Clock.POSIX (POSIXTime, utcTimeToPOSIXSeconds)
|
||||
@ -26,9 +27,9 @@ import Development.Shake (Action, traced)
|
||||
import Distribution.Aeson (jsonGenericPackageDescription)
|
||||
import Distribution.Package (PackageIdentifier (pkgName, pkgVersion))
|
||||
import Distribution.Pretty (prettyShow)
|
||||
import Foliage.Meta (PackageVersionMeta (..), PackageVersionSource, PackageVersionSpec (PackageVersionSpec, packageVersionRevisions, packageVersionSource, packageVersionTimestamp), RevisionSpec (RevisionSpec, revisionTimestamp), revisedCabalFile)
|
||||
import Foliage.Meta (PackageVersionSource)
|
||||
import Foliage.Meta.Aeson ()
|
||||
import Foliage.Shake (originalCabalFile, readGenericPackageDescription')
|
||||
import Foliage.PreparePackageVersion (PreparedPackageVersion (..))
|
||||
import Foliage.Utils.Aeson (MyAesonEncoding (..))
|
||||
import GHC.Generics (Generic)
|
||||
import System.Directory qualified as IO
|
||||
@ -50,34 +51,44 @@ data AllPackagesPageEntry = AllPackagesPageEntry
|
||||
allPackagesPageEntryTimestamp :: UTCTime,
|
||||
allPackagesPageEntryTimestampPosix :: POSIXTime,
|
||||
allPackagesPageEntrySource :: PackageVersionSource,
|
||||
allPackagesPageEntryRevision :: Maybe RevisionSpec
|
||||
allPackagesPageEntryLatestRevisionTimestamp :: Maybe UTCTime
|
||||
}
|
||||
deriving stock (Generic)
|
||||
deriving (ToJSON) via MyAesonEncoding AllPackagesPageEntry
|
||||
|
||||
makeAllPackagesPage :: UTCTime -> FilePath -> [PackageVersionMeta] -> Action ()
|
||||
makeAllPackagesPage currentTime outputDir packageVersions = do
|
||||
let packages =
|
||||
sortOn allPackagesPageEntryPkgId $
|
||||
map
|
||||
( ( \PackageVersionMeta {pkgId, pkgSpec = PackageVersionSpec {packageVersionTimestamp, packageVersionRevisions, packageVersionSource}} ->
|
||||
AllPackagesPageEntry
|
||||
{ allPackagesPageEntryPkgId = pkgId,
|
||||
allPackagesPageEntryTimestamp = fromMaybe currentTime packageVersionTimestamp,
|
||||
allPackagesPageEntryTimestampPosix = utcTimeToPOSIXSeconds (fromMaybe currentTime packageVersionTimestamp),
|
||||
allPackagesPageEntrySource = packageVersionSource,
|
||||
allPackagesPageEntryRevision = listToMaybe packageVersionRevisions
|
||||
}
|
||||
)
|
||||
. head
|
||||
. sortOn (Down . pkgVersion . pkgId)
|
||||
)
|
||||
$ groupBy ((==) `on` (pkgName . pkgId)) packageVersions
|
||||
makeAllPackagesPage :: UTCTime -> FilePath -> [PreparedPackageVersion] -> Action ()
|
||||
makeAllPackagesPage currentTime outputDir packageVersions =
|
||||
traced "webpages / all-packages" $ do
|
||||
IO.createDirectoryIfMissing True (outputDir </> "all-packages")
|
||||
TL.writeFile (outputDir </> "all-packages" </> "index.html") $
|
||||
renderMustache allPackagesPageTemplate $
|
||||
object ["packages" .= packages]
|
||||
where
|
||||
packages =
|
||||
packageVersions
|
||||
-- group package versions by package name
|
||||
& NE.groupBy ((==) `on` (pkgName . pkgId))
|
||||
-- for each package name pick the most recent version
|
||||
& map
|
||||
( \group ->
|
||||
group
|
||||
-- sort them from the most recent version to the least recent
|
||||
& NE.sortBy (comparing $ Down . pkgVersion . pkgId)
|
||||
-- pick the most recent version
|
||||
& NE.head
|
||||
-- turn it into the template data
|
||||
& ( \(PreparedPackageVersion {pkgId, pkgTimestamp, cabalFileRevisions, pkgVersionSource}) ->
|
||||
AllPackagesPageEntry
|
||||
{ allPackagesPageEntryPkgId = pkgId,
|
||||
allPackagesPageEntryTimestamp = fromMaybe currentTime pkgTimestamp,
|
||||
allPackagesPageEntryTimestampPosix = utcTimeToPOSIXSeconds (fromMaybe currentTime pkgTimestamp),
|
||||
allPackagesPageEntrySource = pkgVersionSource,
|
||||
allPackagesPageEntryLatestRevisionTimestamp = fst <$> listToMaybe cabalFileRevisions
|
||||
}
|
||||
)
|
||||
)
|
||||
-- sort packages by pkgId
|
||||
& sortOn allPackagesPageEntryPkgId
|
||||
|
||||
data AllPackageVersionsPageEntry
|
||||
= AllPackageVersionsPageEntryPackage
|
||||
@ -94,47 +105,49 @@ data AllPackageVersionsPageEntry
|
||||
deriving stock (Generic)
|
||||
deriving (ToJSON) via MyAesonEncoding AllPackageVersionsPageEntry
|
||||
|
||||
makeAllPackageVersionsPage :: UTCTime -> FilePath -> [PackageVersionMeta] -> Action ()
|
||||
makeAllPackageVersionsPage currentTime outputDir packageVersions = do
|
||||
let entries =
|
||||
sortOn (Down . allPackageVersionsPageEntryTimestamp) $
|
||||
foldMap
|
||||
( \PackageVersionMeta {pkgId, pkgSpec = PackageVersionSpec {packageVersionTimestamp, packageVersionRevisions, packageVersionSource}} ->
|
||||
AllPackageVersionsPageEntryPackage
|
||||
{ allPackageVersionsPageEntryPkgId = pkgId,
|
||||
allPackageVersionsPageEntryTimestamp = fromMaybe currentTime packageVersionTimestamp,
|
||||
allPackageVersionsPageEntryTimestampPosix = utcTimeToPOSIXSeconds (fromMaybe currentTime packageVersionTimestamp),
|
||||
allPackageVersionsPageEntrySource = packageVersionSource
|
||||
} :
|
||||
map
|
||||
( \RevisionSpec {revisionTimestamp} ->
|
||||
AllPackageVersionsPageEntryRevision
|
||||
{ allPackageVersionsPageEntryPkgId = pkgId,
|
||||
allPackageVersionsPageEntryTimestamp = revisionTimestamp,
|
||||
allPackageVersionsPageEntryTimestampPosix = utcTimeToPOSIXSeconds revisionTimestamp
|
||||
}
|
||||
)
|
||||
packageVersionRevisions
|
||||
)
|
||||
packageVersions
|
||||
|
||||
makeAllPackageVersionsPage :: UTCTime -> FilePath -> [PreparedPackageVersion] -> Action ()
|
||||
makeAllPackageVersionsPage currentTime outputDir packageVersions =
|
||||
traced "webpages / all-package-versions" $ do
|
||||
IO.createDirectoryIfMissing True (outputDir </> "all-package-versions")
|
||||
TL.writeFile (outputDir </> "all-package-versions" </> "index.html") $
|
||||
renderMustache allPackageVersionsPageTemplate $
|
||||
object ["entries" .= entries]
|
||||
where
|
||||
entries =
|
||||
-- collect all cabal file revisions including the original cabal file
|
||||
foldMap
|
||||
( \PreparedPackageVersion {pkgId, pkgTimestamp, pkgVersionSource, cabalFileRevisions} ->
|
||||
-- original cabal file
|
||||
AllPackageVersionsPageEntryPackage
|
||||
{ allPackageVersionsPageEntryPkgId = pkgId,
|
||||
allPackageVersionsPageEntryTimestamp = fromMaybe currentTime pkgTimestamp,
|
||||
allPackageVersionsPageEntryTimestampPosix = utcTimeToPOSIXSeconds (fromMaybe currentTime pkgTimestamp),
|
||||
allPackageVersionsPageEntrySource = pkgVersionSource
|
||||
}
|
||||
-- list of revisions
|
||||
: [ AllPackageVersionsPageEntryRevision
|
||||
{ allPackageVersionsPageEntryPkgId = pkgId,
|
||||
allPackageVersionsPageEntryTimestamp = revisionTimestamp,
|
||||
allPackageVersionsPageEntryTimestampPosix = utcTimeToPOSIXSeconds revisionTimestamp
|
||||
}
|
||||
| (revisionTimestamp, _) <- cabalFileRevisions
|
||||
]
|
||||
)
|
||||
packageVersions
|
||||
-- sort them by timestamp
|
||||
& sortOn (Down . allPackageVersionsPageEntryTimestamp)
|
||||
|
||||
makePackageVersionPage :: FilePath -> FilePath -> PackageVersionMeta -> Action ()
|
||||
makePackageVersionPage inputDir outputDir pkgMeta@PackageVersionMeta {pkgId, pkgSpec} = do
|
||||
cabalFilePath <- maybe (originalCabalFile pkgMeta) pure (revisedCabalFile inputDir pkgMeta)
|
||||
pkgDesc <- readGenericPackageDescription' cabalFilePath
|
||||
makePackageVersionPage :: FilePath -> PreparedPackageVersion -> Action ()
|
||||
makePackageVersionPage outputDir PreparedPackageVersion {pkgId, pkgTimestamp, pkgVersionSource, pkgDesc, cabalFileRevisions} = do
|
||||
traced ("webpages / package / " ++ prettyShow pkgId) $ do
|
||||
IO.createDirectoryIfMissing True (outputDir </> "package" </> prettyShow pkgId)
|
||||
TL.writeFile (outputDir </> "package" </> prettyShow pkgId </> "index.html") $
|
||||
renderMustache packageVersionPageTemplate $
|
||||
object
|
||||
[ "pkgSpec" .= pkgSpec,
|
||||
"pkgDesc" .= jsonGenericPackageDescription pkgDesc
|
||||
[ "pkgVersionSource" .= pkgVersionSource,
|
||||
"cabalFileRevisions" .= map fst cabalFileRevisions,
|
||||
"pkgDesc" .= jsonGenericPackageDescription pkgDesc,
|
||||
"pkgTimestamp" .= pkgTimestamp
|
||||
]
|
||||
|
||||
indexPageTemplate :: Template
|
||||
|
132
app/Foliage/PreparePackageVersion.hs
Normal file
132
app/Foliage/PreparePackageVersion.hs
Normal file
@ -0,0 +1,132 @@
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE PatternSynonyms #-}
|
||||
|
||||
module Foliage.PreparePackageVersion
|
||||
( PreparedPackageVersion
|
||||
( pkgId,
|
||||
pkgTimestamp,
|
||||
pkgVersionSource,
|
||||
pkgVersionForce,
|
||||
pkgDesc,
|
||||
sdistPath,
|
||||
cabalFilePath,
|
||||
originalCabalFilePath,
|
||||
cabalFileRevisions
|
||||
),
|
||||
pattern PreparedPackageVersion,
|
||||
preparePackageVersion,
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Monad (unless)
|
||||
import Data.List (sortOn)
|
||||
import Data.Ord (Down (Down))
|
||||
import Development.Shake (Action)
|
||||
import Development.Shake.FilePath (joinPath, splitDirectories)
|
||||
import Distribution.Client.Compat.Prelude (fromMaybe, prettyShow)
|
||||
import Distribution.Parsec (simpleParsec)
|
||||
import Distribution.Types.GenericPackageDescription (GenericPackageDescription (packageDescription))
|
||||
import Distribution.Types.PackageDescription (PackageDescription (package))
|
||||
import Distribution.Types.PackageId
|
||||
import Foliage.Meta (PackageVersionSource, PackageVersionSpec (..), RevisionSpec (..), UTCTime, latestRevisionNumber)
|
||||
import Foliage.PrepareSdist (prepareSdist)
|
||||
import Foliage.PrepareSource (prepareSource)
|
||||
import Foliage.Shake (readGenericPackageDescription', readPackageVersionSpec')
|
||||
import System.FilePath (takeBaseName, takeFileName, (<.>), (</>))
|
||||
|
||||
data PreparedPackageVersion = PreparedPackageVersion
|
||||
{ pkgId :: PackageId,
|
||||
pkgTimestamp :: Maybe UTCTime,
|
||||
pkgVersionSource :: PackageVersionSource,
|
||||
pkgVersionForce :: Bool,
|
||||
pkgDesc :: GenericPackageDescription,
|
||||
sdistPath :: FilePath,
|
||||
cabalFilePath :: FilePath,
|
||||
originalCabalFilePath :: FilePath,
|
||||
cabalFileRevisions :: [(UTCTime, FilePath)]
|
||||
}
|
||||
|
||||
preparePackageVersion :: FilePath -> FilePath -> Action PreparedPackageVersion
|
||||
preparePackageVersion inputDir metaFile = do
|
||||
let (name, version) = case splitDirectories metaFile of
|
||||
[n, v, _] -> (n, v)
|
||||
_else -> error $ "internal error: I should not be looking at " ++ metaFile
|
||||
|
||||
let pkgName = fromMaybe (error $ "invalid package name: " ++ name) $ simpleParsec name
|
||||
let pkgVersion = fromMaybe (error $ "invalid package version: " ++ version) $ simpleParsec version
|
||||
let pkgId = PackageIdentifier pkgName pkgVersion
|
||||
|
||||
pkgSpec <-
|
||||
readPackageVersionSpec' (inputDir </> metaFile) >>= \case
|
||||
PackageVersionSpec {packageVersionRevisions, packageVersionTimestamp = Nothing}
|
||||
| not (null packageVersionRevisions) -> do
|
||||
error $
|
||||
unlines
|
||||
[ inputDir </> metaFile <> " has cabal file revisions but the original package has no timestamp.",
|
||||
"This combination doesn't make sense. Either add a timestamp on the original package or remove the revisions"
|
||||
]
|
||||
PackageVersionSpec {packageVersionRevisions, packageVersionTimestamp = Just pkgTs}
|
||||
| any ((< pkgTs) . revisionTimestamp) packageVersionRevisions -> do
|
||||
error $
|
||||
unlines
|
||||
[ inputDir </> metaFile <> " has a revision with timestamp earlier than the package itself.",
|
||||
"Adjust the timestamps so that all revisions come after the original package"
|
||||
]
|
||||
meta ->
|
||||
return meta
|
||||
|
||||
srcDir <- prepareSource pkgId pkgSpec
|
||||
|
||||
let originalCabalFilePath = srcDir </> prettyShow pkgName <.> "cabal"
|
||||
cabalFileRevisionPath revisionNumber =
|
||||
joinPath
|
||||
[ inputDir,
|
||||
prettyShow pkgName,
|
||||
prettyShow pkgVersion,
|
||||
"revisions",
|
||||
show revisionNumber
|
||||
]
|
||||
<.> "cabal"
|
||||
|
||||
let cabalFilePath =
|
||||
maybe
|
||||
originalCabalFilePath
|
||||
cabalFileRevisionPath
|
||||
(latestRevisionNumber pkgSpec)
|
||||
|
||||
pkgDesc <- readGenericPackageDescription' cabalFilePath
|
||||
|
||||
sdistPath <- prepareSdist srcDir
|
||||
|
||||
let expectedSdistName = prettyShow pkgId <.> "tar.gz"
|
||||
unless (takeFileName sdistPath == expectedSdistName) $ do
|
||||
error $
|
||||
unlines
|
||||
[ "creating a source distribution for " ++ prettyShow pkgId ++ " has failed because",
|
||||
"cabal has produced a source distribtion that does not match the expected file name:",
|
||||
"actual: " ++ takeBaseName sdistPath,
|
||||
"expected: " ++ expectedSdistName,
|
||||
"possible cause: the package name and/or version implied by the metadata file path does not match what is contained in the cabal file",
|
||||
"metadata file: " ++ metaFile,
|
||||
"version in cabal file: " ++ prettyShow (Distribution.Types.PackageId.pkgVersion $ package $ packageDescription pkgDesc)
|
||||
]
|
||||
|
||||
let cabalFileRevisions =
|
||||
sortOn
|
||||
(Down . fst)
|
||||
[ (revisionTimestamp, cabalFileRevisionPath revisionNumber)
|
||||
| RevisionSpec {revisionTimestamp, revisionNumber} <- packageVersionRevisions pkgSpec
|
||||
]
|
||||
|
||||
return
|
||||
PreparedPackageVersion
|
||||
{ pkgId,
|
||||
pkgTimestamp = packageVersionTimestamp pkgSpec,
|
||||
pkgVersionSource = packageVersionSource pkgSpec,
|
||||
pkgVersionForce = packageVersionForce pkgSpec,
|
||||
pkgDesc,
|
||||
sdistPath,
|
||||
cabalFilePath,
|
||||
originalCabalFilePath,
|
||||
cabalFileRevisions
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
{-# LANGUAGE DataKinds #-}
|
||||
{-# LANGUAGE DeriveGeneric #-}
|
||||
{-# LANGUAGE DerivingStrategies #-}
|
||||
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE TypeFamilies #-}
|
||||
|
||||
module Foliage.PrepareSdist
|
||||
@ -71,18 +70,24 @@ addPrepareSdistRule outputDirRoot = addBuiltinRule noLint noIdentity run
|
||||
_differentOrMissing -> ChangedRecomputeDiff
|
||||
|
||||
when (changed == ChangedRecomputeSame) $
|
||||
putInfo $ "Wrote " ++ path ++ " (same hash " ++ showHashValue hv ++ ")"
|
||||
putInfo ("Wrote " ++ path ++ " (same hash " ++ showHashValue hv ++ ")")
|
||||
|
||||
when (changed == ChangedRecomputeDiff) $
|
||||
putInfo $ "Wrote " ++ path ++ " (new hash " ++ showHashValue hv ++ ")"
|
||||
putInfo ("Wrote " ++ path ++ " (new hash " ++ showHashValue hv ++ ")")
|
||||
|
||||
return $ RunResult {runChanged = changed, runStore = new, runValue = path}
|
||||
|
||||
makeSdist srcDir = do
|
||||
cabalFile <- do
|
||||
getDirectoryFiles srcDir ["*.cabal"] >>= \case
|
||||
[f] -> pure f
|
||||
fs -> fail $ "Invalid srcDir: " ++ srcDir ++ ". It contains multiple cabal files: " ++ unwords fs
|
||||
cabalFiles <- getDirectoryFiles srcDir ["*.cabal"]
|
||||
let cabalFile = case cabalFiles of
|
||||
[f] -> f
|
||||
fs ->
|
||||
error $
|
||||
unlines
|
||||
[ "Invalid source directory: " ++ srcDir,
|
||||
"It contains multiple cabal files, while only one is allowed",
|
||||
unwords fs
|
||||
]
|
||||
|
||||
traced "cabal sdist" $ do
|
||||
gpd <- readGenericPackageDescription Verbosity.normal (srcDir </> cabalFile)
|
||||
|
@ -8,7 +8,6 @@ module Foliage.PrepareSource where
|
||||
import Control.Monad (when)
|
||||
import Data.ByteString qualified as BS
|
||||
import Data.Foldable (for_)
|
||||
import Data.Text qualified as T
|
||||
import Development.Shake
|
||||
import Development.Shake.Classes
|
||||
import Development.Shake.Rule
|
||||
@ -18,8 +17,8 @@ import Distribution.Types.PackageName (unPackageName)
|
||||
import Foliage.Meta
|
||||
import Foliage.RemoteAsset (fetchRemoteAsset)
|
||||
import Foliage.UpdateCabalFile (rewritePackageVersion)
|
||||
import Foliage.Utils.GitHub (githubRepoTarballUrl)
|
||||
import GHC.Generics
|
||||
import Network.URI (URI (..), URIAuth (..), nullURI, nullURIAuth)
|
||||
import System.Directory qualified as IO
|
||||
import System.FilePath ((<.>), (</>))
|
||||
|
||||
@ -79,12 +78,7 @@ addPrepareSourceRule inputDir cacheDir = addBuiltinRule noLint noIdentity run
|
||||
-- metadata.
|
||||
--
|
||||
GitHubSource repo rev mSubdir -> do
|
||||
let url =
|
||||
nullURI
|
||||
{ uriScheme = "https:",
|
||||
uriAuthority = Just nullURIAuth {uriRegName = "github.com"},
|
||||
uriPath = "/" </> T.unpack (unGitHubRepo repo) </> "tarball" </> T.unpack (unGitHubRev rev)
|
||||
}
|
||||
let url = githubRepoTarballUrl repo rev
|
||||
|
||||
tarballPath <- fetchRemoteAsset url
|
||||
|
||||
|
@ -35,14 +35,16 @@ addFetchRemoteAssetRule cacheDir = addBuiltinRule noLint noIdentity run
|
||||
run :: BuiltinRun RemoteAsset FilePath
|
||||
run (RemoteAsset uri) old _mode = do
|
||||
unless (uriQuery uri == "") $
|
||||
fail $ "Query elements in URI are not supported: " <> show uri
|
||||
error ("Query elements in URI are not supported: " <> show uri)
|
||||
|
||||
unless (uriFragment uri == "") $
|
||||
fail $ "Fragments in URI are not supported: " <> show uri
|
||||
error ("Fragments in URI are not supported: " <> show uri)
|
||||
|
||||
let scheme = dropWhileEnd (not . isAlpha) $ uriScheme uri
|
||||
Just host = uriRegName <$> uriAuthority uri
|
||||
path = cacheDir </> joinPath (scheme : host : pathSegments uri)
|
||||
|
||||
let host = maybe (error $ "invalid uri " ++ show uri) uriRegName (uriAuthority uri)
|
||||
|
||||
let path = cacheDir </> joinPath (scheme : host : pathSegments uri)
|
||||
|
||||
-- parse etag from store
|
||||
let oldETag = fromMaybe BS.empty old
|
||||
|
@ -3,7 +3,6 @@ module Foliage.Shake
|
||||
readKeysAt,
|
||||
readPackageVersionSpec',
|
||||
readGenericPackageDescription',
|
||||
originalCabalFile,
|
||||
)
|
||||
where
|
||||
|
||||
@ -12,12 +11,9 @@ import Development.Shake
|
||||
import Development.Shake.FilePath
|
||||
import Distribution.Simple.PackageDescription
|
||||
import Distribution.Types.GenericPackageDescription
|
||||
import Distribution.Types.PackageId
|
||||
import Distribution.Types.PackageName
|
||||
import Distribution.Verbosity qualified as Verbosity
|
||||
import Foliage.HackageSecurity
|
||||
import Foliage.Meta
|
||||
import Foliage.PrepareSource
|
||||
|
||||
computeFileInfoSimple' :: FilePath -> Action FileInfo
|
||||
computeFileInfoSimple' fp = do
|
||||
@ -41,8 +37,3 @@ readGenericPackageDescription' :: FilePath -> Action GenericPackageDescription
|
||||
readGenericPackageDescription' fp = do
|
||||
need [fp]
|
||||
liftIO $ readGenericPackageDescription Verbosity.silent fp
|
||||
|
||||
originalCabalFile :: PackageVersionMeta -> Action FilePath
|
||||
originalCabalFile PackageVersionMeta {pkgId, pkgSpec} = do
|
||||
srcDir <- prepareSource pkgId pkgSpec
|
||||
return $ srcDir </> unPackageName (pkgName pkgId) <.> "cabal"
|
||||
|
@ -2,20 +2,21 @@
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
{-# LANGUAGE UndecidableInstances #-}
|
||||
|
||||
module Foliage.Utils.Aeson where
|
||||
|
||||
import Data.Aeson
|
||||
import GHC.Generics
|
||||
import Data.Coerce
|
||||
import GHC.Generics
|
||||
|
||||
newtype MyAesonEncoding a = MyAesonEncoding a
|
||||
deriving Generic
|
||||
deriving (Generic)
|
||||
|
||||
myOptions :: Options
|
||||
myOptions =
|
||||
defaultOptions
|
||||
{ sumEncoding = ObjectWithSingleField
|
||||
, omitNothingFields = True
|
||||
{ sumEncoding = ObjectWithSingleField,
|
||||
omitNothingFields = True
|
||||
}
|
||||
|
||||
instance (Generic a, GToJSON' Value Zero (Rep a), GToJSON' Encoding Zero (Rep a)) => ToJSON (MyAesonEncoding a) where
|
||||
|
17
app/Foliage/Utils/GitHub.hs
Normal file
17
app/Foliage/Utils/GitHub.hs
Normal file
@ -0,0 +1,17 @@
|
||||
module Foliage.Utils.GitHub
|
||||
( githubRepoTarballUrl,
|
||||
)
|
||||
where
|
||||
|
||||
import Data.Text qualified as T
|
||||
import Foliage.Meta (GitHubRepo (unGitHubRepo), GitHubRev (unGitHubRev))
|
||||
import Network.URI (URI (..), URIAuth (..), nullURI, nullURIAuth)
|
||||
import System.FilePath ((</>))
|
||||
|
||||
githubRepoTarballUrl :: GitHubRepo -> GitHubRev -> URI
|
||||
githubRepoTarballUrl repo rev =
|
||||
nullURI
|
||||
{ uriScheme = "https:",
|
||||
uriAuthority = Just nullURIAuth {uriRegName = "github.com"},
|
||||
uriPath = "/" </> T.unpack (unGitHubRepo repo) </> "tarball" </> T.unpack (unGitHubRev rev)
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
|
||||
module Main where
|
||||
|
||||
import Foliage.CmdBuild
|
||||
|
@ -1,3 +1,6 @@
|
||||
packages: .
|
||||
index-state: 2022-08-29T00:00:00Z
|
||||
with-compiler: ghc-8.10.7
|
||||
index-state: 2023-03-01T00:00:00Z
|
||||
with-compiler: ghc-9.2.6
|
||||
allow-newer:
|
||||
, tomland:base
|
||||
, tomland:text
|
||||
|
597
flake.lock
597
flake.lock
@ -16,6 +16,21 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"blank": {
|
||||
"locked": {
|
||||
"lastModified": 1625557891,
|
||||
"narHash": "sha256-O8/MWsPBGhhyPoPLHZAuoZiiHo9q6FLlEeIDEXuj6T4=",
|
||||
"owner": "divnix",
|
||||
"repo": "blank",
|
||||
"rev": "5a5d2684073d9f563072ed07c871d577a6c614a8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "divnix",
|
||||
"repo": "blank",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"cabal-32": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@ -36,11 +51,11 @@
|
||||
"cabal-34": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1640353650,
|
||||
"narHash": "sha256-N1t6M3/wqj90AEdRkeC8i923gQYUpzSr8b40qVOZ1Rk=",
|
||||
"lastModified": 1645834128,
|
||||
"narHash": "sha256-wG3d+dOt14z8+ydz4SL7pwGfe7SiimxcD/LOuPCV6xM=",
|
||||
"owner": "haskell",
|
||||
"repo": "cabal",
|
||||
"rev": "942639c18c0cd8ec53e0a6f8d120091af35312cd",
|
||||
"rev": "5ff598c67f53f7c4f48e31d722ba37172230c462",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -53,11 +68,11 @@
|
||||
"cabal-36": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1641652457,
|
||||
"narHash": "sha256-BlFPKP4C4HRUJeAbdembX1Rms1LD380q9s0qVDeoAak=",
|
||||
"lastModified": 1669081697,
|
||||
"narHash": "sha256-I5or+V7LZvMxfbYgZATU4awzkicBwwok4mVoje+sGmU=",
|
||||
"owner": "haskell",
|
||||
"repo": "cabal",
|
||||
"rev": "f27667f8ec360c475027dcaee0138c937477b070",
|
||||
"rev": "8fd619e33d34924a94e691c5fea2c42f0fc7f144",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -83,13 +98,104 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"devshell": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1663445644,
|
||||
"narHash": "sha256-+xVlcK60x7VY1vRJbNUEAHi17ZuoQxAIH4S4iUFUGBA=",
|
||||
"owner": "numtide",
|
||||
"repo": "devshell",
|
||||
"rev": "e3dc3e21594fe07bdb24bdf1c8657acaa4cb8f66",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "devshell",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"dmerge": {
|
||||
"inputs": {
|
||||
"nixlib": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"nixpkgs"
|
||||
],
|
||||
"yants": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"yants"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1659548052,
|
||||
"narHash": "sha256-fzI2gp1skGA8mQo/FBFrUAtY0GQkAIAaV/V127TJPyY=",
|
||||
"owner": "divnix",
|
||||
"repo": "data-merge",
|
||||
"rev": "d160d18ce7b1a45b88344aa3f13ed1163954b497",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "divnix",
|
||||
"repo": "data-merge",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1672831974,
|
||||
"narHash": "sha256-z9k3MfslLjWQfnjBtEtJZdq3H7kyi2kQtUThfTgdRk0=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "flake-compat",
|
||||
"rev": "45f2638735f8cdc40fe302742b79f248d23eb368",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "input-output-hk",
|
||||
"ref": "hkm/gitlab-fix",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-compat_2": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1650374568,
|
||||
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "edolstra",
|
||||
"repo": "flake-compat",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"locked": {
|
||||
"lastModified": 1659877975,
|
||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||
"lastModified": 1667395993,
|
||||
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -100,11 +206,26 @@
|
||||
},
|
||||
"flake-utils_2": {
|
||||
"locked": {
|
||||
"lastModified": 1644229661,
|
||||
"narHash": "sha256-1YdnJAsNy69bpcjuoKdOYQX0YxZBiCYZo4Twxerqv7k=",
|
||||
"lastModified": 1653893745,
|
||||
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "3cecb5b042f7f209c56ffd8371b2711a290ec797",
|
||||
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils_3": {
|
||||
"locked": {
|
||||
"lastModified": 1659877975,
|
||||
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -130,14 +251,33 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gomod2nix": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_2",
|
||||
"utils": "utils"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1655245309,
|
||||
"narHash": "sha256-d/YPoQ/vFn1+GTmSdvbSBSTOai61FONxB4+Lt6w/IVI=",
|
||||
"owner": "tweag",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "40d32f82fc60d66402eb0972e6e368aeab3faf58",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "tweag",
|
||||
"repo": "gomod2nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"hackage": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1661735830,
|
||||
"narHash": "sha256-xJpfFmpzJVci+fM9mjTKyIbkUpJf5XkZMygY+YRKzwU=",
|
||||
"lastModified": 1677809131,
|
||||
"narHash": "sha256-MQ+ybbu5VFA6ERvh8mXcYEVlBCTte4BDxRaILSwBdAk=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "hackage.nix",
|
||||
"rev": "9b22f61f50b19bf401ab104ff0e239f8ada87547",
|
||||
"rev": "4ea4b12737ea42e47eb5c6a7e4a3eafe9da2fc52",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -153,12 +293,13 @@
|
||||
"cabal-34": "cabal-34",
|
||||
"cabal-36": "cabal-36",
|
||||
"cardano-shell": "cardano-shell",
|
||||
"flake-utils": "flake-utils_2",
|
||||
"flake-compat": "flake-compat",
|
||||
"flake-utils": "flake-utils",
|
||||
"ghc-8.6.5-iohk": "ghc-8.6.5-iohk",
|
||||
"hackage": "hackage",
|
||||
"hpc-coveralls": "hpc-coveralls",
|
||||
"hydra": "hydra",
|
||||
"nix-tools": "nix-tools",
|
||||
"iserv-proxy": "iserv-proxy",
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"nixpkgs-unstable"
|
||||
@ -167,16 +308,18 @@
|
||||
"nixpkgs-2105": "nixpkgs-2105",
|
||||
"nixpkgs-2111": "nixpkgs-2111",
|
||||
"nixpkgs-2205": "nixpkgs-2205",
|
||||
"nixpkgs-2211": "nixpkgs-2211",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"old-ghc-nix": "old-ghc-nix",
|
||||
"stackage": "stackage"
|
||||
"stackage": "stackage",
|
||||
"tullia": "tullia"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1661940924,
|
||||
"narHash": "sha256-aXmYSdeDjSWpJPtNAtvAKabKUyOOiJXzZ7EEYYKNrYI=",
|
||||
"lastModified": 1677809260,
|
||||
"narHash": "sha256-RSiv9/LP8/+sf15B305z4DYaj7IiAVjPBkqPfByxAp4=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "haskell.nix",
|
||||
"rev": "c83b33f4198fd8ba62748feb5024ece2b5329a8e",
|
||||
"rev": "02a5acdfc937129e51e41de0eafd0c44f29896b4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -212,11 +355,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1646878427,
|
||||
"narHash": "sha256-KtbrofMtN8GlM7D+n90kixr7QpSlVmdN+vK5CA/aRzc=",
|
||||
"lastModified": 1671755331,
|
||||
"narHash": "sha256-hXsgJj0Cy0ZiCiYdW2OdBz5WmFyOMKuw4zyxKpgUKm4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "hydra",
|
||||
"rev": "28b682b85b7efc5cf7974065792a1f22203a5927",
|
||||
"rev": "f48f00ee6d5727ae3e488cbf9ce157460853fea8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -224,6 +367,46 @@
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"incl": {
|
||||
"inputs": {
|
||||
"nixlib": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1669263024,
|
||||
"narHash": "sha256-E/+23NKtxAqYG/0ydYgxlgarKnxmDbg6rCMWnOBqn9Q=",
|
||||
"owner": "divnix",
|
||||
"repo": "incl",
|
||||
"rev": "ce7bebaee048e4cd7ebdb4cee7885e00c4e2abca",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "divnix",
|
||||
"repo": "incl",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"iserv-proxy": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1670983692,
|
||||
"narHash": "sha256-avLo34JnI9HNyOuauK5R69usJm+GfW3MlyGlYxZhTgY=",
|
||||
"ref": "hkm/remote-iserv",
|
||||
"rev": "50d0abb3317ac439a4e7495b185a64af9b7b9300",
|
||||
"revCount": 10,
|
||||
"type": "git",
|
||||
"url": "https://gitlab.haskell.org/hamishmack/iserv-proxy.git"
|
||||
},
|
||||
"original": {
|
||||
"ref": "hkm/remote-iserv",
|
||||
"type": "git",
|
||||
"url": "https://gitlab.haskell.org/hamishmack/iserv-proxy.git"
|
||||
}
|
||||
},
|
||||
"lowdown-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@ -240,6 +423,35 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"n2c": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1665039323,
|
||||
"narHash": "sha256-SAh3ZjFGsaCI8FRzXQyp56qcGdAqgKEfJWPCQ0Sr7tQ=",
|
||||
"owner": "nlewo",
|
||||
"repo": "nix2container",
|
||||
"rev": "b008fe329ffb59b67bf9e7b08ede6ee792f2741a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nlewo",
|
||||
"repo": "nix2container",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix": {
|
||||
"inputs": {
|
||||
"lowdown-src": "lowdown-src",
|
||||
@ -247,49 +459,123 @@
|
||||
"nixpkgs-regression": "nixpkgs-regression"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1643066034,
|
||||
"narHash": "sha256-xEPeMcNJVOeZtoN+d+aRwolpW8mFSEQx76HTRdlhPhg=",
|
||||
"lastModified": 1661606874,
|
||||
"narHash": "sha256-9+rpYzI+SmxJn+EbYxjGv68Ucp22bdFUSy/4LkHkkDQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nix",
|
||||
"rev": "a1cd7e58606a41fcf62bf8637804cf8306f17f62",
|
||||
"rev": "11e45768b34fdafdcf019ddbd337afa16127ff0f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "2.6.0",
|
||||
"ref": "2.11.0",
|
||||
"repo": "nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-tools": {
|
||||
"flake": false,
|
||||
"nix-nomad": {
|
||||
"inputs": {
|
||||
"flake-compat": "flake-compat_2",
|
||||
"flake-utils": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"nix2container",
|
||||
"flake-utils"
|
||||
],
|
||||
"gomod2nix": "gomod2nix",
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"nixpkgs"
|
||||
],
|
||||
"nixpkgs-lib": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1659569011,
|
||||
"narHash": "sha256-wHS0H5+TERmDnPCfzH4A+rSR5TvjYMWus9BNeNAMyUM=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "nix-tools",
|
||||
"rev": "555d57e1ea81b79945f2608aa261df20f6b602a5",
|
||||
"lastModified": 1658277770,
|
||||
"narHash": "sha256-T/PgG3wUn8Z2rnzfxf2VqlR1CBjInPE0l1yVzXxPnt0=",
|
||||
"owner": "tristanpemble",
|
||||
"repo": "nix-nomad",
|
||||
"rev": "054adcbdd0a836ae1c20951b67ed549131fd2d70",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "input-output-hk",
|
||||
"repo": "nix-tools",
|
||||
"owner": "tristanpemble",
|
||||
"repo": "nix-nomad",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix2container": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils_2",
|
||||
"nixpkgs": "nixpkgs_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1658567952,
|
||||
"narHash": "sha256-XZ4ETYAMU7XcpEeAFP3NOl9yDXNuZAen/aIJ84G+VgA=",
|
||||
"owner": "nlewo",
|
||||
"repo": "nix2container",
|
||||
"rev": "60bb43d405991c1378baf15a40b5811a53e32ffa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nlewo",
|
||||
"repo": "nix2container",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixago": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"flake-utils"
|
||||
],
|
||||
"nixago-exts": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"blank"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1661824785,
|
||||
"narHash": "sha256-/PnwdWoO/JugJZHtDUioQp3uRiWeXHUdgvoyNbXesz8=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nixago",
|
||||
"rev": "8c1f9e5f1578d4b2ea989f618588d62a335083c3",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "nixago",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1632864508,
|
||||
"narHash": "sha256-d127FIvGR41XbVRDPVvozUPQ/uRHbHwvfyKHwEt5xFM=",
|
||||
"lastModified": 1657693803,
|
||||
"narHash": "sha256-G++2CJ9u0E7NNTAi9n5G8TdDmGJXcIjkJ3NF8cetQB8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "82891b5e2c2359d7e58d08849e4c89511ab94234",
|
||||
"rev": "365e1b3a859281cf11b94f87231adeabbdd878a2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"ref": "nixos-21.05-small",
|
||||
"type": "indirect"
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-22.05-small",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-2003": {
|
||||
@ -310,11 +596,11 @@
|
||||
},
|
||||
"nixpkgs-2105": {
|
||||
"locked": {
|
||||
"lastModified": 1655034179,
|
||||
"narHash": "sha256-rf1/7AbzuYDw6+8Xvvf3PtEOygymLBrFsFxvext5ZjI=",
|
||||
"lastModified": 1659914493,
|
||||
"narHash": "sha256-lkA5X3VNMKirvA+SUzvEhfA7XquWLci+CGi505YFAIs=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "046ee4af7a9f016a364f8f78eeaa356ba524ac31",
|
||||
"rev": "022caabb5f2265ad4006c1fa5b1ebe69fb0c3faf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -326,11 +612,11 @@
|
||||
},
|
||||
"nixpkgs-2111": {
|
||||
"locked": {
|
||||
"lastModified": 1656782578,
|
||||
"narHash": "sha256-1eMCBEqJplPotTo/SZ/t5HU6Sf2I8qKlZi9MX7jv9fw=",
|
||||
"lastModified": 1659446231,
|
||||
"narHash": "sha256-hekabNdTdgR/iLsgce5TGWmfIDZ86qjPhxDg/8TlzhE=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "573603b7fdb9feb0eb8efc16ee18a015c667ab1b",
|
||||
"rev": "eabc38219184cc3e04a974fe31857d8e0eac098d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -342,11 +628,11 @@
|
||||
},
|
||||
"nixpkgs-2205": {
|
||||
"locked": {
|
||||
"lastModified": 1657876628,
|
||||
"narHash": "sha256-URmf0O2cQ/3heg2DJOeLyU/JmfVMqG4X5t9crQXMaeY=",
|
||||
"lastModified": 1672580127,
|
||||
"narHash": "sha256-3lW3xZslREhJogoOkjeZtlBtvFMyxHku7I/9IVehhT8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "549d82bdd40f760a438c3c3497c1c61160f3de55",
|
||||
"rev": "0874168639713f547c05947c76124f78441ea46c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -356,6 +642,22 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-2211": {
|
||||
"locked": {
|
||||
"lastModified": 1675730325,
|
||||
"narHash": "sha256-uNvD7fzO5hNlltNQUAFBPlcEjNG5Gkbhl/ROiX+GZU4=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b7ce17b1ebf600a72178f6302c77b6382d09323f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixpkgs-22.11-darwin",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-regression": {
|
||||
"locked": {
|
||||
"lastModified": 1643052045,
|
||||
@ -366,18 +668,19 @@
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "215d4d0fd80ca5163643b03a33fde804a29cc1e2",
|
||||
"type": "indirect"
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1657888067,
|
||||
"narHash": "sha256-GnwJoFBTPfW3+mz7QEeJEEQ9OMHZOiIJ/qDhZxrlKh8=",
|
||||
"lastModified": 1675758091,
|
||||
"narHash": "sha256-7gFSQbSVAFUHtGCNHPF7mPc5CcqDk9M2+inlVPZSneg=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "65fae659e31098ca4ac825a6fef26d890aaf3f4e",
|
||||
"rev": "747927516efcb5e31ba03b7ff32f61f6d47e7d87",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -387,6 +690,68 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1653581809,
|
||||
"narHash": "sha256-Uvka0V5MTGbeOfWte25+tfRL3moECDh1VwokWSZUdoY=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "83658b28fe638a170a19b8933aa008b30640fbd1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_3": {
|
||||
"locked": {
|
||||
"lastModified": 1654807842,
|
||||
"narHash": "sha256-ADymZpr6LuTEBXcy6RtFHcUZdjKTBRTMYwu19WOx17E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "fc909087cc3386955f21b4665731dbdaceefb1d8",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1665087388,
|
||||
"narHash": "sha256-FZFPuW9NWHJteATOf79rZfwfRn5fE0wi9kRzvGfDHPA=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "95fda953f6db2e9496d2682c4fc7b82f959878f7",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nosys": {
|
||||
"locked": {
|
||||
"lastModified": 1667881534,
|
||||
"narHash": "sha256-FhwJ15uPLRsvaxtt/bNuqE/ykMpNAPF0upozFKhTtXM=",
|
||||
"owner": "divnix",
|
||||
"repo": "nosys",
|
||||
"rev": "2d0d5207f6a230e9d0f660903f8db9807b54814f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "divnix",
|
||||
"repo": "nosys",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"old-ghc-nix": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
@ -406,7 +771,10 @@
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"flake-utils": [
|
||||
"haskell-nix",
|
||||
"flake-utils"
|
||||
],
|
||||
"haskell-nix": "haskell-nix",
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
@ -417,11 +785,11 @@
|
||||
"stackage": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1661925696,
|
||||
"narHash": "sha256-eMM1dhdSv0AlLtD2cULJsLhJF4ZWdvpqRcCOw9DbXLI=",
|
||||
"lastModified": 1677543037,
|
||||
"narHash": "sha256-7CPQZZafTQiw7YL+a2KCamb9a3PU0do9iZKy1AaRkBo=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "stackage.nix",
|
||||
"rev": "575039e5410ef653e302d53938aa6df403e5a8b1",
|
||||
"rev": "f4d29fa4403f45541d9f3993523df6027c21fe90",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@ -429,6 +797,113 @@
|
||||
"repo": "stackage.nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"std": {
|
||||
"inputs": {
|
||||
"arion": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"blank"
|
||||
],
|
||||
"blank": "blank",
|
||||
"devshell": "devshell",
|
||||
"dmerge": "dmerge",
|
||||
"flake-utils": "flake-utils_3",
|
||||
"incl": "incl",
|
||||
"makes": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"blank"
|
||||
],
|
||||
"microvm": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"blank"
|
||||
],
|
||||
"n2c": "n2c",
|
||||
"nixago": "nixago",
|
||||
"nixpkgs": "nixpkgs_4",
|
||||
"nosys": "nosys",
|
||||
"yants": "yants"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1674526466,
|
||||
"narHash": "sha256-tMTaS0bqLx6VJ+K+ZT6xqsXNpzvSXJTmogkraBGzymg=",
|
||||
"owner": "divnix",
|
||||
"repo": "std",
|
||||
"rev": "516387e3d8d059b50e742a2ff1909ed3c8f82826",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "divnix",
|
||||
"repo": "std",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"tullia": {
|
||||
"inputs": {
|
||||
"nix-nomad": "nix-nomad",
|
||||
"nix2container": "nix2container",
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"nixpkgs"
|
||||
],
|
||||
"std": "std"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1675695930,
|
||||
"narHash": "sha256-B7rEZ/DBUMlK1AcJ9ajnAPPxqXY6zW2SBX+51bZV0Ac=",
|
||||
"owner": "input-output-hk",
|
||||
"repo": "tullia",
|
||||
"rev": "621365f2c725608f381b3ad5b57afef389fd4c31",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "input-output-hk",
|
||||
"repo": "tullia",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"locked": {
|
||||
"lastModified": 1653893745,
|
||||
"narHash": "sha256-0jntwV3Z8//YwuOjzhV2sgJJPt+HY6KhU7VZUL0fKZQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ed9fb1935d260de5fe1c2f7ee0ebaae17ed2fa1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"yants": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"haskell-nix",
|
||||
"tullia",
|
||||
"std",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1667096281,
|
||||
"narHash": "sha256-wRRec6ze0gJHmGn6m57/zhz/Kdvp9HS4Nl5fkQ+uIuA=",
|
||||
"owner": "divnix",
|
||||
"repo": "yants",
|
||||
"rev": "d18f356ec25cb94dc9c275870c3a7927a10f8c3c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "divnix",
|
||||
"repo": "yants",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
|
56
flake.nix
56
flake.nix
@ -1,50 +1,52 @@
|
||||
{
|
||||
description = "Foliage is a tool to create custom Haskell package repositories, in a fully reproducible way.";
|
||||
description =
|
||||
"Foliage is a tool to create custom Haskell package repositories, in a fully reproducible way.";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.follows = "haskell-nix/nixpkgs-unstable";
|
||||
haskell-nix.url = "github:input-output-hk/haskell.nix";
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
flake-utils.follows = "haskell-nix/flake-utils";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, haskell-nix }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
|
||||
flake-utils.lib.eachSystem [ "x86_64-linux" ] (system:
|
||||
let
|
||||
pkgs = import nixpkgs { inherit system; inherit (haskell-nix) config; overlays = [haskell-nix.overlay]; };
|
||||
project = pkgs.haskell-nix.cabalProject {
|
||||
pkgs = import nixpkgs {
|
||||
inherit system;
|
||||
inherit (haskell-nix) config;
|
||||
overlays = [ haskell-nix.overlay ];
|
||||
};
|
||||
|
||||
pkgs-static-where-possible =
|
||||
if pkgs.stdenv.hostPlatform.isLinux then
|
||||
if pkgs.stdenv.hostPlatform.isAarch64 then
|
||||
pkgs.pkgsCross.aarch64-multiplatform-musl
|
||||
else
|
||||
pkgs.pkgsCross.musl64
|
||||
else
|
||||
pkgs;
|
||||
|
||||
project = pkgs-static-where-possible.haskell-nix.cabalProject' {
|
||||
src = ./.;
|
||||
compiler-nix-name = "ghc8107";
|
||||
shell.tools = {
|
||||
cabal = {};
|
||||
hlint = {};
|
||||
haskell-language-server = {};
|
||||
compiler-nix-name = "ghc926";
|
||||
};
|
||||
shell.buildInputs = with pkgs; [
|
||||
nixpkgs-fmt
|
||||
fsatrace
|
||||
];
|
||||
modules = [{
|
||||
packages.foliage.components.exes.foliage.dontStrip = false;
|
||||
}];
|
||||
};
|
||||
in {
|
||||
packages.default = project.foliage.components.exes.foliage;
|
||||
devShell = pkgs.mkShell {
|
||||
name = "foliage-dev-shell";
|
||||
buildInputs = with pkgs; [
|
||||
fsatrace
|
||||
];
|
||||
};
|
||||
});
|
||||
|
||||
flake = project.flake { };
|
||||
|
||||
in
|
||||
flake // { packages.default = flake.packages."foliage:exe:foliage"; });
|
||||
|
||||
nixConfig = {
|
||||
extra-substituters = [
|
||||
"https://cache.iog.io"
|
||||
"https://foliage.cachix.org"
|
||||
"https://cache.zw3rk.com"
|
||||
];
|
||||
extra-trusted-public-keys = [
|
||||
"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
|
||||
"foliage.cachix.org-1:kAFyYLnk8JcRURWReWZCatM9v3Rk24F5wNMpEj14Q/g="
|
||||
"loony-tools:pr9m4BkM/5/eSTZlkQyRt57Jz7OMBxNSUiMC4FkcNfk="
|
||||
];
|
||||
};
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ executable foliage
|
||||
Foliage.Meta.Aeson
|
||||
Foliage.Options
|
||||
Foliage.Pages
|
||||
Foliage.PreparePackageVersion
|
||||
Foliage.PrepareSource
|
||||
Foliage.PrepareSdist
|
||||
Foliage.RemoteAsset
|
||||
@ -34,13 +35,13 @@ executable foliage
|
||||
Foliage.Time
|
||||
Foliage.UpdateCabalFile
|
||||
Foliage.Utils.Aeson
|
||||
Foliage.Utils.GitHub
|
||||
Network.URI.Orphans
|
||||
|
||||
default-language: Haskell2010
|
||||
default-extensions:
|
||||
ImportQualifiedPost LambdaCase NamedFieldPuns ViewPatterns
|
||||
default-language: GHC2021
|
||||
|
||||
ghc-options: -Wall
|
||||
ghc-options: -threaded
|
||||
build-depends:
|
||||
base >=4.14.3.0 && <4.18,
|
||||
aeson >=2.0.3.0 && <2.2,
|
||||
|
@ -42,28 +42,26 @@
|
||||
<dt class="col-sm-3">License</dt>
|
||||
<dd class="col-sm-9"><p>{{license}}</p></dd>
|
||||
{{/pkgDesc}}
|
||||
{{#pkgSpec}}
|
||||
{{#packageVersionSource}}
|
||||
{{#pkgVersionSource}}
|
||||
<dt class="col-sm-3">Source</dt>
|
||||
<dd class="col-sm-9">
|
||||
<dl class="row">
|
||||
{{> packageVersionSource}}
|
||||
</dl>
|
||||
</dd>
|
||||
{{/packageVersionSource}}
|
||||
{{/pkgVersionSource}}
|
||||
<dt class="col-sm-3">Timestamp</dt>
|
||||
<dd class="col-sm-9"><p>{{packageVersionTimestamp}}</p></dd>
|
||||
<dd class="col-sm-9"><p>{{pkgTimestamp}}</p></dd>
|
||||
<dt class="col-sm-3">Revisions</dt>
|
||||
<dd class="col-sm-9">
|
||||
{{#packageVersionRevisions}}
|
||||
<p>{{revisionTimestamp}}</p>
|
||||
{{/packageVersionRevisions}}
|
||||
{{^packageVersionRevisions}}
|
||||
{{#cabalFileRevisions}}
|
||||
<p>{{.}}</p>
|
||||
{{/cabalFileRevisions}}
|
||||
{{^cabalFileRevisions}}
|
||||
<p>None</p>
|
||||
{{/packageVersionRevisions}}
|
||||
{{/cabalFileRevisions}}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
{{/pkgSpec}}
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user