{- hake: make tool. ruby : rake = haskell : hake
Copyright (C) 2008-2008 Yoshikuni Jujo <PAF01143@nifty.ne.jp>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-}moduleDevelopment.Hake(Rule,hake,hakeT,hakefileIs,base,dflt,deps,mkfl,addDeps,delRules,setCmd,systemE,rawSystemE,isSuffixOf,changeSuffix,getVals,getNewers,ExitCode(ExitSuccess,ExitFailure),const2)whereimportSystem.Environment(getArgs)importSystem.Exit(ExitCode(ExitSuccess,ExitFailure))importSystem.Directory(doesFileExist)importSystem.Directory.Tools(maybeGetModificationTime)importSystem.IO.Unsafe(unsafeInterleaveIO)importControl.Monad.Trans(lift)importControl.Monad.Reader(ReaderT(runReaderT),asks)importControl.Monad.Tools(whenM)importControl.Applicative((<$>))importData.List(isSuffixOf,isPrefixOf)importData.List.Tools(dropUntil,isIncludedElem)importData.Maybe(listToMaybe,catMaybes)importData.Bool.Tools((&&&),(|||))importData.Function.Tools(const2)importDevelopment.Hake.Core(traceRule,applyRule)importDevelopment.Hake.RunHake(runHake)importDevelopment.Hake.Tools(orDie,changeSuffix,systemE,rawSystemE)importDevelopment.Hake.Types(Rule,RuleInner,ruleToRuleInner,Targets,Sources,Commands,MadeFromList,ruleRetToMadeFromList,getUpdateStatus)importDevelopment.Hake.Variables(hakefileUpdateOption,defaultTrgtStr)-- |The 'hake' function take rules as argument and get target from command line-- and make target.hake::[Rule]->IO()hakerl=doargs<-filter(notElem'=')<$>getArgsletud=elemhakefileUpdateOptionargstrgts=filter(/=hakefileUpdateOption)argsmapM_(hakeTargetud(mapruleToRuleInnerrl))trgtshakeT::[Rule]->FilePath->IO()hakeT=hakeTargetTrue.mapruleToRuleInnerhakefileIs::FilePath->[FilePath]->IOExitCodehakefileIssrcothers=getArgs>>=runHakesrcsrcothershakeTarget::Bool->[RuleInner]->FilePath->IO()hakeTargetudrlsfn=dorrls<-traceRuleunsafeInterleaveIOdoesFileExistfnrlscaserrlsof[]->error$"No usable rules for make target '"++fn++"'"r:_->fliprunReaderT(ud,ruleRetToMadeFromListr)$mapM_applyRule$reverseraddDeps::[Rule]->[(FilePath,[FilePath])]->[Rule]addDepsrlsadrls=concatMapadadrls++mapdelsrlswheread::(FilePath,[FilePath])->[Rule]ad(t,ss)=[((==t),const$sgent++ss,c)|(testT,sgen,c)<-rls,testTt]dels::Rule->Ruledelsr=foldrdelr$mapfstadrlsdel::FilePath->Rule->Ruledeltr@(pt,_,_)|ptt=modifyFirstOfThree(&&&(/=t))r|otherwise=rmodifyFirstOfThreef(x,y,z)=(fx,y,z)delRules::[Rule]->[(FilePath,[FilePath])]->[Rule]delRulesrlsdelrls=mapdelsrlswheredels::Rule->Ruledelsr=foldrdelrdelrlsdel::(FilePath,[FilePath])->Rule->Ruledel(t,ss)r@(pt,mkSs,_)|ptt&&isIncludedElemss(mkSst)=modifyFirstOfThree(&&&(/=t))r|otherwise=rmodifyFirstOfThreef(x,y,z)=(fx,y,z)setCmd::Rule->(String->[String]->MadeFromList->IOExitCode)->RulesetCmd(trgts,srcs,_)cmdsGen=(trgts,srcs,cmd)wherecmd::Commandscmdts=domfl<-askssndlift$cmdsGentsmfl`orDie`showgetVals::String->[String]->[String]getValsvarargs=maybe[]words$dropUntil(=='=')<$>(listToMaybe$filter(isPrefixOf$var++"=")args)getNewers::FilePath->[FilePath]->IO[FilePath]getNewersfbfs=catMaybes<$>mapMgetNewerfswheregetNewer::FilePath->IO(MaybeFilePath)getNewerf=dotb<-maybeGetModificationTimefbt<-maybeGetModificationTimefif(tb<t)thenreturn$JustfelsereturnNothingbase::Targets->Sources->(String->[String]->MadeFromList->Bool->IOExitCode)->RulebasetrgtssrcscmdsGen=(trgts,srcs,cmd)wherecmd::Commandscmdts=domfl<-askssndus<-asksfstlift$cmdsGentsmflus`orDie`showdflt::[String]->Ruledflttrgts=((==defaultTrgtStr),consttrgts,const2$return())deps::[String]->[String]->Ruledepstrgtssrcs=(\f->or$map(==f)trgts,constsrcs,const2$return())mkfl::String->[String]->Rulemkfltrgtcont=((==trgt),const[],\t->const$dowhenM(getUpdateStatus|||lift(not<$>doesFileExisttrgt))$dolift$putStrLn$"make file `"++trgt++"' (hake)"lift$writeFilet$unlinescont)