12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313(**************************************************************************)(* *)(* Copyright 2012-2015 OCamlPro *)(* Copyright 2012 INRIA *)(* *)(* 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. *)(* *)(**************************************************************************)openOpamTypesopenOpamTypesBaseopenCmdlineropenOpamStd.Op(* Global options *)typeglobal_options={debug_level:intoption;verbose:int;quiet:bool;color:[`Always|`Never|`Auto]option;opt_switch:stringoption;yes:bool;strict:bool;opt_root:dirnameoption;git_version:bool;external_solver:stringoption;use_internal_solver:bool;cudf_file:stringoption;solver_preferences:stringoption;best_effort:bool;safe_mode:bool;json:stringoption;no_auto_upgrade:bool;working_dir:bool;ignore_pin_depends:bool;}letcreate_global_optionsgit_versiondebugdebug_levelverbosequietcoloropt_switchyesstrictopt_rootexternal_solveruse_internal_solvercudf_filesolver_preferencesbest_effortsafe_modejsonno_auto_upgradeworking_dirignore_pin_depends=letdebug_level=OpamStd.Option.Op.(debug_level>>+fun()->ifdebugthenSome1elseNone)inletverbose=List.lengthverbosein{git_version;debug_level;verbose;quiet;color;opt_switch;yes;strict;opt_root;external_solver;use_internal_solver;cudf_file;solver_preferences;best_effort;safe_mode;json;no_auto_upgrade;working_dir;ignore_pin_depends;}letapply_global_optionso=ifo.git_versionthen(beginmatchOpamGitVersion.versionwith|None->()|Somev->OpamConsole.msg"%s\n"vend;OpamStd.Sys.exit_because`Success);letopenOpamStd.Option.Opinletflagf=iffthenSometrueelseNoneinletsomex=matchxwithNone->None|some->Somesomeinletsolver=ifo.use_internal_solverthenSome(lazy(OpamCudfSolver.get_solver~internal:trueOpamCudfSolver.default_solver_selection))elseo.external_solver>>|funs->lazy(OpamCudfSolver.solver_of_strings)inletsolver_prefs=o.solver_preferences>>|funp->lazy(Somep)inOpamClientConfig.opam_init(* - format options - *)?strict:(flago.strict)(* ?skip_version_checks:bool *)(* ?all_parens:bool *)(* - core options - *)?debug_level:(ifo.safe_modethenSome0elseo.debug_level)?verbose_level:(ifo.quietthenSome0elseifo.verbose=0thenNoneelseSomeo.verbose)?color:o.color(* ?utf8:[ `Extended | `Always | `Never | `Auto ] *)(* ?disp_status_line:[ `Always | `Never | `Auto ] *)?answer:(some(flago.yes))?safe_mode:(flago.safe_mode)(* ?lock_retries:int *)(* ?log_dir:OpamTypes.dirname *)(* ?keep_log_dir:bool *)(* - repository options - *)(* ?download_tool:(OpamTypes.arg list * dl_tool_kind) Lazy.t *)(* ?retries:int *)(* ?force_checksums:bool option *)(* - solver options *)?cudf_file:(someo.cudf_file)?solver?best_effort:(flago.best_effort)?solver_preferences_default:solver_prefs?solver_preferences_upgrade:solver_prefs?solver_preferences_fixup:solver_prefs(* ?solver_preferences_best_effort_prefix: *)(* - state options - *)?root_dir:o.opt_root?current_switch:(o.opt_switch>>|OpamSwitch.of_string)?switch_from:(o.opt_switch>>|fun_->`Command_line)(* ?jobs: int *)(* ?dl_jobs: int *)(* ?keep_build_dir:bool *)(* ?build_test:bool *)(* ?build_doc:bool *)(* ?show:bool *)(* ?dryrun:bool *)(* ?fake:bool *)(* ?makecmd:string Lazy.t *)(* ?ignore_constraints_on:name_set *)(* ?skip_dev_update:bool *)?json_out:OpamStd.Option.Op.(o.json>>|function""->None|s->Somes)(* ?root_is_ok:bool *)?no_auto_upgrade:(flago.no_auto_upgrade)(* - client options - *)?working_dir:(flago.working_dir)?ignore_pin_depends:(flago.ignore_pin_depends)(* ?print_stats:bool *)(* ?sync_archives:bool *)(* ?pin_kind_auto:bool *)(* ?autoremove:bool *)(* ?editor:string *)();ifOpamClientConfig.(!r.json_out<>None)then(OpamJson.append"opam-version"(`StringOpamVersion.(to_string(full())));OpamJson.append"command-line"(`A(List.map(funs->`Strings)(Array.to_listSys.argv))))(* Build options *)typebuild_options={keep_build_dir:bool;reuse_build_dir:bool;inplace_build:bool;make:stringoption;no_checksums:bool;req_checksums:bool;build_test:bool;build_doc:bool;show:bool;dryrun:bool;fake:bool;skip_update:bool;jobs:intoption;ignore_constraints_on:namelistoption;unlock_base:bool;locked:stringoption;}letcreate_build_optionskeep_build_dirreuse_build_dirinplace_buildmakeno_checksumsreq_checksumsbuild_testbuild_docshowdryrunskip_updatefakejobsignore_constraints_onunlock_baselocked={keep_build_dir;reuse_build_dir;inplace_build;make;no_checksums;req_checksums;build_test;build_doc;show;dryrun;skip_update;fake;jobs;ignore_constraints_on;unlock_base;locked;}letapply_build_optionsb=letflagf=iffthenSometrueelseNoneinletsomex=matchxwithNone->None|some->SomesomeinOpamRepositoryConfig.update(* ?download_tool:(OpamTypes.arg list * dl_tool_kind) Lazy.t *)(* ?retries:int *)?force_checksums:(ifb.req_checksumsthenSome(Sometrue)elseifb.no_checksumsthenSome(Somefalse)elseNone)();OpamStateConfig.update(* ?root: -- handled globally *)?jobs:OpamStd.Option.Op.(b.jobs>>|funj->lazyj)(* ?dl_jobs:int *)(* ?no_base_packages:(flag o.no_base_packages) -- handled globally *)?build_test:(flagb.build_test)?build_doc:(flagb.build_doc)?dryrun:(flagb.dryrun)?makecmd:OpamStd.Option.Op.(b.make>>|funm->lazym)?ignore_constraints_on:OpamStd.Option.Op.(b.ignore_constraints_on>>|OpamPackage.Name.Set.of_list)?unlock_base:(flagb.unlock_base)?locked:(someb.locked)();OpamClientConfig.update?keep_build_dir:(flagb.keep_build_dir)?reuse_build_dir:(flagb.reuse_build_dir)?inplace_build:(flagb.inplace_build)?show:(flagb.show)?fake:(flagb.fake)?skip_dev_update:(flagb.skip_update)()letwhen_enum=["always",`Always;"never",`Never;"auto",`Auto](* Help sections common to all commands *)letglobal_option_section="COMMON OPTIONS"lethelp_sections=[`Sglobal_option_section;`P"These options are common to all commands.";`S"ENVIRONMENT VARIABLES";`P"Opam makes use of the environment variables listed here. Boolean \
variables should be set to \"0\", \"no\", \"false\" or the empty string \
to disable, \"1\", \"yes\" or \"true\" to enable.";(* Alphabetical order *)`P"$(i,OPAMCOLOR), when set to $(i,always) or $(i,never), sets a default \
value for the --color option.";`P("$(i,OPAMCRITERIA) specifies user $(i,preferences) for dependency \
solving. The default value depends on the solver version, use `config \
report` to know the current setting. See also option --criteria");`P"$(i,OPAMCURL) can be used to select a given 'curl' program. See \
$(i,OPAMFETCH) for more options.";`P"$(i,OPAMDEBUG) see options `--debug' and `--debug-level'.";`P"$(i,OPAMDOWNLOADJOBS) sets the maximum number of simultaneous downloads.";`P"$(i,OPAMERRLOGLEN) sets the number of log lines printed when a \
sub-process fails. 0 to print all.";`P"$(i,OPAMEXTERNALSOLVER) see option `--solver'.";`P"$(i,OPAMFETCH) specifies how to download files: either `wget', `curl' or \
a custom command where variables $(b,%{url}%), $(b,%{out}%), \
$(b,%{retry}%), $(b,%{compress}%) and $(b,%{checksum}%) will \
be replaced. Overrides the \
'download-command' value from the main config file.";`P"$(i,OPAMJOBS) sets the maximum number of parallel workers to run.";`P"$(i,OPAMJSON) log json output to the given file (use character `%' to \
index the files)";`P"$(i,OPAMLOCK) see option `--lock'.";`P"$(i,OPAMNOAUTOUPGRADE) disables automatic internal upgrade of \
repositories in an earlier format to the current one, on 'update' or \
'init'.";`P"$(i,OPAMKEEPLOGS) tells opam to not remove some temporary command logs \
and some backups. This skips some finalisers and may also help to get \
more reliable backtraces";`P"$(i,OPAMLOCKRETRIES) sets the number of tries after which OPAM gives up \
acquiring its lock and fails. <= 0 means infinite wait.";`P"$(i,OPAMNO) answer no to any question asked.";`P"$(i,OPAMNOASPCUD) see option `--no-aspcud'.";`P"$(i,OPAMNOSELFUPGRADE) see option `--no-self-upgrade'.";`P"$(i,OPAMPINKINDAUTO) sets whether version control systems should be \
detected when pinning to a local path. Enabled by default since 1.3.0.";`P"$(i,OPAMREQUIRECHECKSUMS) Enables option `--require-checksums' when \
available (e.g. for `opam install`).";`P"$(i,OPAMRETRY) sets the number of tries before failing downloads.";`P"$(i,OPAMROOT) see option `--root'. This is automatically set by \
`opam env --root=DIR --set-root'.";`P"$(i,OPAMROOTISOK) don't complain when running as root.";`P"$(i,OPAMSAFE) see option `--safe'";`P"$(i,OPAMSKIPVERSIONCHECKS) bypasses some version checks. Unsafe, for \
compatibility testing only.";`P(Printf.sprintf"$(i,OPAMSOLVERTIMEOUT) change the time allowance of the solver. \
Default is %.1f, set to 0 for unlimited. Note that all solvers may \
not support this option."(OpamStd.Option.default0.OpamSolverConfig.(default.solver_timeout)));`P("$(i,OPAMSTATUSLINE) display a dynamic status line showing what's \
currently going on on the terminal. \
(one of "^Arg.doc_alts_enumwhen_enum^")");`P"$(i,OPAMSWITCH) see option `--switch'. Automatically set by \
`opam env --switch=SWITCH --set-switch'.";`P("$(i,OPAMUPGRADECRITERIA) specifies user $(i,preferences) for dependency \
solving when performing an upgrade. Overrides $(i,OPAMCRITERIA) in \
upgrades if both are set. See also option --criteria");`P"$(i,OPAMUSEINTERNALSOLVER) see option `--use-internal-solver'.";`P("$(i,OPAMUTF8) use UTF8 characters in output \
(one of "^Arg.doc_alts_enumwhen_enum^"). By default `auto', which is determined from the locale).");`P"$(i,OPAMUTF8MSGS) use extended UTF8 characters (camels) in opam \
messages. Implies $(i,OPAMUTF8). This is set by default on OSX only.";`P"$(i,OPAMVAR_var) overrides the contents of the variable $(i,var) when \
substituting `%{var}%` strings in `opam` files.";`P"$(i,OPAMVAR_package_var) overrides the contents of the variable \
$(i,package:var) when substituting `%{package:var}%` strings in \
`opam` files.";`P"$(i,OPAMVERBOSE) see option `--verbose'.";`P"$(i,OPAMYES) see option `--yes'.";`S"EXIT STATUS";`P"As an exception to the following, the `exec' command returns 127 if the \
command was not found or couldn't be executed, and the command's exit \
value otherwise."]@List.map(fun(reason,code)->`I(string_of_intcode,matchreasonwith|`Success->"Success, or true for boolean queries."|`False->"False. Returned when a boolean return value is expected, e.g. when \
running with $(b,--check), or for queries like $(b,opam lint)."|`Bad_arguments->"Bad command-line arguments, or command-line arguments pointing to \
an invalid context (e.g. file not following the expected format)."|`Not_found->"Not found. You requested something (package, version, repository, \
etc.) that couldn't be found."|`Aborted->"Aborted. The operation required confirmation, which wasn't given."|`Locked->"Could not acquire the locks required for the operation."|`No_solution->"There is no solution to the user request. This can be caused by \
asking to install two incompatible packages, for example."|`File_error->"Error in package definition, or other metadata files. Using \
$(b,--strict) raises this error more often."|`Package_operation_error->"Package script error. Some package operations were unsuccessful. \
This may be an error in the packages or an incompatibility with \
your system. This can be a partial error."|`Sync_error->"Sync error. Could not fetch some remotes from the network. This can \
be a partial error."|`Configuration_error->"Configuration error. Opam or system configuration doesn't allow \
operation, and needs fixing."|`Solver_failure->"Solver failure. The solver failed to return a sound answer. It can \
be due to a broken external solver, or an error in solver \
configuration."|`Internal_error->"Internal error. Something went wrong, likely due to a bug in opam \
itself."|`User_interrupt->"User interrupt. SIGINT was received, generally due to the user \
pressing Ctrl-C."))OpamStd.Sys.exit_codes@[`S"FURTHER DOCUMENTATION";`P(Printf.sprintf"See https://opam.ocaml.org/doc.");`S"AUTHORS";`P"Vincent Bernardoff <vb@luminar.eu.org>";`Noblank;`P"Raja Boujbel <raja.boujbel@ocamlpro.com>";`Noblank;`P"Roberto Di Cosmo <roberto@dicosmo.org>";`Noblank;`P"Thomas Gazagnaire <thomas@gazagnaire.org>";`Noblank;`P"Louis Gesbert <louis.gesbert@ocamlpro.com>";`Noblank;`P"Fabrice Le Fessant <Fabrice.Le_fessant@inria.fr>";`Noblank;`P"Anil Madhavapeddy <anil@recoil.org>";`Noblank;`P"Guillem Rieu <guillem.rieu@ocamlpro.com>";`Noblank;`P"Ralf Treinen <ralf.treinen@pps.jussieu.fr>";`Noblank;`P"Frederic Tuong <tuong@users.gforge.inria.fr>";`S"BUGS";`P"Check bug reports at https://github.com/ocaml/opam/issues.";](* Converters *)letpr_str=Format.pp_print_stringletrepository_name=letparsestr=`Ok(OpamRepositoryName.of_stringstr)inletprintppfname=pr_strppf(OpamRepositoryName.to_stringname)inparse,printleturl=letparsestr=`Ok(OpamUrl.parsestr)inletprintppfurl=pr_strppf(OpamUrl.to_stringurl)inparse,printletfilename=letparsestr=`Ok(OpamFilename.of_stringstr)inletprintppffilename=pr_strppf(OpamFilename.to_stringfilename)inparse,printletexisting_filename_or_dash=letparsestr=ifstr="-"then`OkNoneelseletf=OpamFilename.of_stringstrinifOpamFilename.existsfthen`Ok(Somef)else`Error(Printf.sprintf"File %s not found"(OpamFilename.to_stringf))inletprintppffilename=pr_strppfOpamStd.Option.Op.((filename>>|OpamFilename.to_string)+!"-")inparse,printletdirname=letparsestr=`Ok(OpamFilename.Dir.of_stringstr)inletprintppfdir=pr_strppf(OpamFilename.prettify_dirdir)inparse,printletexisting_filename_dirname_or_dash=letparsestr=ifstr="-"then`OkNoneelsematchOpamFilename.opt_file(OpamFilename.of_stringstr)with|Somef->`Ok(Some(OpamFilename.Ff))|None->matchOpamFilename.opt_dir(OpamFilename.Dir.of_stringstr)with|Somed->`Ok(Some(OpamFilename.Dd))|None->`Error(Printf.sprintf"File or directory %s not found"str)inletprintppfgf=pr_strppf@@matchgfwith|None->"-"|Some(OpamFilename.Dd)->OpamFilename.Dir.to_stringd|Some(OpamFilename.Ff)->OpamFilename.to_stringfinparse,printletpackage_name=letparsestr=try`Ok(OpamPackage.Name.of_stringstr)withFailuremsg->`Errormsginletprintppfpkg=pr_strppf(OpamPackage.Name.to_stringpkg)inparse,printletpositive_integer:intArg.converter=let(parser,printer)=Arg.intinletparsers=matchparserswith|`Error_->`Error"expected a strictly positive integer"|`Oknasr->ifn<=0then`Error"expected a positive integer"elserin(parser,printer)(* name * version option *)letpackage=letparsestr=letre=Re.(compile@@seq[bos;group@@rep1@@diffany(set">=<.!");opt@@seq[set".=";group@@rep1any];eos;])intryletsub=Re.execrestrinletname=OpamPackage.Name.of_string(Re.getsub1)inletversion_opt=trySome(OpamPackage.Version.of_string(Re.getsub2))withNot_found->Nonein`Ok(name,version_opt)withNot_found|Failure_->`Error"bad package format"inletprintppf(name,version_opt)=matchversion_optwith|None->pr_strppf(OpamPackage.Name.to_stringname)|Somev->pr_strppf(OpamPackage.Name.to_stringname^"."^OpamPackage.Version.to_stringv)inparse,printletpackage_with_version=letparsestr=matchfstpackagestrwith|`Ok(n,Somev)->`Ok(OpamPackage.createnv)|`Ok(_,None)->`Error"missing package version"|`Errore->`Erroreinletprintppfnv=pr_strppf(OpamPackage.to_stringnv)inparse,print(* name * version constraint *)letatom=letparsestr=letre=Re.(compile@@seq[bos;group@@rep1@@diffany(set">=<.!");group@@alt[seq[set"<>";opt@@char'='];set"=.";str"!=";];group@@rep1any;eos;])intryletsub=Re.execrestrinletsname=Re.getsub1inletsop=Re.getsub2inletsversion=Re.getsub3inletname=OpamPackage.Name.of_stringsnameinletsop=ifsop="."then"="elsesopinletop=OpamLexer.relopsopinletversion=OpamPackage.Version.of_stringsversionin`Ok(name,Some(op,version))withNot_found|Failure_|OpamLexer.Error_->try`Ok(OpamPackage.Name.of_stringstr,None)withFailuremsg->`Errormsginletprintppfatom=pr_strppf(OpamFormula.short_string_of_atomatom)inparse,printletatom_or_local=letparsestr=ifOpamStd.String.contains~sub:Filename.dir_sepstr||OpamStd.String.starts_with~prefix:"."strthenifOpamFilename.(exists(of_stringstr))then`Ok(`Filename(OpamFilename.of_stringstr))elseifOpamFilename.(exists_dir(Dir.of_stringstr))then`Ok(`Dirname(OpamFilename.Dir.of_stringstr))else`Error(Printf.sprintf"Not a valid package specification or existing file or \
directory: %s"str)elsematchfstatomstrwith|`Okat->`Ok(`Atomat)|`Errore->`Erroreinletprintppf=function|`Filenamef->pr_strppf(OpamFilename.to_stringf)|`Dirnamed->pr_strppf(OpamFilename.Dir.to_stringd)|`Atoma->sndatomppfainparse,printletatom_or_dir=letparsestr=matchfstatom_or_localstrwith|`Ok(`Filename_)->`Error(Printf.sprintf"Not a valid package specification or existing directory: %s"str)|`Ok(`Atom_|`Dirname_asatom_or_dir)->`Ok(atom_or_dir)|`Errore->`Erroreinletprintppf=sndatom_or_localppfinparse,printletvariable_bindings=letparsestr=tryOpamStd.String.splitstr','|>List.map(funs->matchOpamStd.String.cut_ats'='with|Some(a,b)->OpamVariable.of_stringa,b|None->Printf.ksprintffailwith"%S is not a binding"s)|>funbnds->`OkbndswithFailuree->`Erroreinletprintppfx=List.map(fun(a,b)->Printf.sprintf"%s=%s"(OpamVariable.to_stringa)b)x|>String.concat","|>pr_strppfinparse,printletwarn_selector=letparsestr=letsep=Re.(compile(set"+-"))inletsel=Re.(compile@@seq[bos;group(rep1digit);opt@@seq[str"..";group(rep1digit)];eos])inletrecseqij=ifi=jthen[i]elseifi<jtheni::seq(i+1)jelsej::seq(j+1)iinletrecauxacc=function|`Delimd::`Textn::r->letnums=letg=Re.execselninleti=int_of_string(Re.Group.getg1)intryseqi(int_of_string(Re.Group.getg2))withNot_found->[i]inletenabled=Re.Group.getd0="+"inletacc=List.fold_left(funaccn->(n,enabled)::acc)accnumsinauxaccr|[]->acc|_->raiseNot_foundintry`Ok(List.rev(aux[](Re.split_fullsepstr)))withNot_found->`Error"Expected a warning string, e.g. '--warn=-10..21+12-36'"inletprintppfwarns=pr_strppf@@OpamStd.List.concat_map""(fun(num,enable)->Printf.sprintf"%c%d"(ifenablethen'+'else'-')num)warnsinparse,printtype'adefault=[>`defaultofstring]as'aletenum_with_defaultsl:'aArg.converter=letparse,print=Arg.enumslinletparses=matchparseswith|`Ok_asx->x|_->`Ok(`defaults)inparse,printletopamlist_column=letparsestr=ifOpamStd.String.ends_with~suffix:":"strthenletfld=OpamStd.String.remove_suffix~suffix:":"strin`Ok(OpamListCommand.Fieldfld)elsetryList.find(function(OpamListCommand.Field_),_->false|_,name->name=str)OpamListCommand.field_names|>fun(f,_)->`OkfwithNot_found->`Error(Printf.sprintf"No known printer for column %s. If you meant an opam file \
field, use '%s:' instead (with a trailing colon)."strstr)inletprintppffield=Format.pp_print_stringppf(OpamListCommand.string_of_fieldfield)inparse,printletopamlist_columns=letfield_re=(* max paren nesting 1, obviously *)Re.(compile@@seq[start;group@@seq[rep@@diffany(set",(");opt@@seq[char'(';rep(diffany(char')'));char')'];];alt[char',';stop];])inletparsestr=tryletrecauxpos=ifpos=String.lengthstrthen[]elseletg=Re.exec~posfield_restrinRe.Group.getg1::aux(Re.Group.stopg0)inletfields=aux0inList.fold_left(function|`Error_ase->fun_->e|`Okacc->funstr->matchfstopamlist_columnstrwith|`Okf->`Ok(acc@[f])|`Error_ase->e)(`Ok[])fieldswithNot_found->`Error(Printf.sprintf"Invalid columns specification: '%s'."str)inletprintppfcols=letrecaux=function|x::(_::_)asr->sndopamlist_columnppfx;Format.pp_print_charppf',';auxr|[x]->sndopamlist_columnppfx|[]->()inauxcolsinparse,print(* Helpers *)letmk_flag?sectionflagsdoc=letdoc=Arg.info?docs:section~docflagsinArg.(value&flag&doc)letmk_opt?section?voptflagsvaluedockinddefault=letdoc=Arg.info?docs:section~docv:value~docflagsinArg.(value&opt?voptkinddefault&doc)letmk_opt_all?section?vopt?(default=[])flagsvaluedockind=letdoc=Arg.info?docs:section~docv:value~docflagsinArg.(value&opt_all?voptkinddefault&doc)letmk_tristate_opt?sectionflagsvaluedoc=letdoc=Arg.info?docs:section~docv:value~docflagsinArg.(value&opt(some(enumwhen_enum))None&doc)type'asubcommand=string*'a*stringlist*stringtype'asubcommands='asubcommandlistletmk_subdoc?(defaults=[])commands=letbolds=Printf.sprintf"$(b,%s)"sinletits=Printf.sprintf"$(i,%s)"sin`S"COMMANDS"::(List.map(function|"",name->`P(Printf.sprintf"Without argument, defaults to %s."(boldname))|arg,default->`I(itarg,Printf.sprintf"With a %s argument, defaults to %s %s."(itarg)(bolddefault)(itarg)))defaults)@List.map(fun(c,_,args,d)->letcmds=boldc^" "^OpamStd.List.concat_map" "itargsin`I(cmds,d))commandsletmk_subcommands_auxmy_enumcommands=letcommand=letdoc=Arg.info~docv:"COMMAND"[]inletcommands=List.fold_left(funacc(c,f,_,_)->(c,f)::acc)[]commandsinArg.(value&pos0(some&my_enumcommands)None&doc)inletparams=letdoc=Arg.info~doc:"Optional parameters."[]inArg.(value&pos_right0string[]&doc)incommand,paramsletmk_subcommandscommands=mk_subcommands_auxArg.enumcommandsletmk_subcommands_with_defaultcommands=mk_subcommands_auxenum_with_defaultcommandsletmake_command_aliascmd?(options="")name=letterm,info=cmdinletorig=Term.nameinfoinletdoc=Printf.sprintf"An alias for $(b,%s%s)."origoptionsinletman=[`S"DESCRIPTION";`P(Printf.sprintf"$(mname)$(b, %s) is an alias for $(mname)$(b, %s%s)."nameorigoptions);`P(Printf.sprintf"See $(mname)$(b, %s --help) for details."orig);`S"OPTIONS";]@help_sectionsinterm,Term.infoname~docs:"COMMAND ALIASES"~doc~manletbad_subcommandsubcommands(command,usersubcommand,userparams)=matchusersubcommandwith|None->`Error(false,Printf.sprintf"Missing subcommand. Valid subcommands are %s."(OpamStd.Format.pretty_list(List.map(fun(a,_,_,_)->a)subcommands)))|Some(`defaultcmd)->`Error(true,Printf.sprintf"Invalid %s subcommand %S"commandcmd)|Someusersubcommand->letexe=Filename.basenameSys.executable_nameinmatchList.find_all(fun(_,cmd,_,_)->cmd=usersubcommand)subcommandswith|[name,_,args,_doc]->letusage=Printf.sprintf"%s %s [OPTION]... %s %s"execommandname(String.concat" "args)inifList.lengthuserparams<List.lengthargsthen`Error(false,Printf.sprintf"%s: Missing argument.\nUsage: %s\n"exeusage)else`Error(false,Printf.sprintf"%s: Too many arguments.\nUsage: %s\n"exeusage)|_->`Error(true,Printf.sprintf"Invalid %s subcommand"command)letterm_infotitle~doc~man=letman=man@help_sectionsinTerm.info~sdocs:global_option_section~docs:"COMMANDS"~doc~mantitleletarg_listnamedockind=letdoc=Arg.info~docv:name~doc[]inArg.(value&pos_allkind[]&doc)letnonempty_arg_listnamedockind=letdoc=Arg.info~docv:name~doc[]inArg.(non_empty&pos_allkind[]&doc)(* Common flags *)letprint_short_flag=mk_flag["s";"short"]"Output raw lists of names, one per line, skipping any details."letinstalled_roots_flag=mk_flag["installed-roots"]"Display only the installed roots."letshell_opt=letenum=["bash",SH_bash;"sh",SH_sh;"csh",SH_csh;"zsh",SH_zsh;"fish",SH_fish;]inmk_opt["shell"]"SHELL"(Printf.sprintf"Sets the configuration mode for opam environment appropriate for \
$(docv). One of %s. Guessed from the parent processes and the \\$SHELL \
variable by default."(Arg.doc_alts_enumenum))(Arg.some(Arg.enumenum))Noneletdot_profile_flag=mk_opt["dot-profile"]"FILENAME""Name of the configuration file to update instead of \
$(i,~/.profile) or $(i,~/.zshrc) based on shell detection."(Arg.somefilename)Noneletrepo_kind_flag=letmain_kinds=["http",`http;"local",`rsync;"git",`git;"darcs",`darcs;"hg",`hg;]inletaliases_kinds=["wget",`http;"curl",`http;"rsync",`rsync;]inmk_opt["k";"kind"]"KIND"(Printf.sprintf"Specify the kind of the repository to be used (%s)."(Arg.doc_alts_enummain_kinds))Arg.(some(enum(main_kinds@aliases_kinds)))Noneletjobs_flag=mk_opt["j";"jobs"]"JOBS""Set the maximal number of concurrent jobs to use. The default value is \
calculated from the number of cores. You can also set it using the \
$(b,\\$OPAMJOBS) environment variable."Arg.(somepositive_integer)Noneletname_list=arg_list"PACKAGES""List of package names."package_nameletatom_list=arg_list"PACKAGES""List of package names, with an optional version or constraint, \
e.g `pkg', `pkg.1.0' or `pkg>=0.5'."atomletatom_or_local_list=arg_list"PACKAGES""List of package names, with an optional version or constraint, e.g `pkg', \
`pkg.1.0' or `pkg>=0.5' ; or files or directory names containing package \
description, with explicit directory (e.g. `./foo.opam' or `.')"atom_or_localletatom_or_dir_list=arg_list"PACKAGES""List of package names, with an optional version or constraint, e.g `pkg', \
`pkg.1.0' or `pkg>=0.5' ; or directory names containing package \
description, with explicit directory (e.g. `./srcdir' or `.')"atom_or_dirletnonempty_atom_list=nonempty_arg_list"PACKAGES""List of package names, with an optional version or constraint, \
e.g `pkg', `pkg.1.0' or `pkg>=0.5'."atomletparam_list=arg_list"PARAMS""List of parameters."Arg.string(* Options common to all commands *)letglobal_options=letsection=global_option_sectioninletgit_version=mk_flag~section["git-version"]"Print the git version of opam, if set (i.e. you are using a development \
version), and exit."inletdebug=mk_flag~section["debug"]"Print debug message to stderr. \
This is equivalent to setting $(b,\\$OPAMDEBUG) to \"true\"."inletdebug_level=mk_opt~section["debug-level"]"LEVEL""Like $(b,--debug), but allows specifying the debug level ($(b,--debug) \
sets it to 1). Equivalent to setting $(b,\\$OPAMDEBUG) to a positive \
integer."Arg.(someint)Noneinletverbose=Arg.(value&flag_all&info~docs:section["v";"verbose"]~doc:"Be more verbose. One $(b,-v) shows all package commands, repeat to \
also display commands called internally (e.g. $(i,tar), $(i,curl), \
$(i,patch) etc.) Repeating $(i,n) times is equivalent to setting \
$(b,\\$OPAMVERBOSE) to \"$(i,n)\".")inletquiet=mk_flag~section["q";"quiet"]"Disables $(b,--verbose)."inletcolor=mk_tristate_opt~section["color"]"WHEN"(Printf.sprintf"Colorize the output. $(docv) must be %s."(Arg.doc_alts_enumwhen_enum))inletswitch=mk_opt~section["switch"]"SWITCH""Use $(docv) as the current compiler switch. \
This is equivalent to setting $(b,\\$OPAMSWITCH) to $(i,SWITCH)."Arg.(somestring)Noneinletyes=mk_flag~section["y";"yes"]"Answer yes to all yes/no questions without prompting. \
This is equivalent to setting $(b,\\$OPAMYES) to \"true\"."inletstrict=mk_flag~section["strict"]"Fail whenever an error is found in a package definition \
or a configuration file. The default is to continue silently \
if possible."inletroot=mk_opt~section["root"]"ROOT""Use $(docv) as the current root path. \
This is equivalent to setting $(b,\\$OPAMROOT) to $(i,ROOT)."Arg.(somedirname)Noneinletuse_internal_solver=mk_flag~section["no-aspcud";"use-internal-solver"]"Disable any external solver, and use the built-in one (this requires \
that opam has been compiled with a built-in solver)."inletexternal_solver=mk_opt~section["solver"]"CMD"(Printf.sprintf"Specify the CUDF solver to use for resolving package installation \
problems. This is either a predefined solver (this version of opam \
supports %s), or a custom command that should contain the variables \
%%{input}%%, %%{output}%%, %%{criteria}%%, and optionally \
%%{timeout}%%."(OpamStd.List.concat_map", "(fun(moduleS:OpamCudfSolver.S)->S.name)(OpamCudfSolver.default_solver_selection)))Arg.(somestring)Noneinletsolver_preferences=mk_opt~section["criteria"]"CRITERIA"("Specify user $(i,preferences) for dependency solving for this run. \
Overrides both $(b,\\$OPAMCRITERIA) and $(b,\\$OPAMUPGRADECRITERIA). \
For details on the supported language, and the external solvers available, see \
$(i, http://opam.ocaml.org/doc/Specifying_Solver_Preferences.html). \
A general guide to using solver preferences can be found at \
$(i, http://www.dicosmo.org/Articles/usercriteria.pdf).")Arg.(somestring)Noneinletcudf_file=mk_opt~section["cudf"]"FILENAME""Debug option: Save the CUDF requests sent to the solver to \
$(docv)-<n>.cudf."Arg.(somestring)Noneinletbest_effort=mk_flag~section["best-effort"]"Don't fail if all requested packages can't be installed: try to install \
as many as possible. Note that not all external solvers may support \
this option (recent versions of $(i,aspcud) or $(i,mccs) should)."inletsafe_mode=mk_flag~section["readonly";"safe"]"Make sure nothing will be automatically updated or rewritten. Useful \
for calling from completion scripts, for example. Will fail whenever \
such an operation is needed ; also avoids waiting for locks, skips \
interactive questions and overrides the $(b,\\$OPAMDEBUG) variable."inletjson_flag=mk_opt~section["json"]"FILENAME""Save the results of the opam run in a computer-readable file. If the \
filename contains the character `%', it will be replaced by an index \
that doesn't overwrite an existing file. Similar to setting the \
$(b,\\$OPAMJSON) variable."Arg.(somestring)Noneinletno_auto_upgrade=mk_flag~section["no-auto-upgrade"]"When configuring or updating a repository that is written for an \
earlier opam version (1.2), opam internally converts it to the current \
format. This disables this behaviour. Note that repositories should \
define their format version in a 'repo' file at their root, or they \
will be assumed to be in the older format. It is, in any case, \
preferable to upgrade the repositories manually using $(i,opam admin \
upgrade [--mirror URL]) when possible."inletworking_dir=mk_flag~section["working-dir";"w"]"Whenever updating packages that are bound to a local, \
version-controlled directory, update to the current working state of \
their source instead of the last committed state, or the ref they are \
pointing to. \
This only affects packages explicitly listed on the command-line."inletignore_pin_depends=mk_flag~section["ignore-pin-depends"]"Ignore extra pins required by packages that get pinned, either manually \
through $(i,opam pin) or through $(i,opam install DIR). This is \
equivalent to setting $(b,IGNOREPINDEPENDS=true)."inTerm.(constcreate_global_options$git_version$debug$debug_level$verbose$quiet$color$switch$yes$strict$root$external_solver$use_internal_solver$cudf_file$solver_preferences$best_effort$safe_mode$json_flag$no_auto_upgrade$working_dir$ignore_pin_depends)(* Options common to all build commands *)letbuild_option_section="PACKAGE BUILD OPTIONS"letbuild_options=letsection=build_option_sectioninletkeep_build_dir=mk_flag~section["b";"keep-build-dir"]"Keep the build directories after compiling packages. \
This is equivalent to setting $(b,\\$OPAMKEEPBUILDDIR) to \"true\"."inletreuse_build_dir=mk_flag~section["reuse-build-dir"]"Reuse existing build directories (kept by using $(b,--keep-build-dir)), \
instead of compiling from a fresh clone of the source. This can be \
faster, but also lead to failures if the build systems of the packages \
don't handle upgrades of dependencies well. This is equivalent to \
setting $(b,\\$OPAMREUSEBUILDDIR) to \"true\"."inletinplace_build=mk_flag~section["inplace-build"]"When compiling a package which has its source bound to a local \
directory, process the build and install actions directly in that \
directory, rather than in a clean copy handled by opam. This only \
affects packages that are explicitly listed on the command-line. \
This is equivalent to setting $(b,\\$OPAMINPLACEBUILD) to \"true\"."inletno_checksums=mk_flag~section["no-checksums"]"Do not verify the checksum of downloaded archives.\
This is equivalent to setting $(b,\\$OPAMNOCHECKSUMS) to \"true\"."inletreq_checksums=mk_flag~section["require-checksums"]"Reject the installation of packages that don't provide a checksum for the upstream archives. \
This is equivalent to setting $(b,\\$OPAMREQUIRECHECKSUMS) to \"true\"."inletbuild_test=mk_flag~section["t";"with-test";"build-test"]"Build and $(b,run) the package unit-tests. This only affects packages \
listed on the command-line. The $(b,--build-test) form is deprecated as \
this also affects installation. This is equivalent to setting \
$(b,\\$OPAMWITHTEST) (or the deprecated $(b,\\$OPAMBUILDTEST)) to \
\"true\"."inletbuild_doc=mk_flag~section["d";"with-doc";"build-doc"]"Build the package documentation. This only affects packages listed on \
the command-line. The $(b,--build-doc) form is deprecated as this does \
also installation. This is equivalent to setting $(b,\\$OPAMWITHDOC) \
(or the deprecated $(b,\\$OPAMBUILDDOC)) to \"true\"."inletmake=mk_opt~section["m";"make"]"MAKE""Use $(docv) as the default 'make' command. Deprecated: use $(b,opam \
config set[-global] make MAKE) instead. Has no effect if the $(i,make) \
variable is defined."Arg.(somestring)Noneinletshow=mk_flag~section["show-actions"]"Call the solver and display the actions. Don't perform any changes."inletdryrun=mk_flag~section["dry-run"]"Simulate the command, but don't actually perform any changes."inletskip_update=mk_flag~section["skip-updates"]"When running an install, upgrade or reinstall on source-pinned \
packages, they are normally updated from their origin first. This flag \
disables that behaviour and will keep them to their version in cache."inletfake=mk_flag~section["fake"]"This option registers the actions into the opam database, without \
actually performing them. \
WARNING: This option is dangerous and likely to break your opam \
environment. You probably want `--dry-run'. You've been warned."inletignore_constraints_on=mk_opt~section["ignore-constraints-on"]"PACKAGES""Forces opam to ignore version constraints on all dependencies to the \
listed packages. This can be used to test compatibility, but expect \
builds to break when using this. Note that version constraints on \
optional dependencies and conflicts are unaffected."Arg.(some(listpackage_name))None~vopt:(Some[])inletunlock_base=mk_flag~section["unlock-base"]"Allow changes to the packages set as switch base (typically, the main \
compiler). Use with caution."inletlocked=letopenArginvalue&opt~vopt:(Some"locked")(somestring)None&info~docs:section~docv:"SUFFIX"["locked"]~doc:"In commands that use opam files found from pinned sources, if a variant \
of the file with an added .$(i,SUFFIX) extension is found (e.g. \
$(b,foo.opam.locked) besides $(b,foo.opam)), that will be used instead. \
This is typically useful to offer a more specific set of dependencies \
and reproduce similar build contexts, hence the name. The $(i,opam \
lock) plugin can be used to generate such files, based on the versions \
of the dependencies currently installed on the host. This is equivalent \
to setting the $(b,\\$OPAMLOCK) environment variable. Note that this \
option doesn't generally affect already pinned packages."inTerm.(constcreate_build_options$keep_build_dir$reuse_build_dir$inplace_build$make$no_checksums$req_checksums$build_test$build_doc$show$dryrun$skip_update$fake$jobs_flag$ignore_constraints_on$unlock_base$locked)(* Option common to install commands *)letassume_built=Arg.(value&flag&info["assume-built"]~doc:"For use on locally-pinned packages: assume they have already \
been correctly built, and only run their installation \
instructions, directly from their source directory. This \
skips the build instructions and can be useful to install \
packages that are being worked on. Implies $(i,--inplace-build). \
No locally-pinned packages will be skipped.")letpackage_selection_section="PACKAGE SELECTION OPTIONS"letpackage_selection=letsection=package_selection_sectioninletdocs=sectioninletdepends_on=letdoc="List only packages that depend on one of (comma-separated) $(docv)."inArg.(value&opt_all(listatom)[]&info~doc~docs~docv:"PACKAGES"["depends-on"])inletrequired_by=letdoc="List only the dependencies of (comma-separated) $(docv)."inArg.(value&opt_all(listatom)[]&info~doc~docs~docv:"PACKAGES"["required-by"])inletconflicts_with=letdoc="List packages that have declared conflicts with at least one of the \
given list. This includes conflicts defined from the packages in the \
list, from the other package, or by a common $(b,conflict-class:) \
field."inArg.(value&opt_all(listpackage_with_version)[]&info~doc~docs~docv:"PACKAGES"["conflicts-with"])inletcoinstallable_with=letdoc="Only list packages that are compatible with all of $(docv)."inArg.(value&opt_all(listpackage_with_version)[]&info~doc~docs~docv:"PACKAGES"["coinstallable-with"])inletresolve=letdoc="Restrict to a solution to install (comma-separated) $(docv), $(i,i.e.) \
a consistent set of packages including those. This is subtly different \
from `--required-by --recursive`, which is more predictable and can't \
fail, but lists all dependencies independently without ensuring \
consistency. \
Without `--installed`, the answer is self-contained and independent of \
the current installation. With `--installed', it's computed from the \
set of currently installed packages. \
`--no-switch` further makes the solution independent from the \
currently pinned packages, architecture, and compiler version. \
The combination with `--depopts' is not supported."inArg.(value&opt_all(listatom)[]&info~doc~docs~docv:"PACKAGES"["resolve"])inletrecursive=mk_flag["recursive"]~section"With `--depends-on' and `--required-by', display all transitive \
dependencies rather than just direct dependencies."inletdepopts=mk_flag["depopts"]~section"Include optional dependencies in dependency requests."inletnobuild=mk_flag["nobuild"]~section"Exclude build dependencies (they are included by default)."inletpost=mk_flag["post"]~section"Include dependencies tagged as $(i,post)."inletdev=mk_flag["dev"]~section"Include development packages in dependencies."inletdoc_flag=mk_flag["doc";"with-doc"]~section"Include doc-only dependencies."inlettest=mk_flag["t";"test";"with-test"]~section"Include test-only dependencies."inletfield_match=mk_opt_all["field-match"]"FIELD:PATTERN"~section"Filter packages with a match for $(i,PATTERN) on the given $(i,FIELD)"Arg.(pair~sep:':'stringstring)inlethas_flag=mk_opt_all["has-flag"]"FLAG"~section("Only include packages which have the given flag set. Package flags are \
one of: "^(OpamStd.List.concat_map" "(Printf.sprintf"$(b,%s)"@*string_of_pkg_flag)all_package_flags))((funs->matchpkg_flag_of_stringswith|Pkgflag_Unknowns->`Error("Invalid package flag "^s^", must be one of "^OpamStd.List.concat_map" "string_of_pkg_flagall_package_flags)|f->`Okf),funfmtflag->Format.pp_print_stringfmt(string_of_pkg_flagflag))inlethas_tag=mk_opt_all["has-tag"]"TAG"~section"Only includes packages which have the given tag set"Arg.stringinletfilterdepends_onrequired_byconflicts_withcoinstallable_withresolverecursivedepoptsnobuildpostdevdoc_flagtestfield_matchhas_flaghas_tag=letdependency_toggles={OpamListCommand.recursive;depopts;build=notnobuild;post;test;doc=doc_flag;dev}inList.map(funflag->OpamListCommand.Flagflag)has_flag@List.map(funtag->OpamListCommand.Tagtag)has_tag@List.map(fun(field,patt)->OpamListCommand.Pattern({OpamListCommand.default_pattern_selectorwithOpamListCommand.fields=[field]},patt))field_match@List.map(fundeps->OpamListCommand.Depends_on(dependency_toggles,deps))depends_on@List.map(funrdeps->OpamListCommand.Required_by(dependency_toggles,rdeps))required_by@List.map(funpkgs->OpamListCommand.Conflicts_withpkgs)conflicts_with@List.map(fundeps->OpamListCommand.Solution(dependency_toggles,deps))resolve@List.map(funpkgs->OpamListCommand.Coinstallable_with(dependency_toggles,pkgs))coinstallable_withinTerm.(constfilter$depends_on$required_by$conflicts_with$coinstallable_with$resolve$recursive$depopts$nobuild$post$dev$doc_flag$test$field_match$has_flag$has_tag)letpackage_listing_section="OUTPUT FORMAT OPTIONS"letpackage_listing=letsection=package_listing_sectioninletall_versions=mk_flag["all-versions";"V"]~section"Normally, when multiple versions of a package match, only one is shown \
in the output (the installed one, the pinned-to one, or, failing that, \
the highest one available or the highest one). This flag disables this \
behaviour and shows all matching versions. This also changes the \
default display format to include package versions instead of just \
package names (including when --short is set). This is automatically \
turned on when a single non-pattern package name is provided on the \
command-line."inletprint_short=mk_flag["short";"s"]~section"Don't print a header, and sets the default columns to $(b,name) only. \
If you need package versions included, use $(b,--columns=package) \
instead"inletsort=mk_flag["sort";"S"]~section"Sort the packages in dependency order (i.e. an order in which they \
could be individually installed.)"inletcolumns=mk_opt["columns"]"COLUMNS"~section(Printf.sprintf"Select the columns to display among: %s.\n\
The default is $(b,name) when $(i,--short) is present \
and %s otherwise."(OpamStd.List.concat_map", "(fun(_,f)->Printf.sprintf"$(b,%s)"f)OpamListCommand.field_names)(OpamStd.List.concat_map", "(funf->Printf.sprintf"$(b,%s)"(OpamListCommand.string_of_fieldf))OpamListCommand.default_list_format))Arg.(some&opamlist_columns)Noneinletnormalise=mk_flag["normalise"]~section"Print the values of opam fields normalised"inletwrap=mk_flag["wrap"]~section"Wrap long lines, the default being to truncate when displaying on a \
terminal, or to keep as is otherwise"inletseparator=Arg.(value&optstring" "&info["separator"]~docv:"STRING"~docs:package_listing_section~doc:"Set the column-separator string")inletformatall_versionsshortsortcolumnsnormalisewrapseparator=fun~force_all_versions->letall_versions=force_all_versions||all_versionsinletcolumns=matchcolumnswith|Somec->c|None->letcols=ifshortthen[OpamListCommand.Name]elseOpamListCommand.default_list_formatinifall_versionsthenList.map(function|OpamListCommand.Name->OpamListCommand.Package|c->c)colselsecolsin{OpamListCommand.short;header=notshort;columns;all_versions;wrap=ifwrapthenSome(`Wrap"\\ ")elseSome`Truncate;separator;value_printer=ifnormalisethen`Normalisedelse`Normal;order=ifsortthen`Dependencyelse`Standard;}inTerm.(constformat$all_versions$print_short$sort$columns$normalise$wrap$separator)