OPAM-LINT(1)
πΈ OPAM-LINT(1) β the Opam Manual, bestie edition πΈ
okay so you opened the manual page for opam-lint, part of the Opam Manual, and honestly? it's giving quality control queen. Let's go. π
β¨ NAME β¨
opam-lint β checks and validates package description (opam) files. yes it's literally the vibes-check for your .opam files and it WILL tell you what's wrong π
β¨ SYNOPSIS β¨
opam lint [OPTION]β¦ [FILES]β¦
β¨ DESCRIPTION β¨
so here's the deal: you hand it an opam file, and it runs a whole bunch of quality checks on it. then it tells you what it thinks β recommendations, warnings, errors β and it prints all of that to stderr, not stdout, so don't be out here wondering why your pipe is empty, bestie ππ«Ά
β¨ ARGUMENTS β¨
FILESβ the names of the opam files you wanna check, or a directory that contains them. if you don't specify anything at all, it just uses the current directory. lowkey convenient fr fr.
β¨ OPTIONS β¨
--check-upstreamβ checks upstream, plus archive availability and checksum(s). like a lil wellness check on the source you're pointing at π--normaliseβ spits out a normalised version of the opam file to stdout. glow-up mode β¨--package=PKGβ lint the current definition of the package you name, instead of pointing at an opam file directly. no file path needed, just say the name π--recursiveβ allows recursive lookups of*.opamfiles. and yeah, see--subpathtoo, they're besties π€-s,--shortβ only prints the warning/error numbers, space-separated, if there are any. minimalism, we love her π--subpath=PATHβ the*.opamfiles get retrieved from the sub directory you give instead of from the top directory. sources are then taken from that targeted sub directory, and internally only that subdirectory is copied/fetched. you can combine it with--recursiveto get a recursive lookup on that subpath. nesting but make it intentional πͺ-W WARNS,--warnings=WARNSβ picks which warnings to show or hide.WARNSshould be a concatenation of+N,-N,@N,+N..M,-N..M,@N..M, which respectively enable, disable or enable-as-error warning or error number N, or every warning with numbers between N and M inclusive. by default all warnings are enabled β UNLESSWARNSstarts with+or@, in which case all of them get disabled except the ones you selected. so+and@are the "actually, only these" girlies π
β¨ LINT CODES β¨
here's the whole roster of codes it can throw at you. no skips, no cuts, we're listing every single one π
W20β Fieldopam-versionrefers to the patch version of opam, it should be of the formMAJOR.MINORE21β Fieldopam-versiondoesn't match the current version, validation may not be accurateE22β Some fields are present but empty; remove or fill themE23β Missing fieldmaintainerE24β Fieldmaintainerhas the old default valueW25β Missing fieldauthorsW26β No fieldinstall, but a fieldremove: install instructions probably part ofbuild. Use theinstallfield or a.installfileE28β Unknown package flags foundE29β Package dependencies or conflicts mention package variablesE31β Fieldsdependsanddepoptsrefer to the same package namesE32β Fieldocaml-version:and variableocaml-versionare deprecated, use a dependency towards theocamlpackage instead for availability, and theocaml:versionpackage variable for scriptsE33β Fieldosis deprecated, useavailableand theosvariable insteadE34β Fieldavailable:contains references to package-local variables. It should only be determined from global configuration variablesW35β Missing fieldhomepageW36β Missing fieldbug-reportsW37β Missing fielddev-repoE39β Commandmakecalled directly, use the built-in variable insteadW41β Some packages are mentioned in package scripts or features, but there is no dependency or depopt toward themE42β Thedev-repo:field doesn't use version control. You should use URLs of the form"git://","git+https://","hg+https://"β¦E43β Conjunction used inconflicts:field. Only|is allowedW44β Thepluginpackage flag is set but the package name doesn't begin withopam-E45β Unclosed variable interpolations in stringsE46β Package is flagged"conf"but has source, install or remove instructionsW47β Synopsis should start with a capital and not end with a dotW48β The fieldsbuild-test:andbuild-doc:are deprecated, and should be replaced by uses of thewith-testandwith-docfilter variables in thebuild:andinstall:fields, and by the newerrun-test:fieldW49β The following URLs don't use version control but look like version control URLsW50β Thepostflag doesn't make sense with build or optional dependenciesE51β The behaviour for negated dependency flagsbuildorpostis unspecifiedE52β Package is needlessly flagged"light-uninstall", since it has no remove instructionsE53β Mismatchingextra-files:fieldW54β External dependencies should not contain spaces nor empty stringE55β Non-normalised OS or arch string being testedE57β Synopsis must not be emptyW58β Found variable, predefined oneW59β url doesn't contain a checksumE60β Upstream check failedW61βwith-testvariable inrun-testis out of scope, it will be ignoredW62β License doesn't adhere to the SPDX standard, seehttps://spdx.org/licenses/E63βsubpathfield needs a restriction in available field:opam-version > 2.1E65β URLs must be absoluteW66β String that can't be resolved to bool in filtered package formulaE67β Checksum specified with a non archive urlW68β Missing fieldlicenseW69β Package name in variable in string interpolation contains several'+', useE70β Fieldextra-filescontains duplicated filesE71β Fieldurl.checksumcontains duplicated checksumsE72β Fieldextra-sourcescontains duplicated checksumsE73β Fieldextra-filescontains path with'..'W74β Field'pin-depends'contains packages that are neither in'depends'nor in'depopts'
ok that was a LOT of codes but you survived, icon behaviour fr fr π«Ά don't go anywhere β there's more of this page coming π
β¨ COMMON OPTIONS β¨
okay bestie these are the glow-up options that literally every opam command gets π like they're the shared accessory every outfit comes with. same for all commands, no cap.
--best-effortβ don't just give up when some packages refuse to install π€ try to install as many as humanly possible instead. heads up tho: not all external solvers support this (recent versions ofaspcudormccsshould, slay). it's giving the exact same energy as setting the$OPAMBESTEFFORTenvironment variable.--cli=MAJOR.MINOR(absent=2.6) β tells opam to use the command-line interface syntax and semantics ofMAJOR.MINOR. made for any persistent use of opam (scripts, blog posts, etc. β the stuff that lives forever online π), so any version of opam in the sameMAJORseries will behave like that specifiedMINORrelease. important tea: this flag was NOT available in opam 2.0, so if you wanna select the 2.0 CLI you gotta set theOPAMCLIenvironment variable to2.0instead of using this parameter. iykyk.--color=WHENβ colorize that output bestie πWHENmust be one ofalways,neverorauto.--confirm-level=LEVELβ the confirmation level, andLEVELmust be one ofask,no,yesorunsafe-yes. can be specified more than once! if--yesor--noare also given, the value of the last--confirm-levelis the one that counts. equivalent to setting$OPAMCONFIRMLEVEL.--criteria=CRITERIAβ set your personal preferences for dependency solving, just for this run π overrides$OPAMCRITERIA,$OPAMFIXUPCRITERIAand$OPAMUPGRADECRITERIA. for the details on the supported language and the external solvers available, seehttp://opam.ocaml.org/doc/External_solvers.html. and there's a whole general guide to using solver preferences athttp://www.dicosmo.org/Articles/usercriteria.pdfπ.--cudf=FILENAMEβ debug option π saves the CUDF requests sent to the solver intoFILENAME-<n>.cudf, where<n>is the n-th call to the solver during the opam run.--debugβ print debug messages to stderr. equivalent to setting$OPAMDEBUGto"true".--debug-level=LEVELβ like--debugbut you get to pick the debug level (--debugsets it to1). equivalent to setting$OPAMDEBUGto a positive integer.--git-versionβ print the git version of opam, if set (i.e. you're running a development version), and exit. main character dev energy π--help[=FMT](default=auto) β show this help in formatFMT. the valueFMTmust be one ofauto,pager,grofforplain. withauto, the format ispagerorplainwhenever theTERMenv var isdumbor undefined.--ignore-pin-dependsβ ignore the extra pins required by packages that get pinned, whether manually throughopam pinor throughopam install DIR. equivalent to settingIGNOREPINDEPENDS=true.--json=FILENAMEβ save the results of the opam run into a computer-readable file π€ if the filename contains the character%, it gets replaced by an index that doesn't overwrite an existing file. similar to setting the$OPAMJSONvariable.--noβ answer no to every single opam yes/no question, no prompting π« see also--confirm-level. equivalent to setting$OPAMNOto"true".--no-aspcudβ removed in 2.1. she's gone bestie, rest in peace π--no-auto-upgradeβ when configuring or updating a repository that was written for an earlier opam version (1.2), opam internally converts it to the current format. this disables that behaviour. note: repositories should define their format version in a'repo'file at their root, or they'll just be assumed to be in the older format. it's, in any case, preferable to upgrade the repositories manually usingopam admin upgrade [--mirror URL]when you can π«Ά--no-self-upgradeβ opam will replace itself with a newer binary found atOPAMROOT/opamif present. this disables that behaviour. rude of opam honestly π-q,--quietβ disables--verbose. shhh π€«--root=ROOTβ useROOTas the current root path. equivalent to setting$OPAMROOTtoROOT.--safe,--readonlyβ makes sure nothing gets automatically updated or rewritten, periodt. super useful for calling from completion scripts, for example. will fail whenever such an operation is needed ; it also avoids waiting for locks, skips interactive questions and overrides the$OPAMDEBUGvariable. equivalent to setting the environment variable$OPAMSAFE.--solver=CMDβ specify the CUDF solver to use for resolving package installation problems π§© this is either a predefined solver (this version of opam supportsbuiltin-mccs+lp(),builtin-mccs+glpk,builtin-dummy-z3-solver,builtin-0install,aspcud,mccs,aspcud-old,packup), or a custom command that should contain the variables%{input}%,%{output}%,%{criteria}%, and optionally%{timeout}%. equivalent to setting$OPAMEXTERNALSOLVER.--strictβ fail whenever an error is found in a package definition or a configuration file. the default is to just continue silently if possible π--switch=SWITCHβ useSWITCHas the current compiler switch. equivalent to setting$OPAMSWITCHtoSWITCH.--use-internal-solverβ disable any external solver and use the built-in one instead (this requires that opam has been compiled with a built-in solver, no cap). equivalent to setting$OPAMNOASPCUDor$OPAMUSEINTERNALSOLVER.-v,--verboseβ be more verbose π¬ one-vshows all package commands, repeat it to also display commands called internally (e.g.tar,curl,patchetc.). repeating it n times is equivalent to setting$OPAMVERBOSEto"n".--versionβ show version information.-w,--working-dirβ 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're pointing to. β οΈ note: as the source directory is copied as it is, if it isn't clean it may result on a opam build failure. this only affects packages explicitly listed on the command-line. it can also be set with$OPAMWORKINGDIR.-y,--yesβ answer yes to all opam yes/no questions without prompting π― see also--confirm-level. equivalent to setting$OPAMYESto"true".
π ENVIRONMENT π
okay so bestie, opam is very into environment variables, and this is the whole list π. Here's the deal on the boolean ones: set them to "0", "no", "false" or just the empty string to turn them off, and "1", "yes" or "true" to turn them on. That's the whole vibe check β¨.
OPAMALLPARENSβ wraps all the filters in parenthesis. cute and contained fr πOPAMASSUMEDEPEXTSβ see the `--assume-depexts' option.OPAMAUTOANSWERβ internal use only π like don't touch her, she's working.OPAMAUTOREMOVEβ see theremoveoption `--auto-remove'.OPAMBESTEFFORTβ see the `--best-effort' option.OPAMBESTEFFORTPREFIXCRITERIAβ sets the string that has to be prepended to the criteria when--best-effort' is set, and it's expected to maximise theopam-query' property in the solution. lowkey powerful πOPAMBUILDDOCβ Removed in 2.1. she's gone, respect the memory πͺ¦OPAMBUILDTESTβ Removed in 2.1. also gone, also missed.OPAMCLIβ see the `--cli' option.OPAMCOLORβ when it's set toalwaysornever, it gives the `--color' option a default value. πOPAMCONFIRMLEVELβ see the--confirm-leveloption. And plot twist:OPAMCONFIRMLEVELhas priority overOPAMYESandOPAMNOπOPAMCRITERIAβ this one specifies your user preferences for dependency solving. The default value depends on the solver version, so runconfig reportif you wanna know the current setting. Also see the--criteriaoption.OPAMCUDFFILEβ saves the cudf graph tofile-actions-explicit.dot. she's documenting the drama πOPAMCUDFTRIMβ controls the filtering of unrelated packages during CUDF preprocessing.OPAMCURLβ use this to pick a givencurlprogram. SeeOPAMFETCHfor more options.OPAMDEBUGβ see the--debugand--debug-leveloptions.OPAMDEBUGSECTIONSβ if set, it limits debug messages to that space-separated list of sections. Sections can optionally carry a specific debug level (likeCLIENT:2orCLIENT CUDF:2) π§, but otherwise just use--debug-level.OPAMDIGDEPTHβ defines how aggressive the lookup for conflicts is during CUDF preprocessing. she digs deep fr βοΈOPAMDOWNLOADJOBSβ sets the maximum number of simultaneous downloads. main character energy but for bandwidth πOPAMDROPWORKINGDIRβ overrides packages that were previously updated with--working-dironupdate. Without this variable set, opam would keep them unchanged unless you explicitly named them on the command-line.OPAMDRYRUNβ see the `--dry-run' option.OPAMEDITORβ sets the editor used for opam file editing, and it overrides$EDITORand$VISUAL. she doesn't ask, she tells πOPAMERRLOGLENβ sets the number of log lines printed when a sub-process fails. Set it to0to print all of them πOPAMEXTERNALSOLVERβ see the `--solver' option.OPAMFAKEβ see the `--fake' option.OPAMFETCHβ specifies how to download files: eitherwget,curl, or a custom command where the variables%{url}%,%{out}%,%{retry}%,%{compress}%and%{checksum}%will be replaced. Overrides the'download-command'value from the main config file βOPAMFIXUPCRITERIAβ same asOPAMUPGRADECRITERIA, but specific to fixup and reinstall.OPAMIGNOREAVAILABLEβ see theinstalloption `--ignore-available-on'.OPAMIGNORECONSTRAINTSβ see theinstalloption `--ignore-constraints-on'.OPAMIGNOREPINDEPENDSβ see the `--ignore-pin-depends' option.OPAMINPLACEBUILDβ see the `--inplace-build' option.OPAMJOBSβ sets the maximum number of parallel workers to run. go off, parallelism πOPAMJSONβ logs json output to the given file (use the character%to index the files).OPAMKEEPBUILDDIRβ see theinstalloption `--keep-build-dir'.OPAMKEEPLOGSβ tells opam to not remove some temporary command logs and some backups. Heads up: this skips some finalisers and may also help you get more reliable backtraces.OPAMLOCKEDβ a combination of the--locked' and--lock-suffix' options.OPAMLOGSβ sets the log directory (logdir), default is a temporary directory in/tmp.OPAMMAKECMDβ sets the systemmakecommand to use.OPAMMERGEOUTβ merges process outputs, putting stderr on stdout.OPAMNOβ answers no to any question asked; see the--noand--confirm-leveloptions.OPAMNOis ignored if eitherOPAMCONFIRMLEVELorOPAMYESis set. she gets overruled π€OPAMNOAGGREGATEβ withopam admin check, don't aggregate packages.OPAMNOASPCUDβ Deprecated. β οΈ do not use.OPAMNOAUTOUPGRADEβ disables the automatic internal upgrade of repositories in an earlier format to the current one, on'update'or'init'.OPAMNOCHECKSUMSβ enables the--no-checksumsoption when it's available.OPAMNODEPEXTSβ disables system dependencies handling, see the `--no-depexts' option.OPAMNOENVNOTICEβ Internal. πOPAMNOSELFUPGRADEβ see the `--no-self-upgrade' option.OPAMPINKINDAUTOβ sets whether version control systems should be detected when pinning to a local path. Enabled by default since 1.3.0 β¨OPAMPRECISETRACKINGβ fine grain tracking of directories. very detail-oriented of her πOPAMPREPROβ set this tofalseto disable CUDF preprocessing. Less efficient, but it might help with debugging a solver issue.OPAMREPOSITORYTARRINGβ internally store all non-vcs repositories astar.gzfiles (by default, http repositories are stored as archive). This can be much faster on filesystems that don't cope well with scanning large trees. All operations are done in-memory, with no I/O for scanning the repository π₯OPAMREQUIRECHECKSUMSβ enables the--require-checksums' option when available (e.g. foropam install`).OPAMRETRIESβ sets the number of tries before failing downloads. she's persistent, okay? πͺOPAMREUSEBUILDDIRβ see the `--reuse-build-dir' option.OPAMROOTβ see the--root' option. This is automatically set byopam env --root=DIR --set-root`.OPAMROOTISOKβ don't complain when running as root. she's chill about it πΈOPAMSAFEβ see the `--safe' option.OPAMSHOWβ see the `--show' option.OPAMSKIPUPDATEβ see the `--skip-updates' option.OPAMSKIPVERSIONCHECKSβ bypasses some version checks. β οΈ Unsafe, for compatibility testing only.OPAMSOLVERALLOWSUBOPTIMALβ (defaulttrue) allows some solvers to still return a solution when they reach timeout; while the solution remains assured to be consistent, there's no guarantee in this case that it fits the expected optimisation criteria. Iftrue, opam will continue with a warning; iffalse, a timeout is an error. Currently only the builtin-z3 backend handles this degraded case.OPAMSOLVERTIMEOUTβ change the time allowance of the solver. Default is60.0, set it to0for unlimited. Note that not all solvers may support this option πOPAMSOLVERTOLERANCEβ changes the tolerance towards the solver choosing an unoptimized solution (i.e. it might pull outdated packages). Typical values range from0.0(best solution known to the solver) to1.0(unoptimized solution). Default is0.0. This one is useful in case the solver can't find a solution in a reasonable time (see$OPAMSOLVERTIMEOUT). Note that not all solvers may support this option either π«OPAMSTATSβ Removed in 2.4. gone bestie πOPAMSTATUSLINEβ display a dynamic status line showing what's currently going on on the terminal. (one ofalways,neverorauto)OPAMSTRICTβ fails on inconsistencies (file reading, switch import, etc.). no chill, only correctness πOPAMSWITCHβ see the--switch' option. Automatically set byopam env --switch=SWITCH --set-switch`.OPAMUNLOCKBASEβ see theinstalloption `--unlock-base'.OPAMUPGRADECRITERIAβ specifies your user preferences for dependency solving when performing an upgrade. It overridesOPAMCRITERIAin upgrades if both are set. Also see the--criteriaoption.OPAMUSEINTERNALSOLVERβ see the `--use-internal-solver' option.OPAMUSEOPENSSLβ Removed in 2.2. rest in peace πͺ¦OPAMUTF8β use UTF8 characters in output (one ofalways,neverorauto). By default it'sauto, which is determined from the locale π¦OPAMUTF8MSGSβ use extended UTF8 characters (camels πͺ) in opam messages. ImpliesOPAMUTF8. This is set by default on macOS only.OPAMVALIDATIONHOOKβ if set, uses the%{hook}%command to validate an opam repository update.OPAMVERBOSEβ see the `--verbose' option.OPAMVERBOSEONβ see the--verbose-onoption.OPAMVERSIONLAGPOWERβ do not use. β οΈ that's it, that's the whole instruction.OPAMWITHDEVSETUPβ see theinstalloption `--with-dev-setup'.OPAMWITHDOCβ see theinstalloption `--with-doc'.OPAMWITHTESTβ see theinstalloption--with-test.OPAMWORKINGDIRβ see the `--working-dir' option.OPAMYESβ see the--yes' and--confirm-level' options.OPAMYEShas priority overOPAMNOand is ignored ifOPAMCONFIRMLEVELis set πOPAMVAR_varβ overrides the contents of the variable var when substituting the%{var}%strings inopamfiles. (yes, that_is doing a lot of work here, she's iconic like that β¨)OPAMVAR_package_varβ overrides the contents of the variable package:var when substituting the%{package:var}%strings inopamfiles.
β CLI VERSION β
okay so here's the thing: all scripts and programmatic invocations of opam should use --cli, so they work seamlessly with future versions of the opam client. no cap, this is the move π«Ά. And bonus: blog posts or other documentation benefit too, because it stops the info from going stale. petty protection π
Although opam only supports roots (~/.opam/) for the current version, it does provide backwards compatibility for its command-line interface. bestie is generous like that π
Since CLI version support was only added in opam 2.1, use OPAMCLI to select 2.0 support (since opam 2.0 will just ignore it), and use --cli=2.1 for 2.1 (or later) versions β because an environment variable controlling the parsing of syntax is brittle π« . To this end, opam displays a warning if OPAMCLI specifies a valid version other than 2.0, and also if --cli=2.0 is specified.
The command-line version is selected by using the --cli option or the OPAMCLI environment variable. --cli may be specified more than once, and in that case the last instance takes precedence π. OPAMCLI is only inspected if --cli is not given.
π EXIT STATUS π
Okay bestie, real talk: when opam dips out, it leaves you a little number so you know why. β¨
Wait, one exception first π¨execdoes its own thing. It returns127if the command was not found or couldn't be executed, and the command's own exit value otherwise.
Here's the whole mood ring of status codes:
0β Success, ortruefor boolean queries. π1βFalse. Returned when a boolean return value is expected, e.g. when running with--check, or for queries likeopam lint.2β Bad command-line arguments, or command-line arguments pointing to an invalid context (e.g. file not following the expected format).5β Not found. You requested something (package, version, repository, etc.) that couldn't be found.10β Aborted. The operation required confirmation, which wasn't given. π15β Could not acquire the locks required for the operation.20β There is no solution to the user request. This can be caused by asking to install two incompatible packages, for example.30β Error in package definition, or other metadata files. Using--strictraises this error more often.31β 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.40β Sync error. Could not fetch some remotes from the network. This can be a partial error.50β Configuration error. Opam or system configuration doesn't allow operation, and needs fixing.60β 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.99β Internal error. Something went wrong, likely due to a bug in opam itself. π130β User interrupt.SIGINTwas received, generally due to the user pressing Ctrl+C.
And then there's the extra little trio, for when a command exits with the exit code of some other program it ran:
0β on success.123β on indiscriminate errors reported on standard error.124β on command line parsing errors.125β on unexpected internal errors (bugs).
π FURTHER DOCUMENTATION π
Need more? See https://opam.ocaml.org/doc. That's the spot. π«Ά
π AUTHORS π
These are the actual legends who built this thing. Show some respect:
- David Allsopp
<david@tarides.com> - Vincent Bernardoff
<vb@luminar.eu.org> - Raja Boujbel
<raja.boujbel@ocamlpro.com> - Kate Deplaix
<kit-ty-kate@exn.st> - Roberto Di Cosmo
<roberto@dicosmo.org> - Thomas Gazagnaire
<thomas@gazagnaire.org> - Louis Gesbert
<louis.gesbert@ocamlpro.com> - Fabrice Le Fessant
<Fabrice.Le_fessant@inria.fr> - Anil Madhavapeddy
<anil@recoil.org> - Guillem Rieu
<guillem.rieu@ocamlpro.com> - Ralf Treinen
<ralf.treinen@pps.jussieu.fr> - Frederic Tuong
<tuong@users.gforge.inria.fr>
πΈ SEE ALSO πΈ
Go read that one too, bestie, it's the main character. π
π BUGS π
Found something cursed? Check bug reports at https://github.com/ocaml/opam/issues. No cap, that's where the fix happens.
And that's a wrap on the whole page, babe!! π This one's from Opam 2.6.1 and it's the OPAM-LINT(1) page, dated right alongside that release. You read the entire thing, every flag, every code, every name β iconic behavior, honestly. β¨π Now go lint something and make it slay. ππ¦
π¦ where this page comes from
- arch rolling: opam 2.6.1-1 Β· LGPL-2.1-only
- fedora 44: opam 2.6.1-1.fc44 Β· LGPL-2.1-only WITH OCaml-LGPL-linking-exception
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms