{-# LANGUAGE CPP, OverloadedStrings #-}moduleCabalMetawhereimportShellyhiding(tag)importPreludehiding(FilePath)importData.Text.Lazy(Text,unpack)importqualifiedData.Text.LazyasTimportFilesystem.Path.CurrentOS(hasExtension,filename)importData.Maybe(fromMaybe,maybeToList)importData.List(partition)#if __GLASGOW_HASKELL__ < 704importData.Monoid(Monoid(..))importControl.Monad(when,forM)infixr5<>(<>)::Monoidm=>m->m->m(<>)=mappend#elseimportControl.Monad(forM)importData.Monoid((<>),Monoid(..))#endif{--
import FileLocation (debug)
--}source_file::FilePathsource_file="sources.txt"dataPackage=Directory{dLocation::FilePath,pFlags::[Text]}|Package{pLocation::Text,pFlags::[Text]}|GitPackage{gitLocation::Text,pFlags::[Text],gTag::MaybeText}deriving(Show,Eq)asList::Package->[Text]asList(Packagelflags)=l:flagsasList(GitPackagelflagstag)=l:flags++maybeToListtagasList(Directorydflags)=toTextIgnored:flagsdataPackageSources=PackageSources{dirs::[Package],hackages::[Package],https::[Package]-- also git for now ,gits::[Package]}deriving(Show,Eq)packageList::PackageSources->[[Text]]packageList=mapasList.packagespackages::PackageSources->[Package]packagespsources=dirspsources++hackagespsources++gitPackagespsourcesgitPackages::PackageSources->[Package]gitPackagespsources=gitspsources++httpspsourcesinstanceMonoidPackageSourceswheremempty=PackageSources[][][][]mappend(PackageSourcesd1ha1ht1g1)(PackageSourcesd2ha2ht2g2)=PackageSources(mappendd1d2)(mappendha1ha2)(mappendht1ht2)(mappendg1g2)vendor_dir::FilePathvendor_dir="vendor"git_::Text->[Text]->ShIO()git_=command1_"git"[]readPackages::Bool->FilePath->ShIOPackageSourcesreadPackagesallowCabalsstartDir=dofullDir<-canonicstartDirchdirfullDir$docabalPresent<-ifallowCabalsthenreturnFalseelseisCabalPresentifcabalPresentthenreturnmemptyelsedopsources<-getSourceswhen(psources==mempty)$terror$"empty "<>toTextIgnoresource_fileletgit_pkgs=gitPackagespsourceschild_vendor_pkgs<-ifnullgit_pkgsthenreturn[]elsedomkdir_pvendor_dirchdirvendor_dir$forMgit_pkgs$\pkg->doletrepo=gitLocationpkgletd=filename$fromTextrepoe<-test_ddifnotethengit_"clone"["--recursive",repo]elsechdird$git_"fetch"["origin"]chdird$dogit_"checkout"[fromMaybe"master"(gTagpkg)]git_"submodule"["foreach","git","pull","origin","master"]readPackagesFalsedchild_dir_pkgs<-forM(dirspsources)$\dir->dob<-fmap(==fullDir)(canonic$dLocationdir)ifbthenreturnmemptyelsereadPackagesFalse(dLocationdir)letchild_pkgs=child_dir_pkgs++child_vendor_pkgs-- in the end we have either hackage packages or directories-- a directory was either listed as a directory or a child found in a sources.txt in that directory-- if there are no child, there will be an empty list [] of children-- this would be easy to break & should be cleaned upreturn$mempty{hackages=hackagespsources++concatMaphackageschild_pkgs,dirs=concatMap(\(p,ps)->ifnullpsthen[p]elseps)$zip(dirspsources++gitspsources++httpspsources)(mapdirschild_pkgs)}whereheadMay[]=NothingheadMayxs=Just(headxs)isCabalFile=fliphasExtension"cabal"isCabalPresent=fmap(anyisCabalFile)(ls".")getSources::ShIOPackageSourcesgetSources=dosourceContent<-readfilesource_fileletsources=paritionSources[source|source<-map(T.words.T.strip)(T.linessourceContent),not.null$source,"--"/=headsource]ds<-mapMfullPath(dirssources)return$sources{dirs=ds}wherefullPathpackage=dofp<-canonic$dLocationpackagereturnpackage{dLocation=fp}paritionSources::[[Text]]->PackageSourcesparitionSources=gomemptywheregosources[]=sourcesgo_([]:_)=error"impossible"gosources((name:flags):more)=letn=T.headnameinifn=='.'||n=='/'thengosources{dirs=mkDir:dirssources}moreelseif"http"`T.isPrefixOf`namethengosources{https=mkGit:httpssources}moreelseif"https"`T.isPrefixOf`namethengosources{gits=mkGit:httpssources}moreelseif"git:"`T.isPrefixOf`namethengosources{gits=mkGit:gitssources}moreelsegosources{hackages=mkPkg:hackagessources}morewheremkDir=Directory(fromTextname)flagsmkPkg=PackagenameflagsmkGit=let(realFlags,tags)=partition(T.isPrefixOf"-")flagsiniflengthtags>1thenerror$unpack$"did not understand"<>T.intercalate" "(asList(Packagenameflags))elseGitPackagenamerealFlags(headMaytags)