123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386(**************************************************************************)(* *)(* Copyright 2015-2020 OCamlPro *)(* *)(* All rights reserved. This file is distributed under the terms of the *)(* GNU Lesser General Public License version 2.1, with the special *)(* exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)openOpamTypesopenOpamStateTypesmoduleE=structtypeOpamStd.Config.E.t+=|BUILDDOCofbooloption|BUILDTESTofbooloption|DOWNLOADJOBSofintoption|DRYRUNofbooloption|IGNORECONSTRAINTSofstringoption|JOBSofintoption|LOCKEDofstringoption|MAKECMDofstringoption|NODEPEXTSofbooloption|NOENVNOTICEofbooloption|ROOTofstringoption|SWITCHofstringoption|UNLOCKBASEofbooloption|WITHDOCofbooloption|WITHTESTofbooloptionopenOpamStd.Config.Eletbuilddoc=value(functionBUILDDOCb->b|_->None)letbuildtest=value(functionBUILDTESTb->b|_->None)letdownloadjobs=value(functionDOWNLOADJOBSi->i|_->None)letdryrun=value(functionDRYRUNb->b|_->None)letignoreconstraints=value(functionIGNORECONSTRAINTSs->s|_->None)letjobs=value(functionJOBSi->i|_->None)letlocked=value(functionLOCKEDs->s|_->None)letmakecmd=value(functionMAKECMDs->s|_->None)letnodepexts=value(functionNODEPEXTSb->b|_->None)letnoenvnotice=value(functionNOENVNOTICEb->b|_->None)letroot=value(functionROOTs->s|_->None)letswitch=value(functionSWITCHs->s|_->None)letunlockbase=value(functionUNLOCKBASEb->b|_->None)letwithdoc=value(functionWITHDOCb->b|_->None)letwithtest=value(functionWITHTESTb->b|_->None)endtypet={root_dir:OpamFilename.Dir.t;current_switch:OpamSwitch.toption;switch_from:provenance;jobs:intLazy.t;dl_jobs:int;build_test:bool;build_doc:bool;dryrun:bool;makecmd:stringLazy.t;ignore_constraints_on:name_set;unlock_base:bool;no_env_notice:bool;locked:stringoption;no_depexts:bool;}letdefault={root_dir=OpamFilename.(concat_and_resolve(Dir.of_string(OpamStd.Sys.home()))".opam");current_switch=None;switch_from=`Default;jobs=lazy(max1(OpamSysPoll.cores()-1));dl_jobs=3;build_test=false;build_doc=false;dryrun=false;makecmd=lazyOpamStd.Sys.(matchos()with|FreeBSD|OpenBSD|NetBSD|DragonFly->"gmake"|_->"make");ignore_constraints_on=OpamPackage.Name.Set.empty;unlock_base=false;no_env_notice=false;locked=None;no_depexts=false;}type'aoptions_fun=?root_dir:OpamFilename.Dir.t->?current_switch:OpamSwitch.t->?switch_from:provenance->?jobs:(intLazy.t)->?dl_jobs:int->?build_test:bool->?build_doc:bool->?dryrun:bool->?makecmd:stringLazy.t->?ignore_constraints_on:name_set->?unlock_base:bool->?no_env_notice:bool->?locked:stringoption->?no_depexts:bool->'aletsetkkt?root_dir?current_switch?switch_from?jobs?dl_jobs?build_test?build_doc?dryrun?makecmd?ignore_constraints_on?unlock_base?no_env_notice?locked?no_depexts=let(+)xopt=matchoptwithSomex->x|None->xink{root_dir=t.root_dir+root_dir;current_switch=(matchcurrent_switchwithNone->t.current_switch|s->s);switch_from=t.switch_from+switch_from;jobs=t.jobs+jobs;dl_jobs=t.dl_jobs+dl_jobs;build_test=t.build_test+build_test;build_doc=t.build_doc+build_doc;dryrun=t.dryrun+dryrun;makecmd=t.makecmd+makecmd;ignore_constraints_on=t.ignore_constraints_on+ignore_constraints_on;unlock_base=t.unlock_base+unlock_base;no_env_notice=t.no_env_notice+no_env_notice;locked=t.locked+locked;no_depexts=t.no_depexts+no_depexts;}letsett=setk(funx()->x)tletr=refdefaultletupdate?noop:_=setk(funcfg()->r:=cfg)!rletinitkk=letopenOpamStd.Option.Opinletcurrent_switch,switch_from=matchE.switch()with|Some""|None->None,None|Somes->Some(OpamSwitch.of_strings),Some`Envinsetk(setk(func->r:=c;k))!r?root_dir:(E.root()>>|OpamFilename.Dir.of_string)?current_switch?switch_from?jobs:(E.jobs()>>|funs->lazys)?dl_jobs:(E.downloadjobs())?build_test:(E.withtest()++E.buildtest())?build_doc:(E.withdoc()++E.builddoc())?dryrun:(E.dryrun())?makecmd:(E.makecmd()>>|funs->lazys)?ignore_constraints_on:(E.ignoreconstraints()>>|funs->OpamStd.String.splits','|>List.mapOpamPackage.Name.of_string|>OpamPackage.Name.Set.of_list)?unlock_base:(E.unlockbase())?no_env_notice:(E.noenvnotice())?locked:(E.locked()>>|function""->None|s->Somes)?no_depexts:(E.nodepexts())letinit?noop:_=initk(fun()->())letopamroot?root_dir()=letopenOpamStd.Option.Opin(root_dir>>+fun()->OpamStd.Env.getopt"OPAMROOT">>|OpamFilename.Dir.of_string)+!default.root_dirletis_newer_raw=function|Somev->OpamVersion.comparevOpamFile.Config.root_version>0|None->falseletis_newerconfig=is_newer_raw(Some(OpamFile.Config.opam_root_versionconfig))(** none -> shouldn't load (write attempt in readonly)
Some true -> everything is fine normal read
Some false -> readonly accorded, load with best effort *)letis_readonly_opamroot_raw?(lock_kind=`Lock_write)version=letnewer=is_newer_rawversioninletwrite=lock_kind=`Lock_writeinifnewer&&writethenNoneelseSome(newer&¬write)letis_readonly_opamroot_t?lock_kindgt=is_readonly_opamroot_raw?lock_kind(Some(OpamFile.Config.opam_root_versiongt.config))letis_newer_than_self?lock_kindgt=is_readonly_opamroot_t?lock_kindgt<>Somefalseletload_if_possible_raw?lock_kindrootversion(read,read_wo_err)f=matchis_readonly_opamroot_raw?lock_kindversionwith|None->OpamConsole.error_and_exit`Locked"Refusing write access to %s, which is more recent than this version of \
opam (%s > %s), aborting."(OpamFilename.Dir.to_stringroot)(OpamStd.Option.to_stringOpamVersion.to_stringversion)OpamVersion.(to_stringcurrent_nopatch)|Sometrue->read_wo_errf|Somefalse->readfletload_if_possible_t?lock_kindopamrootconfigreadff=load_if_possible_raw?lock_kindopamroot(Some(OpamFile.Config.opam_root_versionconfig))readffletload_if_possible?lock_kindgt=load_if_possible_t?lock_kindgt.rootgt.configletload_config_root?lock_kindreadfopamroot=letf=OpamPath.configopamrootinload_if_possible_raw?lock_kindopamroot(OpamFile.Config.raw_root_versionf)readffletsafereadread'default=letsaferf=OpamStd.Option.defaultdefault@@rfinsaferead,saferead'letsafe_load?lock_kindopamroot=load_config_root?lock_kindOpamFile.Config.(saferead_optBestEffort.read_optempty)opamrootletload?lock_kindopamroot=load_config_root?lock_kindOpamFile.Config.(read_opt,BestEffort.read_opt)opamroot(* switches *)moduleSwitch=structletload_raw?lock_kindrootconfigreadfswitch=load_if_possible_t?lock_kindrootconfigreadf(OpamPath.Switch.switch_configrootswitch)letsafe_load_t?lock_kindrootswitch=letconfig=safe_load~lock_kind:`Lock_readrootinload_raw?lock_kindrootconfigOpamFile.Switch_config.(saferead_optBestEffort.read_optempty)switchletload?lock_kindgtreadfswitch=load_raw?lock_kindgt.rootgt.configreadfswitchletsafe_load?lock_kindgtswitch=load?lock_kindgtOpamFile.Switch_config.(saferead_optBestEffort.read_optempty)switchletread_opt?lock_kindgtswitch=load?lock_kindgtOpamFile.Switch_config.(read_opt,BestEffort.read_opt)switchletsafe_read_selections?lock_kindgtswitch=load_if_possible?lock_kindgtOpamFile.SwitchSelections.(saferead_optBestEffort.read_optempty)(OpamPath.Switch.selectionsgt.rootswitch)end(* repos *)moduleRepos=structletsafe_read?lock_kindgt=load_if_possible?lock_kindgtOpamFile.Repos_config.(saferead_optBestEffort.read_optempty)(OpamPath.repos_configgt.root)endletdowngrade_2_1_switchf=letfilename=OpamFile.filenamefinletstr_f=OpamFilename.to_stringfilenameinletopamfile=OpamParser.FullPos.filestr_finletopamfile'=letopenOpamParserTypes.FullPosin{opamfilewithfile_contents=List.map(funitem->matchitem.pelemwith|Variable(({pelem="opam-version";_}asopam_v),({pelem=String"2.1";_}asv))->{itemwithpelem=Variable({opam_vwithpelem="opam-version"},{vwithpelem=String"2.0"})}|_->item)opamfile.file_contents}inifopamfile'=opamfilethenNoneelseSome(opamfile'|>OpamPrinter.FullPos.opamfile|>OpamFile.Switch_config.read_from_string)letlocal_switch_existsrootswitch=(* we don't use safe loading function to avoid errors displaying *)letf=OpamPath.Switch.switch_configrootswitchinmatchOpamFile.Switch_config.BestEffort.read_optfwith|None->false|Someconf->conf.OpamFile.Switch_config.opam_root=Someroot|exception(OpamPp.Bad_version_ase)->matchOpamFile.Config.raw_root_version(OpamPath.configroot)with|None->raisee|Some_->matchdowngrade_2_1_switchfwith|None->raisee|Someconf->ifconf.OpamFile.Switch_config.opam_root=Somerootthen(OpamFile.Switch_config.writefconf;true)elsefalseletresolve_local_switchroots=letswitch_root=OpamSwitch.get_rootrootsinifOpamSwitch.is_externals&&OpamFilename.dirname_dirswitch_root=rootthenOpamSwitch.of_string(OpamFilename.remove_prefix_dirrootswitch_root)elsesletget_current_switch_from_cwdroot=tryletopenOpamStd.Option.OpinOpamFilename.find_in_parents(fundir->OpamSwitch.of_string(OpamFilename.Dir.to_stringdir)|>local_switch_existsroot)(OpamFilename.cwd())>>|OpamSwitch.of_dirname>>|resolve_local_switchrootwithOpamPp.Bad_version_->None(* do we want `load_defaults` to fail / run a format upgrade ? *)letload_defaults?lock_kindroot_dir=letcurrent_switch=matchE.switch()with|Some""|None->get_current_switch_from_cwdroot_dir|_->(* OPAMSWITCH is set, no need to lookup *)Noneinmatchtryload?lock_kindroot_dirwithOpamPp.Bad_version_->Nonewith|None->update?current_switch();None|Someconf->letopenOpamStd.Option.OpinOpamRepositoryConfig.update?download_tool:(OpamFile.Config.dl_toolconf>>|function|(CStringc,None)::_astwhenOpamStd.String.ends_with~suffix:"curl"c->lazy(t,`Curl)|t->lazy(t,`Default))~validation_hook:(OpamFile.Config.validation_hookconf)();update?current_switch:(OpamFile.Config.switchconf)~switch_from:`Default?jobs:(OpamFile.Config.jobsconf>>|funs->lazys)~dl_jobs:(OpamFile.Config.dl_jobsconf)();update?current_switch();Someconfletget_switch_opt()=match!r.current_switchwith|Somes->Some(resolve_local_switch!r.root_dirs)|None->Noneletget_switch()=matchget_switch_opt()with|Somes->s|None->OpamConsole.error_and_exit`Configuration_error"No switch is currently set. Please use 'opam switch' to set or install \
a switch"