├── .ocp-indent ├── src ├── debug.ocp ├── admin.META.in ├── format.META.in ├── core.META.in ├── repository.META.in ├── state.META.in ├── opam.ocp ├── solver.META.in ├── client.META.in ├── solver │ ├── solver.ocp │ ├── opamSolverConfig.mli │ └── opamActionGraph.mli ├── repository │ ├── repository.ocp │ ├── opamGit.mli │ ├── opamDarcs.mli │ ├── opamHg.mli │ ├── opamHTTP.mli │ ├── opamLocal.mli │ ├── opamRepositoryConfig.mli │ ├── opamDownload.mli │ ├── opamRepositoryPath.ml │ ├── opamRepositoryPath.mli │ ├── opamVCS.mli │ └── opamRepository.mli ├── format │ ├── format.ocp │ ├── opamRepositoryName.ml │ ├── opamLineLexer.mli │ ├── opamRepositoryName.mli │ ├── opamFormatConfig.mli │ ├── opamSwitch.mli │ ├── opamFormatConfig.ml │ ├── opamSwitch.ml │ ├── opamLineLexer.mll │ ├── opamVariable.mli │ └── opamTypesBase.mli ├── core │ ├── core.ocp │ ├── opamCompat.ml.4.03 │ ├── opamCompat.mli.4.03 │ ├── opamSHA.mli │ ├── opamCompat.ml.4.02 │ ├── opamJson.mli │ ├── opamCompat.mli.4.02 │ ├── opamCompat.ml.4.01 │ ├── opamHash.mli │ ├── opamVersion.mli │ ├── opamCompat.mli.4.01 │ ├── opamDirTrack.mli │ ├── opamVersionCompare.mli │ ├── opamVersion.ml.in │ ├── opamCoreConfig.mli │ ├── opamUrl.mli │ ├── opamCoreConfig.ml │ ├── opamJson.ml │ └── opamHash.ml ├── state │ ├── state.ocp │ ├── opamScript.mli │ ├── opamFormatUpgrade.mli │ ├── opamPinned.mli │ ├── opamGlobalState.mli │ ├── opamStateConfig.mli │ ├── opamFileTools.mli │ ├── opamRepositoryState.mli │ ├── opamPinned.ml │ ├── opamPackageVar.mli │ └── opamSwitchAction.mli ├── tools │ ├── tools.ocp │ ├── opam_admin_top.mli │ └── opam_check.ml └── client │ ├── opamAdminRepoUpgrade.mli │ ├── opamAdminCommand.mli │ ├── opamGitVersion.mli │ ├── client.ocp │ ├── opamInitDefaults.mli │ ├── opamInitDefaults.ml │ ├── opamMain.mli │ ├── opamPinCommand.mli │ ├── opamRepositoryCommand.mli │ ├── opamConfigCommand.mli │ ├── opamAction.mli │ └── opamSwitchCommand.mli ├── tests ├── packages │ ├── P1-1 │ │ ├── README │ │ ├── p1.ml │ │ ├── build.sh │ │ ├── P1.config.in │ │ └── P1.install │ ├── P1-2 │ │ ├── README │ │ ├── p1.ml │ │ ├── P1.install │ │ ├── build.sh │ │ └── P1.config.in │ ├── P2 │ │ ├── p2.ml │ │ ├── P2.install │ │ ├── config.in │ │ ├── P2.config.in │ │ ├── README │ │ └── build.sh │ ├── P3 │ │ ├── README │ │ ├── p3.ml │ │ ├── p3_bar.ml │ │ ├── P3.config.in │ │ ├── build.sh │ │ ├── P3.install │ │ └── myocamlbuild.ml │ ├── P5 │ │ ├── p5.ml │ │ ├── README │ │ └── build.sh │ ├── P4 │ │ ├── README │ │ ├── P4.install │ │ ├── _tags │ │ ├── p4.ml │ │ └── build.sh │ ├── P1-0 │ │ ├── p1.ml │ │ ├── P1.install │ │ └── P1.config.in │ ├── ocaml │ │ ├── ocaml.20 │ │ │ ├── opam │ │ │ └── files │ │ │ │ └── ocaml.config │ │ ├── ocaml.10+a+b │ │ │ ├── opam │ │ │ └── files │ │ │ │ └── ocaml.config │ │ └── ocaml.system │ │ │ ├── opam │ │ │ └── files │ │ │ └── gen.sh │ ├── P4-3.opam │ ├── P4-1.opam │ ├── P4-2.opam │ ├── P2.opam │ ├── P3.opam │ ├── P1-0.opam │ ├── P1-2.opam │ ├── P5.opam │ └── P1-1.opam ├── test-TEST.sh ├── results │ ├── install-P1 │ ├── install-opt │ ├── reinstall-P2 │ ├── install-remove-P1 │ ├── install-P1-P2-P3-P4 │ ├── install-upgrade-P2 │ └── README.tests ├── README.unittest └── init-repo.sh ├── doc ├── dev-manual │ ├── htmlmacros.hva │ ├── dev-manual.pdf │ ├── Makefile │ └── dev-manual.css ├── pages │ ├── index.menu │ └── About.md ├── release │ └── readme.md └── Makefile ├── .merlin ├── shell ├── dot_ocamlinit ├── wrap-build.sh ├── crunch.ml ├── wrap-install.sh ├── wrap-remove.sh ├── bootstrap-ocaml.sh ├── md5check.ml ├── opam_prompt.sh ├── get-git-id.ml └── opam_installer.sh ├── AUTHORS ├── CONTRIBUTING.md ├── .ocamlinit ├── admin-scripts ├── Makefile ├── add-build-deps.ml ├── add-github-dev.ml ├── split_install.ml ├── cudf-debug.ml ├── lint.ml ├── depopts_to_conflicts.ml └── extract_mini_repository.sh ├── opam-repository.opam ├── opam-format.opam ├── opam-solver.opam ├── opam-client.opam ├── Makefile.config.in ├── opam-state.opam ├── .travis.yml ├── opam-core.opam ├── appveyor.yml ├── .gitignore ├── opam-devel.opam └── .travis-ci.sh /.ocp-indent: -------------------------------------------------------------------------------- 1 | normal 2 | strict_else=auto 3 | -------------------------------------------------------------------------------- /src/debug.ocp: -------------------------------------------------------------------------------- 1 | comp += [ "-g"] 2 | link += [ "-g"] 3 | -------------------------------------------------------------------------------- /tests/packages/P1-1/README: -------------------------------------------------------------------------------- 1 | A very useful package 2 | -------------------------------------------------------------------------------- /tests/packages/P1-2/README: -------------------------------------------------------------------------------- 1 | A very useful package 2 | -------------------------------------------------------------------------------- /tests/packages/P2/p2.ml: -------------------------------------------------------------------------------- 1 | let g () = 2 | P1.x () 3 | -------------------------------------------------------------------------------- /tests/packages/P3/README: -------------------------------------------------------------------------------- 1 | Testing version names 2 | -------------------------------------------------------------------------------- /tests/packages/P5/p5.ml: -------------------------------------------------------------------------------- 1 | let g () = 2 | P1.x () 3 | -------------------------------------------------------------------------------- /tests/packages/P4/README: -------------------------------------------------------------------------------- 1 | Testing transitive closure 2 | -------------------------------------------------------------------------------- /tests/packages/P5/README: -------------------------------------------------------------------------------- 1 | Testing optional dependencies 2 | -------------------------------------------------------------------------------- /doc/dev-manual/htmlmacros.hva: -------------------------------------------------------------------------------- 1 | \loadcssfile{./dev-manual.css} 2 | -------------------------------------------------------------------------------- /tests/packages/P3/p3.ml: -------------------------------------------------------------------------------- 1 | let z () = 2 | try P1.x () 3 | with _ -> 0 4 | -------------------------------------------------------------------------------- /tests/packages/P4/P4.install: -------------------------------------------------------------------------------- 1 | bin: [ 2 | "p4.foo" { "p4" } 3 | "p4.foo" 4 | ] -------------------------------------------------------------------------------- /tests/packages/P1-0/p1.ml: -------------------------------------------------------------------------------- 1 | let x () = 2 | try Random.int 10 3 | with _ -> 0 4 | -------------------------------------------------------------------------------- /tests/packages/P1-1/p1.ml: -------------------------------------------------------------------------------- 1 | let x () = 2 | try Random.int 10 3 | with _ -> 0 4 | -------------------------------------------------------------------------------- /tests/packages/P4/_tags: -------------------------------------------------------------------------------- 1 | <*.{byte,native}>: use_p2, use_p3 2 | <*.ml>: use_p2, use_p3 -------------------------------------------------------------------------------- /tests/packages/P1-2/p1.ml: -------------------------------------------------------------------------------- 1 | let x () = 2 | failwith "the new version is not very good" 3 | -------------------------------------------------------------------------------- /.merlin: -------------------------------------------------------------------------------- 1 | PKG ocamlgraph cmdliner dose3 cudf re jsonm 2 | 3 | S src/* 4 | B _obuild/* 5 | B src/* 6 | -------------------------------------------------------------------------------- /tests/packages/P3/p3_bar.ml: -------------------------------------------------------------------------------- 1 | let f () = 2 | Printf.printf "foo\n%!" 3 | 4 | let _ = 5 | P3.z () 6 | -------------------------------------------------------------------------------- /tests/packages/P2/P2.install: -------------------------------------------------------------------------------- 1 | lib: [ 2 | "p2.cma" 3 | "p2.cmxa" 4 | "p2.a" 5 | "p2.cmi" 6 | ] 7 | -------------------------------------------------------------------------------- /doc/dev-manual/dev-manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbuenzli/opam/master/doc/dev-manual/dev-manual.pdf -------------------------------------------------------------------------------- /tests/packages/P2/config.in: -------------------------------------------------------------------------------- 1 | Foo is %{P1:FOO}% 2 | 3 | Foo also contains a variable with %{P1:l}%. Funny, isn't it? 4 | -------------------------------------------------------------------------------- /shell/dot_ocamlinit: -------------------------------------------------------------------------------- 1 | let () = 2 | try Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH") 3 | with Not_found -> () 4 | ;; -------------------------------------------------------------------------------- /tests/packages/P1-0/P1.install: -------------------------------------------------------------------------------- 1 | lib: [ 2 | "_build/p1.cmi" 3 | "_build/p1.cma" 4 | "_build/p1.cmxa" 5 | "_build/p1.a" 6 | ] 7 | -------------------------------------------------------------------------------- /tests/packages/P1-2/P1.install: -------------------------------------------------------------------------------- 1 | lib: [ 2 | "_build/p1.cma" 3 | "_build/p1.cmxa" 4 | "_build/p1.a" 5 | "_build/p1.cmi" 6 | ] 7 | -------------------------------------------------------------------------------- /tests/packages/ocaml/ocaml.20/opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.3" 2 | maintainer: "contact@ocamlpro.com" 3 | flags: compiler 4 | setenv: TEST = "1" 5 | -------------------------------------------------------------------------------- /tests/packages/P4-3.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1" 2 | name: "P4" 3 | version: "3" 4 | maintainer: "contact@ocamlpro.com" 5 | depends: [ "P2" "P3" ] 6 | build: [ "./build.sh" ] 7 | -------------------------------------------------------------------------------- /tests/packages/P4-1.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1" 2 | name: "P4" 3 | version: "1" 4 | maintainer: "contact@ocamlpro.com" 5 | depends: ["ocaml" "P2" "P3"] 6 | build: [ "./build.sh" ] 7 | -------------------------------------------------------------------------------- /tests/packages/ocaml/ocaml.10+a+b/opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.3" 2 | maintainer: "contact@ocamlpro.com" 3 | # depends: ["P1" "P2" "P3" "P4"] 4 | flags: compiler 5 | setenv: TEST = "1" 6 | -------------------------------------------------------------------------------- /tests/packages/P2/P2.config.in: -------------------------------------------------------------------------------- 1 | asmcomp: "-I %{lib}%/P2" 2 | bytecomp: "-I %{lib}%/P2" 3 | asmlink: "-I %{lib}%/P2 p2.cmxa" 4 | bytelink: "-I %{lib}%/P2 p2.cma" 5 | requires: "p1" 6 | -------------------------------------------------------------------------------- /tests/packages/P1-1/build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -eu 2 | 3 | if [ -n "${P1:-}" ]; then 4 | echo "P1 ('$P1') should not be set yet" >&2 5 | exit 12 6 | fi 7 | 8 | ocamlbuild p1.cma p1.cmxa 9 | -------------------------------------------------------------------------------- /tests/packages/P1-2/build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -eu 2 | 3 | if [ -n "${P1:-}" ]; then 4 | echo "P1 ('$P1') should not be set yet" >&2 5 | exit 12 6 | fi 7 | 8 | ocamlbuild p1.cma p1.cmxa 9 | -------------------------------------------------------------------------------- /tests/packages/P2/README: -------------------------------------------------------------------------------- 1 | An other very useful package 2 | 3 | The description can go on multiple lines. The first line is the package synopsis, 4 | and the rest is the package description. 5 | -------------------------------------------------------------------------------- /tests/test-TEST.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -f $1 ]; then 4 | . $1 5 | fi 6 | 7 | if [ x${TEST} != x$2 ]; then 8 | echo "Error: TEST=${TEST} instead of $2" 9 | exit 2 10 | fi 11 | -------------------------------------------------------------------------------- /tests/packages/P3/P3.config.in: -------------------------------------------------------------------------------- 1 | asmcomp : "-I %{lib}%/P3" 2 | bytecomp: "-I %{lib}%/P3" 3 | asmlink : "-I %{lib}%/P3 p3.cmxa p3_bar.cmxa" 4 | bytelink: "-I %{lib}%/P3 p3.cma p3_bar.cma" 5 | requires: "p1" 6 | -------------------------------------------------------------------------------- /src/admin.META.in: -------------------------------------------------------------------------------- 1 | version = "@PACKAGE_VERSION@" 2 | description = "OCaml Package Manager client and CLI library" 3 | archive(byte) = "opam-admin.cma" 4 | archive(native) = "opam-admin.cmxa" 5 | requires = "opam-client" 6 | -------------------------------------------------------------------------------- /tests/packages/P1-2/P1.config.in: -------------------------------------------------------------------------------- 1 | asmcomp: "-I %{lib}%/P1" 2 | bytecomp: "-I %{lib}%/P1" 3 | asmlink: "-I %{lib}%/P1 p1.cmxa" 4 | bytelink: "-I %{lib}%/P1 p1.cma" 5 | LOCAL: "local" 6 | l: "L" 7 | FOO: "foo" 8 | bar: true -------------------------------------------------------------------------------- /tests/packages/P1-1/P1.config.in: -------------------------------------------------------------------------------- 1 | asmcomp: "-I %{lib}%/P1" 2 | bytecomp: "-I %{lib}%/P1" 3 | asmlink: "-I %{lib}%/P1 p1.cmxa" 4 | bytelink: "-I %{lib}%/P1 p1.cma" 5 | LOCAL: "local" 6 | l: "L" 7 | FOO: "foo" 8 | bar: true 9 | -------------------------------------------------------------------------------- /tests/packages/ocaml/ocaml.20/files/ocaml.config: -------------------------------------------------------------------------------- 1 | opam-version: "1.3~dev4" 2 | variables { 3 | compiler: "20" 4 | native: true 5 | native-tools: true 6 | native-dynlink: true 7 | stubsdir: "%{lib}%/stublibs" 8 | } 9 | -------------------------------------------------------------------------------- /tests/packages/P4-2.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1" 2 | name: "P4" 3 | version: "2" 4 | maintainer: "contact@ocamlpro.com" 5 | depends: [ 6 | "P1" { <= "1" } 7 | "P2" 8 | "P3" 9 | ] 10 | build: [ "./build.sh" ] 11 | -------------------------------------------------------------------------------- /tests/packages/P4/p4.ml: -------------------------------------------------------------------------------- 1 | let f = 2 | try P3_bar.f (); P1.x () 3 | with _ -> P3.z () 4 | 5 | let () = 6 | let t = 7 | try Sys.getenv "TEST" 8 | with _ -> "" in 9 | Printf.printf "TEST=%s\n%!" t 10 | -------------------------------------------------------------------------------- /tests/packages/ocaml/ocaml.10+a+b/files/ocaml.config: -------------------------------------------------------------------------------- 1 | opam-version: "1.3~dev4" 2 | variables { 3 | compiler: "10+a+b" 4 | native: true 5 | native-tools: true 6 | native-dynlink: true 7 | stubsdir: "%{lib}%/stublibs" 8 | } 9 | -------------------------------------------------------------------------------- /tests/packages/P2.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1" 2 | name: "P2" 3 | version: "1" 4 | maintainer: "contact@ocamlpro.com" 5 | substs: [ "config" "P2.config" ] 6 | depends: ["ocaml" "P1"] 7 | libraries: [ "p2" ] 8 | build: [ "./build.sh" ] 9 | -------------------------------------------------------------------------------- /shell/wrap-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | exec unshare -Umnr /bin/sh -se "$@" <= "4" && ocaml_minor_version >= "02" ) then { 5 | comp += [ "-safe-string" ] 6 | link += [ "-safe-string" ] 7 | } 8 | 9 | build_libs = [] 10 | -------------------------------------------------------------------------------- /src/solver.META.in: -------------------------------------------------------------------------------- 1 | version = "@PACKAGE_VERSION@" 2 | description = "OCaml Package Manager solver interaction library" 3 | archive(byte) = "opam-solver.cma" 4 | archive(native) = "opam-solver.cmxa" 5 | requires = "opam-core, opam-format, cudf, dose3.common, dose3.algo" 6 | -------------------------------------------------------------------------------- /tests/packages/P1-1/P1.install: -------------------------------------------------------------------------------- 1 | lib: [ 2 | "_build/p1.cmi" 3 | "_build/p1.cma" 4 | "_build/p1.cmxa" 5 | "_build/p1.a" 6 | "?_build/this_file_will_not_exits_but_that's_ok" 7 | ] 8 | share: [ "build.sh" ] 9 | doc: [ 10 | "_build/p1.cmi" { "foo/bar/index.html" } 11 | ] -------------------------------------------------------------------------------- /tests/packages/P3/P3.install: -------------------------------------------------------------------------------- 1 | lib: [ 2 | (* p3 *) 3 | "_build/p3.cma" 4 | "_build/p3.cmxa" 5 | "_build/p3.a" 6 | "_build/p3.cmi" 7 | 8 | (* p3_bar *) 9 | "_build/p3_bar.cma" 10 | "_build/p3_bar.cmxa" 11 | "_build/p3_bar.a" 12 | "_build/p3_bar.cmi" 13 | ] 14 | -------------------------------------------------------------------------------- /tests/packages/P1-2.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1" 2 | name: "P1" 3 | version: "2" 4 | depends: [ "ocaml" {<= "10" | = "system"} ] 5 | maintainer: "contact@ocamlpro.com" 6 | substs: [ "P1.config" ] 7 | libraries: [ "p1" ] 8 | build: [ "./build.sh" ] 9 | setenv: [P1 = "version2"] 10 | -------------------------------------------------------------------------------- /src/client.META.in: -------------------------------------------------------------------------------- 1 | version = "@PACKAGE_VERSION@" 2 | description = "OCaml Package Manager client and CLI library" 3 | archive(byte) = "opam-client.cma" 4 | archive(native) = "opam-client.cmxa" 5 | requires = "opam-core, opam-format, opam-solver, opam-repository, opam-state, cmdliner, re.glob" 6 | -------------------------------------------------------------------------------- /tests/packages/P1-0/P1.config.in: -------------------------------------------------------------------------------- 1 | opam-version: "1.3" 2 | variables { 3 | asmcomp: "-I %{lib}%/P1" 4 | bytecomp: "-I %{lib}%/P1" 5 | asmlink: "-I %{lib}%/P1 p1.cmxa" 6 | bytelink: "-I %{lib}%/P1 p1.cma" 7 | LOCAL: "local" 8 | l: "L" 9 | FOO: "foo" 10 | bar: true 11 | } 12 | -------------------------------------------------------------------------------- /tests/packages/P5/build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -eu 2 | 3 | FLAGS="-I `${OPAM} config var P1:lib`" 4 | 5 | echo "Bytecode Compilation" 6 | ocamlc ${FLAGS} -a p5.ml -o p5.cma 7 | 8 | if which ocamlopt >/dev/null 2>&1; then 9 | echo "Native Compilation" 10 | ocamlopt ${FLAGS} -a p5.ml -o p5.cmxa 11 | fi 12 | -------------------------------------------------------------------------------- /doc/dev-manual/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all 2 | all: dev-manual.pdf 3 | html: dev-manual.html 4 | 5 | %.pdf: %.tex 6 | pdflatex $* 7 | pdflatex $* 8 | 9 | %.html: %.tex 10 | hevea -fix htmlmacros.hva $< 11 | 12 | %.txt: %.html 13 | links -dump $< > $@ 14 | 15 | clean: 16 | rm -f *~ *.log *toc *.out *.bbl *.blg *aux *.html 17 | -------------------------------------------------------------------------------- /tests/results/install-P1-P2-P3-P4: -------------------------------------------------------------------------------- 1 | Available packages for system: 2 | P1 1 A very useful package 3 | P2 1 An other very useful package 4 | P3 1~weird-version.test Testing version names 5 | P4 1 Testing transitive closure 6 | P5 -- Testing optional dependencies 7 | -------------------------------------------------------------------------------- /tests/results/install-upgrade-P2: -------------------------------------------------------------------------------- 1 | Available packages for system: 2 | P1 1 A very useful package 3 | P2 1 An other very useful package 4 | P3 1~weird-version.test Testing version names 5 | P4 1 Testing transitive closure 6 | P5 -- Testing optional dependencies 7 | -------------------------------------------------------------------------------- /tests/packages/P2/build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -eu 2 | 3 | OFLAGS="`${OPAM} config var P1:asmcomp`" 4 | CFLAGS="`${OPAM} config var P1:bytecomp`" 5 | 6 | echo "Bytecode Compilation" 7 | ocamlc ${CFLAGS} -a p2.ml -o p2.cma 8 | 9 | if which ocamlopt >/dev/null 2>&1; then 10 | echo "Native Compilation" 11 | ocamlopt ${OFLAGS} -a p2.ml -o p2.cmxa 12 | fi 13 | 14 | -------------------------------------------------------------------------------- /tests/packages/P5.opam: -------------------------------------------------------------------------------- 1 | (* API version *) 2 | opam-version: "1" 3 | name: "P5" 4 | version: "1" 5 | maintainer: "contact@ocamlpro.com" 6 | depends: ["ocaml" "P1"] 7 | depopts: [ "P2" ] 8 | build: [ [ "./build.sh" ] ] 9 | install: [ [ "mkdir" "-p" "%{lib}%/p5" ] 10 | [ "touch" "%{lib}%/p5/p2_present" ] {P2:installed} 11 | [ "touch" "%{lib}%/p5/p2_absent" ] {!P2:installed} ] 12 | remove: [ "rm" "-rf" "%{lib}%/p5" ] 13 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Thomas Gazagnaire 2 | Anil Madhavapeddy 3 | Fabrice Le Fessant 4 | Frederic Tuong 5 | Louis Gesbert 6 | Guillem Rieu 7 | Vincent Bernardoff 8 | Roberto Di Cosmo 9 | Ralf Treinen 10 | -------------------------------------------------------------------------------- /doc/pages/index.menu: -------------------------------------------------------------------------------- 1 | # Contains the documentation menu with the following syntax: 2 | # without extension -> A menu title 3 | # .md -> A markdown page 4 | # empty -> A menu divider 5 | #source: https://github.com/ocaml/opam/tree/master/doc/pages 6 | opam 2.0 DOCUMENTATION (work in progress) 7 | 8 | Install.md 9 | Usage.md 10 | 11 | FAQ.md 12 | Tricks.md 13 | Packaging.md 14 | Specifying_Solver_Preferences.md 15 | 16 | Manual.md 17 | -------------------------------------------------------------------------------- /src/solver/solver.ocp: -------------------------------------------------------------------------------- 1 | if build_libs = [] || 2 | %mem( string = "opam-solver" 3 | strings = build_libs ) 4 | then { 5 | begin library "opam-solver" 6 | 7 | files = [ 8 | "opamSolverConfig.ml" 9 | "opamActionGraph.ml" 10 | "opamCudf.ml" 11 | "opamHeuristic.ml" 12 | "opamSolver.ml" 13 | ] 14 | 15 | requires = [ 16 | "dose3.common" 17 | "dose3.algo" 18 | "opam-core" 19 | "opam-format" 20 | ] 21 | 22 | end 23 | } 24 | -------------------------------------------------------------------------------- /shell/crunch.ml: -------------------------------------------------------------------------------- 1 | let add_stdin buf = 2 | try 3 | while true do 4 | let line = input_line stdin in 5 | Buffer.add_string buf line; 6 | Buffer.add_char buf '\n' 7 | done 8 | with End_of_file -> 9 | () 10 | 11 | let () = 12 | let name = Sys.argv.(1) in 13 | let buf = Buffer.create 1024 in 14 | add_stdin buf; 15 | let contents = Buffer.contents buf in 16 | Printf.printf "let %s =\n\"%s\"\n\n" 17 | name 18 | (String.escaped contents) 19 | -------------------------------------------------------------------------------- /shell/wrap-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | exec unshare -Umnr /bin/sh -se "$@" < List.iter add_dep deps 19 | | _ -> () 20 | -------------------------------------------------------------------------------- /shell/bootstrap-ocaml.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ex 2 | 3 | V=ocaml-4.02.1 4 | URL=http://caml.inria.fr/pub/distrib/ocaml-4.02/${V}.tar.gz 5 | mkdir -p bootstrap 6 | cd bootstrap 7 | if [ ! -e ${V}.tar.gz ]; then 8 | if command -v curl > /dev/null; then 9 | curl -OL ${URL} 10 | elif command -v wget > /dev/null; then 11 | wget ${URL} 12 | else 13 | echo "This script requires curl or wget" 14 | exit 1 15 | fi 16 | fi 17 | tar -zxvf ${V}.tar.gz 18 | cd ${V} 19 | ./configure -prefix "`pwd`/../ocaml" 20 | make world opt 21 | make install 22 | -------------------------------------------------------------------------------- /shell/md5check.ml: -------------------------------------------------------------------------------- 1 | let file, md5 = 2 | if Array.length Sys.argv <> 3 then ( 3 | Printf.eprintf "usage: ocaml %s \n" Sys.argv.(0); 4 | exit 1 5 | ) else 6 | Sys.argv.(1), Sys.argv.(2) 7 | 8 | let md5_of_file = 9 | Digest.to_hex (Digest.file file) 10 | 11 | let () = 12 | if md5 <> md5_of_file then ( 13 | Printf.eprintf 14 | "MD5 for %s differ:\n\ 15 | \ expected: %s\n\ 16 | \ actual: %s\n" 17 | file md5 md5_of_file; 18 | Sys.remove file; 19 | exit 1 20 | ) else 21 | Printf.printf "%s has the expected MD5.\n" file 22 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Bug reports and feature requests for **the opam tool** should be reported on: 2 | 3 | * http://github.com/ocaml/opam/issues 4 | (please include the output of `opam config report` whenever possible) 5 | 6 | **Packaging issues** or requests for a new package should be reported on: 7 | 8 | * http://github.com/ocaml/opam-repository/issues 9 | 10 | **General queries** can be addressed at: 11 | 12 | * http://lists.ocaml.org/listinfo/platform 13 | (for the both the tool & packages) 14 | 15 | * http://lists.ocaml.org/listinfo/opam-devel 16 | (for the tool and its evolution) 17 | -------------------------------------------------------------------------------- /src/repository/repository.ocp: -------------------------------------------------------------------------------- 1 | if build_libs = [] || 2 | %mem( string = "opam-repository" 3 | strings = build_libs ) 4 | then { 5 | begin library "opam-repository" 6 | 7 | files = [ 8 | "opamRepositoryConfig.ml" 9 | "opamDownload.ml" 10 | "opamRepositoryBackend.ml" 11 | "opamRepositoryPath.ml" 12 | "opamHTTP.ml" 13 | "opamLocal.ml" 14 | "opamVCS.ml" 15 | "opamGit.ml" 16 | "opamDarcs.ml" 17 | "opamHg.ml" 18 | "opamRepository.ml" 19 | ] 20 | 21 | requires = [ 22 | "opam-core" 23 | "opam-format" 24 | ] 25 | 26 | end 27 | } 28 | -------------------------------------------------------------------------------- /.ocamlinit: -------------------------------------------------------------------------------- 1 | #use "topfind";; 2 | #require "opam-client";; 3 | 4 | OpamClientConfig.opam_init ();; 5 | 6 | let gt = OpamGlobalState.load `Lock_none;; 7 | OpamConsole.msg "Opam global state for %s loaded in 'gt'\n" 8 | OpamStateConfig.(OpamFilename.Dir.to_string !r.root_dir);; 9 | let rt = OpamRepositoryState.load `Lock_none gt;; 10 | OpamConsole.msg "Opam repository state loaded in 'rt'\n";; 11 | let st = OpamSwitchState.load `Lock_none gt rt (OpamStateConfig.get_switch ());; 12 | OpamConsole.msg "Opam switch state of '%s' loaded in 'st'\n" 13 | (OpamSwitch.to_string (OpamStateConfig.get_switch ()));; 14 | -------------------------------------------------------------------------------- /src/format/format.ocp: -------------------------------------------------------------------------------- 1 | if build_libs = [] || 2 | %mem( string = "opam-format" 3 | strings = build_libs ) 4 | then { 5 | begin library "opam-format" 6 | sort = false 7 | files = [ 8 | "opamFormatConfig.ml" 9 | "opamSwitch.ml" 10 | "opamPackage.ml" 11 | "opamFormula.ml" 12 | "opamVariable.ml" 13 | "opamRepositoryName.ml" 14 | "opamTypes.mli" 15 | "opamTypesBase.ml" 16 | "opamPp.ml" 17 | "opamFormat.ml" 18 | "opamLineLexer.mll" 19 | "opamFilter.ml" 20 | "opamFile.ml" 21 | ] 22 | 23 | requires = [ 24 | "opam-file-format" 25 | "opam-core" 26 | ] 27 | 28 | end 29 | } 30 | -------------------------------------------------------------------------------- /admin-scripts/Makefile: -------------------------------------------------------------------------------- 1 | DEPS = core format repository 2 | 3 | INCLUDE = $(patsubst %,-I ../src/%,$(DEPS)) -I ../src/tools 4 | 5 | LIBS = $(patsubst %,../src/opam-%.cma,$(DEPS)) 6 | 7 | %: %.ml 8 | sed 's/^#.*//' $< >$*-tmp.ml 9 | ocamlfind ocamlc -package unix,re.glob,ocamlgraph -linkpkg $(INCLUDE) $(LIBS) ../src/tools/opam_admin_top.ml $*-tmp.ml -o $@ 10 | rm $*-tmp.ml 11 | 12 | 1_2_to_2_0: compilers-to-packages 13 | cp $< $@ 14 | 15 | couverture: couverture.ml 16 | sed 's/^#.*//' $< >couverture-tmp.ml 17 | ocamlfind ocamlopt -package re.glob,opam-lib.state -linkpkg ../src/tools/opam_admin_top.ml couverture-tmp.ml -o $@ 18 | rm couverture-tmp.ml 19 | -------------------------------------------------------------------------------- /src/core/core.ocp: -------------------------------------------------------------------------------- 1 | if build_libs = [] || 2 | %mem( string = "opam-core" 3 | strings = build_libs ) 4 | then { 5 | begin library "opam-core" 6 | sort = false 7 | files = [ 8 | "opamCompat.ml" 9 | "opamJson.ml" 10 | "opamSHA.ml" 11 | "opamCoreConfig.ml" 12 | "opamStd.ml" 13 | "opamConsole.ml" 14 | "opamVersionCompare.ml" 15 | "opamVersion.ml" 16 | "opamProcess.ml" 17 | "opamParallel.ml" 18 | "opamSystem.ml" 19 | "opamHash.ml" 20 | "opamFilename.ml" 21 | "opamDirTrack.ml" 22 | "opamUrl.ml" 23 | ] 24 | 25 | requires = [ 26 | "unix" 27 | "bigarray" 28 | "ocamlgraph" 29 | "re" 30 | "re.str" 31 | "jsonm" 32 | ] 33 | 34 | end 35 | } 36 | -------------------------------------------------------------------------------- /src/state/state.ocp: -------------------------------------------------------------------------------- 1 | if build_libs = [] || 2 | %mem( string = "opam-state" 3 | strings = build_libs ) 4 | then { 5 | comp += [ "-w" "-48" ] 6 | 7 | begin library "opam-state" 8 | 9 | files = [ 10 | "opamPath.ml" 11 | "opamStateConfig.ml" 12 | "opamScript.ml" 13 | "opamStateTypes.mli" 14 | "opamPackageVar.ml" 15 | "opamFileTools.ml" 16 | "opamEnv.ml" 17 | "opamFormatUpgrade.ml" 18 | "opamGlobalState.ml" 19 | "opamRepositoryState.ml" 20 | "opamPinned.ml" 21 | "opamSwitchState.ml" 22 | "opamSwitchAction.ml" 23 | "opamUpdate.ml" 24 | ] 25 | 26 | requires = [ 27 | "opam-core" 28 | "opam-repository" 29 | "opam-format" 30 | ] 31 | 32 | end 33 | } 34 | -------------------------------------------------------------------------------- /tests/packages/P4/build.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh -e 2 | 3 | if [ $OPAM_PACKAGE_VERSION -eq 2 ]; then 4 | if [ "X${P1:-}" != "Xversion1" ]; then 5 | echo "P1 not set to version1 while P1.1 should be installed" >&2 6 | exit 12 7 | fi 8 | else 9 | if [ -z "X${P1:-}" ]; then 10 | echo "P1 not set while P1 should be installed" >&2 11 | exit 12 12 | fi 13 | fi 14 | 15 | echo "Building P4 with ${OPAM}" 16 | LIBDIR="`${OPAM} config var lib`" 17 | COMP="-I ${LIBDIR}/P1 -I ${LIBDIR}/P2 -I ${LIBDIR}/P3" 18 | LINK="p1.cmxa p2.cmxa p3.cmxa p3_bar.cmxa" 19 | 20 | OCAMLC=ocamlc 21 | if which ocamlopt >/dev/null 2>&1; then OCAMLC=ocamlopt; fi 22 | 23 | $OCAMLC ${COMP} ${LINK} p4.ml -o p4.foo 24 | 25 | echo "TEST=${TEST}" 26 | -------------------------------------------------------------------------------- /tests/results/README.tests: -------------------------------------------------------------------------------- 1 | 2 | # All tests are performed in a clean repository 3 | 4 | Initial state of the repository 5 | 6 | Available packages for system: 7 | P1 -- A very useful package 8 | P2 -- An other very useful package 9 | P3 -- Testing version names 10 | P4 -- Testing transitive closure 11 | P5 -- Testing optional dependencies 12 | 13 | 14 | * install-P1 15 | install P1 16 | 17 | * install-P1-P2-P3-P4 18 | install P1, P2, P3, P4 19 | 20 | * install-remove-P1 21 | install P1 and then remove P1 22 | 23 | * install-upgrade-P2 24 | install P4 and then upgrade P2 25 | 26 | * reinstall-P2 27 | install P2 and the re-install P2 28 | 29 | * install_opt 30 | install P5 , install P2, remove P5, remove P2, remove P1 31 | -------------------------------------------------------------------------------- /tests/README.unittest: -------------------------------------------------------------------------------- 1 | 2 | # to create a new unit test 3 | 4 | * clean the test repository : 5 | 6 | ./init-repo.sh -c 7 | 8 | * init the test repository : 9 | 10 | ./init-repo.sh -i 11 | 12 | * load a inital scenario (this command can be invoked multiple times): 13 | 14 | ./init-repo.sh -s 1 15 | ./init-repo.sh -s 2 16 | 17 | * install/remove/upgrade : 18 | 19 | OPAM_ROOT=/tmp/OPAM.ROOT PATH=/tmp/OPAM.BIN:$PATH opam --yes --root /tmp/OPAM.ROOT install P4 20 | 21 | * crearte a new expected result file in as 22 | 23 | OPAM_ROOT=/tmp/OPAM.ROOT PATH=/tmp/OPAM.BIN:$PATH \ 24 | opam --yes --root /tmp/OPAM.ROOT list > results/new-expected-result 25 | 26 | * Make sure that the result correct ! 27 | 28 | * Add a new test case in the file tests.py 29 | -------------------------------------------------------------------------------- /shell/opam_prompt.sh: -------------------------------------------------------------------------------- 1 | # This script allows you to see the active opam switch in your prompt. It 2 | # should be portable across all shells in common use. 3 | # 4 | # To enable, change your PS1 to call _opam_ps1 using command substitution. For 5 | # example, in bash: 6 | # 7 | # PS1="$(__opam_ps1 "(%s)")\u@\h:\w\$ " 8 | # 9 | 10 | __opam_ps1() 11 | { 12 | local exit=$? 13 | local printf_format='(%s)' 14 | 15 | case "$#" in 16 | 0|1) printf_format="${1:-$printf_format}" 17 | ;; 18 | *) return $exit 19 | ;; 20 | esac 21 | 22 | local switch_name="$(opam switch show --safe 2>/dev/null)" 23 | if [ -z "$switch_name" ]; then 24 | return $exit 25 | fi 26 | printf -- "$printf_format" "$switch_name" 27 | return $exit 28 | } 29 | -------------------------------------------------------------------------------- /tests/packages/ocaml/ocaml.system/files/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ue 2 | 3 | if ! OCAMLC=$(which ocamlc); then 4 | echo "No OCaml compiler was found on the system" >&2 5 | exit 2 6 | fi 7 | 8 | LIBDIR=$("$OCAMLC" -where) 9 | STUBLIBS=$(cat "$LIBDIR/ld.conf" | tr '\n' ':') 10 | 11 | echo "Using ocaml compiler found at $OCAMLC with base lib at $LIBDIR" 12 | 13 | bool() { 14 | if "$@"; then echo "true"; else echo "false"; fi 15 | } 16 | 17 | cat >ocaml.config < string list list 15 | -------------------------------------------------------------------------------- /opam-repository.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | version: "2.0.0~beta" 3 | maintainer: "opam-devel@lists.ocaml.org" 4 | authors: [ 5 | "Thomas Gazagnaire " 6 | "Anil Madhavapeddy " 7 | "Fabrice Le Fessant " 8 | "Frederic Tuong " 9 | "Louis Gesbert " 10 | "Guillem Rieu " 11 | "Vincent Bernardoff " 12 | "Roberto Di Cosmo " 13 | ] 14 | homepage: "https://opam.ocaml.org/" 15 | bug-reports: "https://github.com/ocaml/opam/issues" 16 | dev-repo: "https://github.com/ocaml/opam.git" 17 | build: [ 18 | ["./configure" "--disable-checks" "--prefix" prefix] 19 | [make name] 20 | [make "%{name}%.install"] 21 | ] 22 | depends: [ 23 | "opam-core" {= "2.0.0~beta"} 24 | "opam-format" {= "2.0.0~beta"} 25 | ] 26 | available: ocaml-version >= "4.01.0" 27 | -------------------------------------------------------------------------------- /src/repository/opamGit.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Git repository backend (based on OpamVCS) *) 13 | 14 | module VCS: OpamVCS.VCS 15 | 16 | module B: OpamRepositoryBackend.S 17 | -------------------------------------------------------------------------------- /admin-scripts/add-build-deps.ml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env opam-admin.top 2 | 3 | #directory "+../opam-lib";; 4 | open Opam_admin_top;; 5 | 6 | (* Add the "build" dependency flag to all ocamlfind depends *) 7 | 8 | let to_build = List.map OpamPackage.Name.of_string ["ocamlfind"] 9 | 10 | let addbuild (pkg, (flags, cstr) as atom) = 11 | if List.mem pkg to_build && not (List.mem OpamTypes.Depflag_Build flags) then 12 | OpamFormula.Atom (pkg, (OpamTypes.Depflag_Build::flags, cstr)) 13 | else 14 | OpamFormula.Atom atom 15 | ;; 16 | 17 | iter_packages ~opam:(fun _ opam0 -> 18 | let open OpamFile.OPAM in 19 | let opam = opam0 in 20 | let opam = with_depends opam @@ OpamFormula.map addbuild @@ depends opam in 21 | let opam = with_depopts opam @@ OpamFormula.map addbuild @@ depopts opam in 22 | let opam = if opam <> opam0 23 | then with_opam_version opam @@ OpamVersion.of_string "1.2" 24 | else opam 25 | in 26 | opam) 27 | () 28 | -------------------------------------------------------------------------------- /opam-format.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | version: "2.0.0~beta" 3 | maintainer: "opam-devel@lists.ocaml.org" 4 | authors: [ 5 | "Thomas Gazagnaire " 6 | "Anil Madhavapeddy " 7 | "Fabrice Le Fessant " 8 | "Frederic Tuong " 9 | "Louis Gesbert " 10 | "Guillem Rieu " 11 | "Vincent Bernardoff " 12 | "Roberto Di Cosmo " 13 | ] 14 | homepage: "https://opam.ocaml.org/" 15 | bug-reports: "https://github.com/ocaml/opam/issues" 16 | dev-repo: "https://github.com/ocaml/opam.git" 17 | build: [ 18 | ["./configure" "--disable-checks" "--prefix" prefix] 19 | [make name] 20 | [make "%{name}%.install"] 21 | ] 22 | depends: [ 23 | "opam-core" {= "2.0.0~beta"} 24 | "opam-file-format" {>= "2.0.0~beta"} 25 | ] 26 | available: ocaml-version >= "4.01.0" 27 | -------------------------------------------------------------------------------- /src/client/opamAdminRepoUpgrade.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2017 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | val clear_cache: unit -> unit 12 | 13 | val upgradeto_version: OpamVersion.t 14 | 15 | val do_upgrade: OpamTypes.dirname -> unit 16 | 17 | val do_upgrade_mirror: OpamTypes.dirname -> OpamUrl.t -> unit 18 | -------------------------------------------------------------------------------- /src/core/opamCompat.mli.4.03: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Compatibility layer (Bytes, etc.) for different OCaml versions *) 12 | 13 | module Bytes = Bytes 14 | module Buffer = Buffer 15 | module Filename = Filename 16 | module String = String 17 | module Char = Char 18 | -------------------------------------------------------------------------------- /src/repository/opamDarcs.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Darcs repository backend (based on OpamVCS) *) 13 | 14 | module VCS: OpamVCS.VCS 15 | 16 | module B: OpamRepositoryBackend.S 17 | -------------------------------------------------------------------------------- /src/repository/opamHg.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Mercurial repository backend (based on OpamVCS) *) 13 | 14 | module VCS: OpamVCS.VCS 15 | 16 | module B: OpamRepositoryBackend.S 17 | -------------------------------------------------------------------------------- /src/format/opamRepositoryName.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** The type for repository names *) 13 | 14 | include OpamStd.ABSTRACT 15 | 16 | (** Default repository name *) 17 | val default: t 18 | -------------------------------------------------------------------------------- /src/state/opamScript.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** (generated) Shell config scripts as OCaml strings *) 13 | 14 | val complete : string 15 | val complete_zsh : string 16 | val prompt : string 17 | -------------------------------------------------------------------------------- /opam-solver.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | version: "2.0.0~beta" 3 | maintainer: "opam-devel@lists.ocaml.org" 4 | authors: [ 5 | "Thomas Gazagnaire " 6 | "Anil Madhavapeddy " 7 | "Fabrice Le Fessant " 8 | "Frederic Tuong " 9 | "Louis Gesbert " 10 | "Guillem Rieu " 11 | "Vincent Bernardoff " 12 | "Roberto Di Cosmo " 13 | ] 14 | homepage: "https://opam.ocaml.org/" 15 | bug-reports: "https://github.com/ocaml/opam/issues" 16 | dev-repo: "https://github.com/ocaml/opam.git" 17 | build: [ 18 | ["./configure" "--disable-checks" "--prefix" prefix] 19 | [make name] 20 | [make "%{name}%.install"] 21 | ] 22 | depends: [ 23 | "opam-core" {= "2.0.0~beta"} 24 | "opam-format" {= "2.0.0~beta"} 25 | "dose3" {>= "5"} 26 | ] 27 | available: ocaml-version >= "4.01.0" 28 | -------------------------------------------------------------------------------- /opam-client.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | version: "2.0.0~beta" 3 | maintainer: "opam-devel@lists.ocaml.org" 4 | authors: [ 5 | "Thomas Gazagnaire " 6 | "Anil Madhavapeddy " 7 | "Fabrice Le Fessant " 8 | "Frederic Tuong " 9 | "Louis Gesbert " 10 | "Guillem Rieu " 11 | "Vincent Bernardoff " 12 | "Roberto Di Cosmo " 13 | ] 14 | homepage: "https://opam.ocaml.org/" 15 | bug-reports: "https://github.com/ocaml/opam/issues" 16 | dev-repo: "https://github.com/ocaml/opam.git" 17 | build: [ 18 | ["./configure" "--disable-checks" "--prefix" prefix] 19 | [make name] 20 | [make "%{name}%.install"] 21 | ] 22 | depends: [ 23 | "opam-state" {= "2.0.0~beta"} 24 | "opam-solver" {= "2.0.0~beta"} 25 | "cmdliner" {>= "0.9.8"} 26 | ] 27 | available: ocaml-version >= "4.01.0" 28 | -------------------------------------------------------------------------------- /Makefile.config.in: -------------------------------------------------------------------------------- 1 | SHELL=bash 2 | 3 | OCAMLVERSION = @OCAMLVERSION@ 4 | OCAML_4_03 = @ocaml_4_03@ 5 | OCAML_4_02 = @ocaml_4_02@ 6 | datarootdir = @datarootdir@ 7 | prefix = @prefix@ 8 | mandir = @mandir@ 9 | version = @PACKAGE_VERSION@ 10 | FETCH = @fetch@ 11 | HAS_PACKAGES = @hasalldeps@ 12 | USE_BYTE := $(if $(subst no,,@OCAMLOPT@),,true) 13 | LIBEXT := $(if $(USE_BYTE),.cma,.cmxa) 14 | 15 | PACKS = @OCAML_PKG_unix@ @OCAML_PKG_bigarray@ @OCAML_PKG_extlib@ @OCAML_PKG_re@ @OCAML_PKG_re_glob@ @OCAML_PKG_cmdliner@ @OCAML_PKG_ocamlgraph@ @OCAML_PKG_cudf@ @OCAML_PKG_dose3_common@ @OCAML_PKG_dose3_algo@ @OCAML_PKG_jsonm@ @OCAML_PKG_opam_file_format@ 16 | 17 | OCAMLFIND = @OCAMLFIND@ 18 | OCAML = @OCAML@ 19 | OCAMLC = @OCAMLC@ 20 | OCAMLOPT = @OCAMLOPT@ 21 | OCAMLDEP = @OCAMLDEP@ 22 | OCAMLLEX = @OCAMLLEX@ 23 | OCAMLYACC = @OCAMLYACC@ 24 | OCAMLMKLIB = @OCAMLMKLIB@ 25 | OCAMLDOC = @OCAMLDOC@ 26 | 27 | export OCAMLVERSION OCAMLFIND OCAML OCAMLC OCAMLOPT OCAMLDEP OCAMLLEX OCAMLYACC OCAMLMKLIB OCAMLDOC 28 | -------------------------------------------------------------------------------- /opam-state.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | version: "2.0.0~beta" 3 | maintainer: "opam-devel@lists.ocaml.org" 4 | authors: [ 5 | "Thomas Gazagnaire " 6 | "Anil Madhavapeddy " 7 | "Fabrice Le Fessant " 8 | "Frederic Tuong " 9 | "Louis Gesbert " 10 | "Guillem Rieu " 11 | "Vincent Bernardoff " 12 | "Roberto Di Cosmo " 13 | ] 14 | homepage: "https://opam.ocaml.org/" 15 | bug-reports: "https://github.com/ocaml/opam/issues" 16 | dev-repo: "https://github.com/ocaml/opam.git" 17 | build: [ 18 | ["./configure" "--disable-checks" "--prefix" prefix] 19 | [make name] 20 | [make "%{name}%.install"] 21 | ] 22 | depends: [ 23 | "opam-core" {= "2.0.0~beta"} 24 | "opam-format" {= "2.0.0~beta"} 25 | "opam-repository" {= "2.0.0~beta"} 26 | ] 27 | available: ocaml-version >= "4.01.0" 28 | -------------------------------------------------------------------------------- /src/repository/opamHTTP.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Main HTTP repository backend, based on Curl *) 13 | 14 | module B: OpamRepositoryBackend.S 15 | 16 | open OpamTypes 17 | 18 | val make_index_tar_gz: dirname -> unit 19 | -------------------------------------------------------------------------------- /src/client/opamAdminCommand.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2017 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | val admin_command_doc: string 13 | 14 | val admin_subcommands: (unit Cmdliner.Term.t * Cmdliner.Term.info) list 15 | 16 | val default_subcommand: unit Cmdliner.Term.t * Cmdliner.Term.info 17 | -------------------------------------------------------------------------------- /src/core/opamSHA.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Pure OCaml implementation of SHA256/512 hashing functions. Functions take a 12 | filename and return the hash as an hex string. *) 13 | 14 | val sha256: string -> string 15 | 16 | val sha512: string -> string 17 | 18 | val hash: [< `SHA256 | `SHA512 ] -> string -> string 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: false 3 | 4 | addons: 5 | apt: 6 | packages: 7 | - aspcud 8 | 9 | before_install: 10 | - bash -ex .travis-ci.sh prepare 11 | install: 12 | - bash -ex .travis-ci.sh install 13 | 14 | cache: 15 | directories: 16 | - $HOME/.opam.bootstrap 17 | 18 | script: 19 | - bash -ex .travis-ci.sh build 20 | 21 | matrix: 22 | include: 23 | - os: linux 24 | env: OCAML_VERSION=4.03.0 OPAM_TEST=1 EXTERNAL_SOLVER= 25 | - os: linux 26 | env: OCAML_VERSION=4.03.0 OPAM_TEST=1 EXTERNAL_SOLVER=aspcud 27 | - os: linux 28 | env: OCAML_VERSION=4.03.0 OPAM_TEST= 29 | - os: linux 30 | env: OCAML_VERSION=4.02.3 OPAM_TEST= 31 | - os: linux 32 | env: OCAML_VERSION=4.01.0 OPAM_TEST= 33 | - os: osx 34 | env: OCAML_VERSION=4.03.0 OPAM_TEST=1 EXTERNAL_SOLVER= 35 | - os: osx 36 | env: OCAML_VERSION=4.03.0 OPAM_TEST= 37 | notifications: 38 | email: 39 | - opam-commits@lists.ocaml.org 40 | irc: 41 | - "chat.freenode.net#opam" 42 | -------------------------------------------------------------------------------- /src/client/opamGitVersion.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2014 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** (generated) Current git version of OPAM *) 13 | 14 | (** This is defined only at the client lib level to avoid triggering 15 | full recompilations all the time *) 16 | 17 | val version: string option 18 | -------------------------------------------------------------------------------- /opam-core.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | version: "2.0.0~beta" 3 | maintainer: "opam-devel@lists.ocaml.org" 4 | authors: [ 5 | "Thomas Gazagnaire " 6 | "Anil Madhavapeddy " 7 | "Fabrice Le Fessant " 8 | "Frederic Tuong " 9 | "Louis Gesbert " 10 | "Guillem Rieu " 11 | "Vincent Bernardoff " 12 | "Roberto Di Cosmo " 13 | ] 14 | homepage: "https://opam.ocaml.org/" 15 | bug-reports: "https://github.com/ocaml/opam/issues" 16 | dev-repo: "https://github.com/ocaml/opam.git" 17 | build: [ 18 | ["./configure" "--disable-checks" "--prefix" prefix] 19 | [make name] 20 | [make "%{name}%.install"] 21 | ] 22 | depends: [ 23 | "ocamlfind" {build} 24 | "ocp-build" {build & >= "1.99.7"} 25 | "base-unix" 26 | "base-bigarray" 27 | "ocamlgraph" 28 | "re" {>= "1.5.0"} 29 | "jsonm" 30 | ] 31 | available: ocaml-version >= "4.01.0" 32 | -------------------------------------------------------------------------------- /src/client/client.ocp: -------------------------------------------------------------------------------- 1 | if build_libs = [] || 2 | %mem( string = "opam-client" 3 | strings = build_libs ) 4 | then { 5 | 6 | comp += [ "-w" "-48" ] 7 | 8 | begin library "opam-client" 9 | 10 | files = [ 11 | "opamClientConfig.ml" 12 | "opamAction.ml" 13 | "opamSolution.ml" 14 | "opamSwitchCommand.ml" 15 | "opamConfigCommand.ml" 16 | "opamAdminRepoUpgrade.ml" 17 | "opamRepositoryCommand.ml" 18 | "opamPinCommand.ml" 19 | "opamListCommand.ml" 20 | "opamInitDefaults.ml" 21 | "opamClient.ml" 22 | "opamGitVersion.ml" 23 | "opamArg.ml" 24 | "opamAdminCommand.ml" 25 | ] 26 | 27 | requires = [ 28 | "opam-state" 29 | "opam-solver" 30 | "re.glob" 31 | "cmdliner" 32 | ] 33 | 34 | end 35 | } 36 | 37 | if build_libs = [] || 38 | %mem( string = "opam-devel" 39 | strings = build_libs ) 40 | then { 41 | 42 | begin program "opam" 43 | 44 | files = [ 45 | "opamMain.ml" 46 | ] 47 | requires = [ 48 | "opam-client" 49 | ] 50 | 51 | end 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/core/opamCompat.ml.4.02: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | module Bytes = Bytes 12 | module Buffer = Buffer 13 | module Filename = Filename 14 | 15 | module String = struct 16 | include String 17 | let lowercase_ascii = lowercase 18 | let capitalize_ascii = capitalize 19 | end 20 | 21 | module Char = struct 22 | include Char 23 | let lowercase_ascii = lowercase 24 | end 25 | -------------------------------------------------------------------------------- /admin-scripts/add-github-dev.ml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env opam-admin.top 2 | #directory "+../opam-lib";; 3 | open Opam_admin_top;; 4 | 5 | #use "topfind";; 6 | #require "re";; 7 | 8 | let github_re = 9 | Re.compile (Re_perl.re "([^/]*github.com/.*)/archive/.*");; 10 | 11 | iter_packages_gen @@ fun nv ~prefix:_ ~opam ~descr:_ ~url ~dot_install:_ -> 12 | let opam = 13 | if OpamFile.OPAM.dev_repo opam <> None then opam else 14 | match url with 15 | | None -> opam 16 | | Some u -> 17 | let url = OpamFile.URL.url u in 18 | if url.OpamUrl.backend = `http && 19 | Re.execp github_re url.OpamUrl.path then 20 | let substrings = Re.exec github_re url.OpamUrl.path in 21 | let dev_url = 22 | { OpamUrl.transport = "git"; 23 | path = Re.get substrings 1; 24 | hash = None; 25 | backend = `git } 26 | in 27 | let opam = OpamFile.OPAM.with_dev_repo opam dev_url in 28 | OpamFile.OPAM.with_opam_version opam (OpamVersion.of_string "1.2") 29 | else opam 30 | in 31 | opam, `Keep, `Keep, `Keep 32 | -------------------------------------------------------------------------------- /src/core/opamJson.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Wrapper on Jsonm; only needed for some debug options *) 12 | 13 | type t = 14 | [ `Null | `Bool of bool | `Float of float| `String of string 15 | | `A of t list | `O of (string * t) list ] 16 | 17 | val to_string: t -> string 18 | 19 | val of_string: string -> t 20 | 21 | val append: string -> t -> unit 22 | 23 | val flush: out_channel -> unit 24 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | platform: 2 | - x86 3 | 4 | environment: 5 | global: 6 | CYG_ROOT: C:/cygwin 7 | CYG_CACHE: C:/cygwin/var/cache/setup 8 | CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/ 9 | matrix: 10 | - 11 | CYG_ARCH: x86 12 | 13 | init: 14 | - 'echo System architecture: %PLATFORM%' 15 | 16 | install: 17 | - 'appveyor DownloadFile http://cygwin.com/setup-%CYG_ARCH%.exe -FileName setup.exe' 18 | - 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P make -P git -P gcc-core -P ocaml -P ocaml-camlp4 -P ocaml-compiler-libs -P libncurses-devel -P unzip >NUL' 19 | - 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P libmpfr-devel -P patch -P flexdll >NUL' 20 | - '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin"' 21 | 22 | build_script: 23 | - '%CYG_ROOT%/bin/bash -lc "cd \"$OLDPWD\" && env DJDIR="workaround" ./configure && make lib-ext && make && make install"' 24 | - '%CYG_ROOT%/bin/bash -lc "opam init -y -a"' 25 | - '%CYG_ROOT%/bin/bash -lc "opam config env"' 26 | - '%CYG_ROOT%/bin/bash -lc "opam install -y -v ocamlfind"' 27 | -------------------------------------------------------------------------------- /src/core/opamCompat.mli.4.02: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2014 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Compatibility layer (Bytes, etc.) for different OCaml versions *) 12 | 13 | module Bytes = Bytes 14 | module Buffer = Buffer 15 | module Filename = Filename 16 | 17 | module String : sig 18 | include module type of String 19 | val lowercase_ascii : string -> string 20 | val capitalize_ascii : string -> string 21 | end 22 | 23 | module Char : sig 24 | include module type of Char 25 | val lowercase_ascii: char -> char 26 | end 27 | 28 | -------------------------------------------------------------------------------- /src/repository/opamLocal.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Rsync repository backend, for local or ssh sources *) 13 | 14 | module B: OpamRepositoryBackend.S 15 | 16 | open OpamTypes 17 | 18 | val rsync_dirs: ?args:string list -> ?exclude_vcdirs:bool -> 19 | OpamUrl.t -> OpamFilename.Dir.t -> 20 | OpamFilename.Dir.t download OpamProcess.job 21 | val rsync_file: ?args:string list -> 22 | OpamUrl.t -> OpamFilename.t -> 23 | OpamFilename.t download OpamProcess.job 24 | -------------------------------------------------------------------------------- /doc/release/readme.md: -------------------------------------------------------------------------------- 1 | ## Steps to follow for each release 2 | 3 | * Update version (and copyright year) in `configure.ac`, `shell/opam_installer.sh` 4 | * Run `make configure` to regenerate `./configure` 5 | * Run `make tests`, `opam-rt` (with and without aspcud) -- now checked by travis 6 | * Run `make doc` to re-generate the API documetation 7 | 8 | -- 9 | 10 | * update the CHANGELOG 11 | * tag the release (git tag -a 1.2.1; git push origin 1.2.1) 12 | * create a release on github based on your tag (https://github.com/ocaml/opam/releases/new) 13 | 14 | -- 15 | 16 | * Generate an inclusive source tarball (and the binary for your current arch while you're at it): 17 | ``` 18 | ./shell/release.sh full-archive binary publish -n git-name:git-token 19 | ``` 20 | * Check that it's been properly uploaded on https://github.com/ocaml/opam/releases 21 | * Ask people on other archs (and with write access to opam) to run 22 | ``` 23 | wget https://raw.github.com/ocaml/opam/master/shell/release.sh && \ 24 | bash -ue ./release.sh -t $VERSION 25 | ``` 26 | 27 | -- 28 | 29 | * Add some news about the release on the platform blog 30 | * Update the installation instructions in doc/pages 31 | * Update the opam-lib, opamfu, opam2web opam packages 32 | * Announce ! (platform-list, caml-list) 33 | -------------------------------------------------------------------------------- /shell/get-git-id.ml: -------------------------------------------------------------------------------- 1 | let file = 2 | if Array.length Sys.argv <> 2 then ( 3 | Printf.eprintf "usage: ocaml %s \n" Sys.argv.(0); 4 | exit 1 5 | ) else 6 | Sys.argv.(1) 7 | 8 | let read file = 9 | if Sys.file_exists file then 10 | let ic = open_in_bin file in 11 | Some (input_line ic) 12 | else 13 | None 14 | 15 | let write file contents = 16 | let write () = 17 | let oc = open_out file in 18 | output_string oc contents; 19 | output_char oc '\n'; 20 | close_out oc in 21 | match read file with 22 | | None -> write () 23 | | Some actual -> if actual <> contents then write () 24 | 25 | let (/) = Filename.concat 26 | 27 | let git file = ".git" / file 28 | 29 | let () = 30 | let version_none () = 31 | write file "let version = None" in 32 | match read (git "HEAD") with 33 | | None -> version_none () 34 | | Some s -> 35 | let reference = 36 | try (* look for "ref: refs/heads/..." *) 37 | let c = String.rindex s ' ' in 38 | let namedref = String.sub s (c+1) (String.length s -c-1) in 39 | read (git namedref) 40 | with Not_found -> (* detached state, .git/HEAD contains sha1 *) 41 | Some s in 42 | match reference with 43 | | None -> version_none () 44 | | Some sha1 -> write file (Printf.sprintf "let version = Some %S" sha1) 45 | -------------------------------------------------------------------------------- /src/client/opamInitDefaults.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** This module defines a few defaults, used at 'opam init', that bind opam to 12 | its default OCaml repository at https://opam.ocaml.org. All can be overriden 13 | through the init command flags or an init config file. *) 14 | 15 | open OpamTypes 16 | 17 | (** Url of the default Opam repository *) 18 | val repository_url: url 19 | 20 | val default_compiler: formula 21 | 22 | val eval_variables: (OpamVariable.t * string list * string) list 23 | 24 | (** Default initial configuration file for use by [opam init] if nothing is 25 | supplied. *) 26 | val init_config: OpamFile.InitConfig.t 27 | -------------------------------------------------------------------------------- /tests/packages/P1-1.opam: -------------------------------------------------------------------------------- 1 | (* API version *) 2 | opam-version: "1" 3 | 4 | name: "P1" 5 | 6 | # Test 7 | # Toto 8 | 9 | (* Version are arbitrary strings *) 10 | version: "1" 11 | 12 | maintainer: "contact@ocamlpro.com" 13 | 14 | (* The command to run *) 15 | build: [ 16 | ["./build.sh"] # HAHAH 17 | ["this" "should" "never" "run"] {ocaml:version > "z100"} 18 | [make "this" ocaml:version "also"] {os = "NO"} 19 | ["echo" "HAHA!"] {ocaml:version = "10"} 20 | ["echo" make share ocaml:version] 21 | ["this as well" {os = "myOS"}] 22 | ] 23 | available: os != "NO" | os != "NO" & os != "YES" 24 | 25 | (* List of files to substitute env variables *) 26 | substs: [ "P1.config" ] 27 | 28 | (* Libraries *) 29 | libraries: [ "p1" ] 30 | 31 | (* External dependencies *) 32 | depexts: [ 33 | [ ["debian" "amd64"] ["foo" "bar"] ] 34 | [ ["osx" ] ["foobar"] ] 35 | ] 36 | 37 | messages: [ "I'll always bother you displaying this message" ] 38 | 39 | post-messages: [ "Thanks SO MUCH for installing this humble package" 40 | "Everything went well" {success} 41 | "Nooo, something went wrong, this makes me feel sooo sad..." {failure} ] 42 | 43 | bug-reports: "TEST.com" 44 | 45 | setenv: [P1 = "version1"] 46 | depends: [ 47 | "ocaml" {(!= "20" | != "10") & (= "20" | = "10" | = "10+a+b" | = "system")} 48 | ] 49 | -------------------------------------------------------------------------------- /src/format/opamFormatConfig.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Configuration options for the format lib (record, global reference and 12 | setter) *) 13 | 14 | type t = private { 15 | strict : bool; 16 | (** Fail early with errors in OPAM files *) 17 | skip_version_checks : bool; 18 | (** Ignore mismatching OPAM versions in files *) 19 | all_parens : bool; 20 | (** Affects the OPAM format printer; for backwards-compatibility *) 21 | } 22 | 23 | type 'a options_fun = 24 | ?strict:bool -> 25 | ?skip_version_checks:bool -> 26 | ?all_parens:bool -> 27 | 'a 28 | 29 | include OpamStd.Config.Sig 30 | with type t := t 31 | and type 'a options_fun := 'a options_fun 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _obuild/ 2 | _opam/ 3 | bootstrap/ 4 | tests/tmp/ 5 | .*.swp 6 | src_ext/cudf/ 7 | src_ext/cppo/ 8 | src_ext/dose/ 9 | src_ext/cmdliner/ 10 | src_ext/extlib/ 11 | src_ext/re/ 12 | src_ext/graph/ 13 | src_ext/opam-file-format/ 14 | src_ext/*.stamp 15 | src_ext/*.tbz 16 | src_ext/*.tar.gz 17 | *.tar.bz2 18 | *.annot 19 | *.tar.gz 20 | *~ 21 | .#* 22 | \#*# 23 | ocp-build.root 24 | ocp-build.root.old 25 | ocp-get 26 | ocp-get-server 27 | ocp-build.root.old.old 28 | # debug files 29 | *.log 30 | *.cudf 31 | *.dot 32 | # Generated files: 33 | *.cmo 34 | *.cmx 35 | *.cmi 36 | *.cmt 37 | *.cmti 38 | *.cma 39 | *.cmxa 40 | *.cmxs 41 | *.a 42 | *.o 43 | META 44 | *.install 45 | Makefile.config 46 | config.log 47 | config.status 48 | src/client/opamGitVersion.ml 49 | src/state/opamScript.ml 50 | src/core/opamVersion.ml 51 | src/core/opamScript.ml 52 | src/format/opamLexer.ml 53 | src/format/opamLineLexer.ml 54 | src/format/opamParser.ml 55 | src/format/opamParser.mli 56 | src/core/opamCompat.ml 57 | src/core/opamCompat.mli 58 | src/opam 59 | src/opam-installer 60 | src/opam-check 61 | src/opam-admin.top 62 | src/*.META 63 | ._d 64 | ._ncdi 65 | ._bcdi 66 | aclocal.m4 67 | autom4te.cache 68 | # doc 69 | doc/dev-manual/*aux 70 | doc/dev-manual/*.html 71 | doc/dev-manual/*toc 72 | doc/html 73 | doc/man-html 74 | doc/tutorials/opam.wiki 75 | doc/dev-manual/*.out 76 | doc/man 77 | src/x_build_libs.ocp 78 | -------------------------------------------------------------------------------- /opam-devel.opam: -------------------------------------------------------------------------------- 1 | opam-version: "1.2" 2 | version: "2.0.0~beta" 3 | maintainer: "opam-devel@lists.ocaml.org" 4 | authors: [ 5 | "Thomas Gazagnaire " 6 | "Anil Madhavapeddy " 7 | "Fabrice Le Fessant " 8 | "Frederic Tuong " 9 | "Louis Gesbert " 10 | "Guillem Rieu " 11 | "Vincent Bernardoff " 12 | "Roberto Di Cosmo " 13 | ] 14 | homepage: "https://opam.ocaml.org" 15 | bug-reports: "https://github.com/ocaml/opam/issues" 16 | dev-repo: "https://github.com/ocaml/opam.git" 17 | build: [ 18 | ["./configure" "--disable-checks" "--prefix" prefix] 19 | [make name] 20 | [make "%{name}%.install"] 21 | ] 22 | build-test: [make "tests"] 23 | depends: [ 24 | "opam-client" {= "2.0.0~beta"} 25 | "cmdliner" {>= "0.9.8"} 26 | ] 27 | post-messages: [ 28 | "The development version of opam has been successfuly compiled into %{lib}%/%{name}%. You should not run it from there, please install the binaries to your PATH, e.g. with 29 | sudo cp %{lib}%/%{name}%/* /usr/local/bin 30 | 31 | If you just want to give it a try without altering your current installation, you could use instead: 32 | alias opam2=\"OPAMROOT=~/.opam2 %{lib}%/%{name}%/opam\"" 33 | {success} 34 | ] 35 | available: ocaml-version >= "4.01.0" 36 | -------------------------------------------------------------------------------- /src/core/opamCompat.ml.4.01: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2014 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | module Bytes = struct 12 | include String 13 | let sub_string = sub 14 | let empty = "" 15 | let of_string x = String.copy x 16 | let to_string x = String.copy x 17 | let blit_string = String.blit 18 | external unsafe_to_string : t -> string = "%identity" 19 | external unsafe_of_string : string -> t = "%identity" 20 | end 21 | 22 | module String = struct 23 | include String 24 | let lowercase_ascii = lowercase 25 | let capitalize_ascii = capitalize 26 | end 27 | 28 | module Char = struct 29 | include Char 30 | let lowercase_ascii = lowercase 31 | end 32 | 33 | module Buffer = struct 34 | include Buffer 35 | let add_subbytes = add_substring 36 | end 37 | 38 | module Filename = struct 39 | include Filename 40 | let get_temp_dir_name () = temp_dir_name 41 | end 42 | -------------------------------------------------------------------------------- /src/repository/opamRepositoryConfig.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Configuration options for the repository lib (record, global reference, 12 | setter, initialisation) *) 13 | 14 | (** Toggles parsing of the tool's output to detect errors 15 | (curl returns 0 on a 404) *) 16 | type dl_tool_kind = [ `Curl | `Default ] 17 | 18 | type t = { 19 | download_tool: (OpamTypes.arg list * dl_tool_kind) Lazy.t; 20 | validation_hook: OpamTypes.arg list option; 21 | retries: int; 22 | force_checksums: bool option; 23 | } 24 | 25 | type 'a options_fun = 26 | ?download_tool:(OpamTypes.arg list * dl_tool_kind) Lazy.t -> 27 | ?validation_hook:OpamTypes.arg list option -> 28 | ?retries:int -> 29 | ?force_checksums:bool option -> 30 | 'a 31 | 32 | include OpamStd.Config.Sig 33 | with type t := t 34 | and type 'a options_fun := 'a options_fun 35 | -------------------------------------------------------------------------------- /src/repository/opamDownload.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Configuration init and handling of downloading commands *) 13 | 14 | (** downloads a file from an URL, using Curl, Wget, or a custom configured 15 | tool, to the given directory. Returns the downloaded filename. 16 | @raise Failure if the download failed or if the checksum is specified and 17 | doesn't match*) 18 | val download: 19 | ?quiet:bool -> ?validate:bool -> overwrite:bool -> ?compress:bool -> 20 | ?checksum:OpamHash.t -> 21 | OpamUrl.t -> OpamFilename.Dir.t -> 22 | OpamFilename.t OpamProcess.job 23 | 24 | (** As [download], but with a specified output filename. *) 25 | val download_as: 26 | ?quiet:bool -> ?validate:bool -> overwrite:bool -> ?compress:bool -> 27 | ?checksum:OpamHash.t -> 28 | OpamUrl.t -> OpamFilename.t -> 29 | unit OpamProcess.job 30 | -------------------------------------------------------------------------------- /src/core/opamHash.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Stored as hexadecimal strings *) 12 | type kind = [ `MD5 | `SHA256 | `SHA512 ] 13 | 14 | type t 15 | 16 | val kind: t -> kind 17 | 18 | (** The value of the hash, as a string of hexadecimal characters *) 19 | val contents: t -> string 20 | 21 | val string_of_kind: kind -> string 22 | 23 | val md5: string -> t 24 | val sha256: string -> t 25 | val sha512: string -> t 26 | 27 | include OpamStd.ABSTRACT with type t := t 28 | 29 | val of_string_opt: string -> t option 30 | 31 | (** returns a sub-path specific to this hash, e.g. 32 | "md5/d4/d41d8cd98f00b204e9800998ecf8427e", as a list *) 33 | val to_path: t -> string list 34 | 35 | val check_file: string -> t -> bool 36 | 37 | (** Like [check_file], but returns the actual mismatching hash of the file, or 38 | [None] in case of match *) 39 | val mismatch: string -> t -> t option 40 | 41 | val compute: ?kind:kind -> string -> t 42 | -------------------------------------------------------------------------------- /src/core/opamVersion.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** (generated) Current OPAM version *) 13 | 14 | include OpamStd.ABSTRACT 15 | 16 | (** The current OPAM version *) 17 | val current: t 18 | 19 | (** Extracts the major version *) 20 | val major: t -> t 21 | 22 | (** Major+minor version, strips the patch version *) 23 | val nopatch: t -> t 24 | 25 | (** The current OPAM version, truncated (only MAJOR.MINOR) *) 26 | val current_nopatch: t 27 | 28 | (** The 'git' version of OPAM *) 29 | val git: unit -> t option 30 | 31 | (** Side-effect to set the git version later in the build *) 32 | val set_git: string -> unit 33 | 34 | (** The full version (current + git) *) 35 | val full: unit -> t 36 | 37 | (** Magic string, always of length 8 *) 38 | val magic: unit -> string 39 | 40 | (** Display the version message *) 41 | val message: unit -> unit 42 | 43 | (** Version comparison *) 44 | val compare: t -> t -> int 45 | -------------------------------------------------------------------------------- /src/core/opamCompat.mli.4.01: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2014 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Compatibility layer (Bytes, etc.) for different OCaml versions *) 12 | 13 | module Bytes : sig 14 | include module type of String 15 | val empty : t 16 | val of_string : string -> t 17 | val to_string : t -> string 18 | val sub_string : t -> int -> int -> string 19 | val blit_string : string -> int -> t -> int -> int -> unit 20 | external unsafe_to_string : t -> string = "%identity" 21 | external unsafe_of_string : string -> t = "%identity" 22 | end 23 | 24 | module String : sig 25 | include module type of String 26 | val lowercase_ascii : string -> string 27 | val capitalize_ascii : string -> string 28 | end 29 | 30 | module Char : sig 31 | include module type of Char 32 | val lowercase_ascii: char -> char 33 | end 34 | 35 | module Buffer : sig 36 | include module type of Buffer with type t = Buffer.t 37 | val add_subbytes : t -> Bytes.t -> int -> int -> unit 38 | end 39 | 40 | module Filename : sig 41 | include module type of Filename 42 | val get_temp_dir_name : unit -> string 43 | end 44 | -------------------------------------------------------------------------------- /admin-scripts/split_install.ml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env opam-admin.top 2 | 3 | #directory "+../opam-lib";; 4 | #directory "+../re";; 5 | open Opam_admin_top;; 6 | open OpamTypes;; 7 | 8 | iter_packages ~opam:(fun _ opam -> 9 | let module O = OpamFile.OPAM in 10 | if O.install opam <> [] then opam else 11 | let rec rev_split_while acc cond = function 12 | | [] -> acc, [] 13 | | x::r when cond x -> rev_split_while (x::acc) cond r 14 | | l -> acc, List.rev l 15 | in 16 | let condition = function 17 | | (CString "install",_)::_, _ -> true 18 | | (CString "cp",_)::r, _ -> 19 | (try 20 | let dest = 21 | match List.filter (function 22 | | CString s, _ -> not (OpamStd.String.starts_with ~prefix:"-" s) 23 | | CIdent _, _ -> true) 24 | (List.rev r) 25 | with 26 | | (d, _)::_ -> d 27 | | _ -> raise Not_found 28 | in 29 | let dests = ["prefix";"bin";"sbin";"lib";"man";"doc";"share";"etc"; 30 | "toplevel";"stublibs";"doc"] in 31 | match dest with 32 | | CIdent i -> List.mem i dests 33 | | CString s -> 34 | Re.(execp (compile (seq [alt (List.map str dests); str "}%"])) s) 35 | with Not_found -> false) 36 | | l, _ -> 37 | List.exists (function 38 | | (CString arg, _) -> OpamStd.String.contains ~sub:"install" arg 39 | | _ -> false) 40 | l 41 | in 42 | let install, build = 43 | rev_split_while [] condition (List.rev (O.build opam)) 44 | in 45 | opam |> 46 | OpamFile.OPAM.with_build build |> 47 | OpamFile.OPAM.with_install install) 48 | () 49 | ;; 50 | -------------------------------------------------------------------------------- /src/solver/opamSolverConfig.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Configuration options for the solver lib (record, global reference, setter, 12 | initialisation) *) 13 | 14 | type t = private { 15 | cudf_file: string option; 16 | solver_timeout: float; 17 | external_solver: OpamTypes.arg list option Lazy.t; 18 | soft: bool; 19 | solver_preferences_default: string Lazy.t option; 20 | solver_preferences_upgrade: string Lazy.t option; 21 | solver_preferences_fixup: string Lazy.t option; 22 | } 23 | 24 | type 'a options_fun = 25 | ?cudf_file:string option -> 26 | ?solver_timeout:float -> 27 | ?external_solver:OpamTypes.arg list option Lazy.t -> 28 | ?soft:bool -> 29 | ?solver_preferences_default:string Lazy.t option -> 30 | ?solver_preferences_upgrade:string Lazy.t option -> 31 | ?solver_preferences_fixup:string Lazy.t option -> 32 | 'a 33 | 34 | include OpamStd.Config.Sig 35 | with type t := t 36 | and type 'a options_fun := 'a options_fun 37 | 38 | val external_solver_command: 39 | input:string -> output:string -> criteria:string -> string list option 40 | 41 | val criteria: OpamTypes.solver_criteria -> string 42 | -------------------------------------------------------------------------------- /src/client/opamInitDefaults.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | let repository_url = { 12 | OpamUrl. 13 | transport = "https"; 14 | path = "opam.ocaml.org"; 15 | hash = None; 16 | backend = `http; 17 | } 18 | 19 | let default_compiler = 20 | OpamFormula.ors [ 21 | OpamFormula.Atom (OpamPackage.Name.of_string "ocaml-system", 22 | OpamFormula.Atom 23 | (`Geq, OpamPackage.Version.of_string "4.01.0")); 24 | OpamFormula.Atom (OpamPackage.Name.of_string "ocaml-base-compiler", 25 | OpamFormula.Empty); 26 | ] 27 | 28 | let eval_variables = [ 29 | OpamVariable.of_string "arch", ["uname"; "-m"], 30 | "Host architecture, as returned by 'uname -m'"; 31 | OpamVariable.of_string "sys-ocaml-version", ["ocamlc"; "-vnum"], 32 | "OCaml version present on your system independently of opam, if any"; 33 | ] 34 | 35 | module I = OpamFile.InitConfig 36 | 37 | let init_config = 38 | I.empty |> 39 | I.with_repositories 40 | [OpamRepositoryName.of_string "default", (repository_url, None)] |> 41 | I.with_default_compiler default_compiler |> 42 | I.with_eval_variables eval_variables 43 | -------------------------------------------------------------------------------- /src/format/opamSwitch.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** The type for switch names *) 13 | 14 | include OpamStd.ABSTRACT 15 | 16 | (** System switch name *) 17 | val unset: t 18 | 19 | (** Display an error message when a switch is not installed. *) 20 | val not_installed: t -> 'a 21 | 22 | (** Determines wether this switch is internal (bound to a prefix within the opam 23 | root) or living somewhere else, in which case its prefix dir is inferred 24 | from its name using [get_root] *) 25 | val is_external: t -> bool 26 | 27 | (** Returns the root directory of the switch with the given name, assuming the 28 | given opam root *) 29 | val get_root: OpamFilename.Dir.t -> t -> OpamFilename.Dir.t 30 | 31 | (** The relative dirname in which the opam switch prefix sits for external 32 | switches ("_opam") *) 33 | val external_dirname: string 34 | 35 | (** Returns an external switch handle from a directory name. Resolves to the 36 | destination if [external_dirname] at the given dir is a symlink to another 37 | [external_dirname]. *) 38 | val of_dirname: OpamFilename.Dir.t -> t 39 | -------------------------------------------------------------------------------- /src/format/opamFormatConfig.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | type t = { 12 | strict: bool; 13 | skip_version_checks: bool; 14 | all_parens: bool; 15 | } 16 | 17 | type 'a options_fun = 18 | ?strict:bool -> 19 | ?skip_version_checks:bool -> 20 | ?all_parens:bool -> 21 | 'a 22 | 23 | let default = { 24 | strict = false; 25 | skip_version_checks = false; 26 | all_parens = false; 27 | } 28 | 29 | let setk k t 30 | ?strict 31 | ?skip_version_checks 32 | ?all_parens 33 | = 34 | let (+) x opt = match opt with Some x -> x | None -> x in 35 | k { 36 | strict = t.strict + strict; 37 | skip_version_checks = t.skip_version_checks + skip_version_checks; 38 | all_parens = t.all_parens + all_parens; 39 | } 40 | 41 | let set t = setk (fun x () -> x) t 42 | 43 | (* Global configuration reference *) 44 | 45 | let r = ref default 46 | 47 | let update ?noop:_ = setk (fun cfg () -> r := cfg) !r 48 | 49 | let initk k = 50 | let open OpamStd.Config in 51 | setk (setk (fun c -> r := c; k)) !r 52 | ?strict:(env_bool "STRICT") 53 | ?skip_version_checks:(env_bool "SKIPVERSIONCHECKS") 54 | ?all_parens:(env_bool "ALLPARENS") 55 | 56 | let init ?noop:_ = initk (fun () -> ()) 57 | -------------------------------------------------------------------------------- /src/format/opamSwitch.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | include OpamStd.AbstractString 13 | 14 | let unset = of_string "#unset#" 15 | 16 | let not_installed s = 17 | OpamConsole.error_and_exit 18 | "The selected switch %s is not installed. Please choose a \ 19 | different one using the 'opam switch' command." 20 | (to_string s) 21 | 22 | let is_external s = 23 | OpamStd.String.starts_with ~prefix:"." s || 24 | OpamStd.String.contains ~sub:Filename.dir_sep s 25 | 26 | let external_dirname = "_opam" 27 | 28 | let of_string s = 29 | if is_external s then OpamFilename.Dir.(to_string (of_string s)) 30 | else s 31 | 32 | let of_dirname d = 33 | let s = OpamFilename.Dir.to_string d in 34 | try 35 | let swdir = Filename.concat s external_dirname in 36 | let r = OpamSystem.real_path Filename.(concat s (Unix.readlink swdir)) in 37 | if Filename.basename r = external_dirname then Filename.dirname r else s 38 | with Unix.Unix_error _ -> s 39 | 40 | let get_root root s = 41 | if is_external s 42 | then OpamFilename.Op.(OpamFilename.Dir.of_string s / external_dirname) 43 | else OpamFilename.Op.(root / s) 44 | -------------------------------------------------------------------------------- /src/state/opamFormatUpgrade.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** This modules handles the conversion from older repository and package 13 | versions to the current one *) 14 | 15 | open OpamTypes 16 | 17 | (** The latest version of the opam root format, that normal operation of this 18 | instance of opam requires *) 19 | val latest_version: OpamVersion.t 20 | 21 | (** Runs the upgrade from its current format to the latest version for the opam 22 | root at the given directory. A global write lock must be supplied, and the 23 | updated global config is returned. *) 24 | val as_necessary: OpamSystem.lock -> dirname -> OpamFile.Config.t -> OpamFile.Config.t 25 | 26 | (** Converts the opam file format, including rewriting availabillity conditions 27 | based on OCaml-related variables into dependencies. The filename is used to 28 | report errors *) 29 | val opam_file_from_1_2_to_2_0: 30 | ?filename:OpamFile.OPAM.t OpamFile.t -> OpamFile.OPAM.t -> OpamFile.OPAM.t 31 | 32 | (** Runs the opam file format from the file's format to current. Supplying 33 | [filename] enables additional notification messages *) 34 | val opam_file: 35 | ?filename:OpamFile.OPAM.t OpamFile.t -> 36 | OpamFile.OPAM.t -> OpamFile.OPAM.t 37 | -------------------------------------------------------------------------------- /src/repository/opamRepositoryPath.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | open OpamFilename.Op 13 | 14 | let create root name = root / "repo" / OpamRepositoryName.to_string name 15 | 16 | let repo repo_root = repo_root // "repo" |> OpamFile.make 17 | 18 | let packages_dir repo_root = repo_root / "packages" 19 | 20 | let packages repo_root prefix nv = 21 | match prefix with 22 | | None -> packages_dir repo_root / OpamPackage.to_string nv 23 | | Some p -> packages_dir repo_root / p / OpamPackage.to_string nv 24 | 25 | let opam repo_root prefix nv = 26 | packages repo_root prefix nv // "opam" |> OpamFile.make 27 | 28 | let descr repo_root prefix nv = 29 | packages repo_root prefix nv // "descr" |> OpamFile.make 30 | 31 | let url repo_root prefix nv = 32 | packages repo_root prefix nv // "url" |> OpamFile.make 33 | 34 | let files repo_root prefix nv = 35 | packages repo_root prefix nv / "files" 36 | 37 | module Remote = struct 38 | (** URL, not FS paths *) 39 | open OpamUrl.Op 40 | 41 | let repo root_url = 42 | root_url / "repo" 43 | 44 | let packages_url root_url = 45 | root_url / "packages" 46 | 47 | let archive root_url nv = 48 | root_url / "archives" / (OpamPackage.to_string nv ^ "+opam.tar.gz") 49 | end 50 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | -include ../Makefile.config 2 | 3 | ifndef OPAM 4 | OPAM = ../src/opam 5 | endif 6 | BINDIR = $(dir $(OPAM)) 7 | SRCDIR = $(sort $(foreach x,$(wildcard ../src/*/*),$(dir $x))) 8 | 9 | TOPICS = $(shell $(OPAM) help topics) 10 | TOPICS_ADMIN = cache filter index lint list upgrade 11 | 12 | HELPFMT = --help=groff 13 | 14 | ifndef OPAM_INSTALLER 15 | OPAM_INSTALLER = $(BINDIR)/opam-installer 16 | endif 17 | 18 | SRCEXTDIR = ../src_ext/lib 19 | 20 | ifneq ($(wildcard $(SRCEXTDIR)),) 21 | OCAMLDOC = ocamldoc $(patsubst %,-I %,$(SRCDIR) $(SRCEXTDIR)) 22 | else 23 | OCAMLDOC = ocamlfind ocamldoc $(patsubst %,-package %,$(PACKS)) $(patsubst %,-I %,$(SRCDIR)) 24 | endif 25 | 26 | .PHONY: man html dev-manual pages 27 | all: man dev html pages 28 | 29 | man: 30 | rm -rf man 31 | mkdir -p man 32 | $(OPAM) $(HELPFMT) > man/opam.1 33 | for i in $(TOPICS); do\ 34 | $(OPAM) $$i $(HELPFMT) > man/opam-$$i.1;\ 35 | done 36 | $(OPAM) admin $(HELPFMT) > man/opam-admin.1 37 | for i in $(TOPICS_ADMIN); do\ 38 | $(OPAM) admin $$i $(HELPFMT) > man/opam-admin-$$i.1;\ 39 | done 40 | $(OPAM_INSTALLER) $(HELPFMT) > man/opam-installer.1 41 | 42 | man-html: man 43 | rm -rf $@ 44 | mkdir -p $@ 45 | for f in $(wildcard man/*); do\ 46 | man2html -r $$f > man-html/$$(basename $$f .1).html;\ 47 | done 48 | 49 | dev: 50 | $(MAKE) -C dev-manual 51 | 52 | html: 53 | rm -rf html/ocamldoc 54 | mkdir -p html/ocamldoc 55 | sed 's/%{OPAMVERSION}%/'$(version)'/g' index.html > html/index.html 56 | $(OCAMLDOC) $(wildcard ../src/*/*.mli) $(wildcard ../src/*/*.ml) -html -d html/ocamldoc || true 57 | $(OCAMLDOC) $(wildcard ../src/*/*.mli) $(wildcard ../src/*/*.ml) -dot -o /dev/stdout | \ 58 | tred | \ 59 | dot -Tsvg > \ 60 | html/ocamldoc/dependencies.svg \ 61 | || true 62 | 63 | pages/%.html: pages/%.md 64 | omd $^ -o $@ 65 | 66 | PAGES=$(wildcard pages/*.md) 67 | 68 | pages: $(PAGES:.md=.html) 69 | 70 | clean: 71 | rm -rf man html/ocamldoc man-html pages/*.html 72 | $(MAKE) -C dev-manual clean 73 | -------------------------------------------------------------------------------- /src/format/opamLineLexer.mll: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | { 13 | 14 | type token = 15 | | WORD of string 16 | | NEWLINE 17 | | EOF 18 | 19 | let word = Buffer.create 57 20 | 21 | } 22 | 23 | let normalchar = [^' ' '\t' '\n' '\\'] 24 | 25 | rule main = parse 26 | | '\n' { Lexing.new_line lexbuf; NEWLINE } 27 | | [' ' '\t']+ { main lexbuf } 28 | | (normalchar* as w) '\\' 29 | { Buffer.reset word ; Buffer.add_string word w; escaped lexbuf } 30 | | (normalchar* as w) 31 | { WORD w } 32 | | eof { EOF } 33 | 34 | and escaped = parse 35 | | (_ normalchar*) as w '\\' 36 | { Buffer.add_string word w; escaped lexbuf } 37 | | (_ normalchar*) as w 38 | { Buffer.add_string word w; WORD (Buffer.contents word) } 39 | 40 | { 41 | 42 | let main lexbuf = 43 | let rec aux lines words = 44 | match main lexbuf with 45 | | WORD "" -> aux lines words 46 | | WORD s -> aux lines (s::words) 47 | | NEWLINE -> 48 | let lines = if words = [] then lines else List.rev words::lines in 49 | aux lines [] 50 | | EOF -> 51 | let lines = if words = [] then lines else List.rev words::lines in 52 | List.rev lines 53 | in 54 | aux [] [] 55 | 56 | } 57 | -------------------------------------------------------------------------------- /admin-scripts/cudf-debug.ml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env opam-admin.top 2 | 3 | #directory "+../cudf";; 4 | #directory "+../dose3";; 5 | #directory "+../opam-lib";; 6 | open Opam_admin_top;; 7 | 8 | let cudf2opam_name cpkg = 9 | OpamPackage.Name.of_string 10 | (try Cudf.lookup_package_property cpkg OpamCudf.s_source 11 | with Not_found -> Common.CudfAdd.decode cpkg.Cudf.package) 12 | 13 | let cudf2opam_version cpkg = 14 | OpamPackage.Version.of_string 15 | (try Cudf.lookup_package_property cpkg OpamCudf.s_source_number 16 | with Not_found -> Printf.sprintf "#cudf%d" cpkg.Cudf.version) 17 | 18 | let cudf_pp cpkg = 19 | OpamPackage.Name.to_string (cudf2opam_name cpkg), 20 | OpamPackage.Version.to_string (cudf2opam_version cpkg), 21 | [] 22 | 23 | let rebuild_version_map univ = 24 | Cudf.fold_packages (fun acc cpkg -> 25 | let nv = 26 | OpamPackage.create (cudf2opam_name cpkg) (cudf2opam_version cpkg) 27 | in 28 | OpamPackage.Map.add nv cpkg.Cudf.version acc 29 | ) 30 | OpamPackage.Map.empty univ 31 | 32 | let _ = 33 | match Cudf_parser.load_from_file Sys.argv.(1) with 34 | | Some preamble, univ, Some req -> 35 | begin match Algo.Depsolver.check_request ~explain:true (preamble, univ, req) with 36 | | Algo.Depsolver.Unsat (Some f) -> 37 | OpamConsole.msg "== DOSE MESSAGE ==\n"; 38 | flush stdout; 39 | Algo.Diagnostic.fprintf_human 40 | ~pp:cudf_pp 41 | Format.err_formatter 42 | f; 43 | flush stderr; 44 | let version_map = rebuild_version_map univ in 45 | begin match OpamCudf.make_conflicts ~version_map univ f with 46 | | OpamTypes.Conflicts cs -> 47 | OpamConsole.msg "== OPAM MESSAGE ==\n%s\n" 48 | (OpamCudf.string_of_conflict (fun a -> Printf.sprintf "%s unavailable" (OpamFormula.string_of_atom a)) cs) 49 | | _ -> prerr_endline "unhandled case" 50 | end 51 | | _ -> () 52 | end 53 | | _ -> OpamConsole.error_and_exit "unsupported cudf file" 54 | -------------------------------------------------------------------------------- /doc/dev-manual/dev-manual.css: -------------------------------------------------------------------------------- 1 | /* ==== general presentation ==== */ 2 | body { 3 | padding: 0.4em 16% 3em 8%; 4 | } 5 | h1, h1 a, 6 | h2, h2 a, 7 | h3, h3 a { 8 | padding: 0 0 0 0.4em; 9 | } 10 | .titlemain, 11 | .titlerest { 12 | padding: 0.2em 3.8em; 13 | } 14 | pre { 15 | padding: 0.2em 0.4em; 16 | margin: 0.4em 0.6em; 17 | } 18 | p { 19 | padding: 0 0 0 0.8em; 20 | } 21 | dt { 22 | padding: 0 0 0 0.6em; 23 | } 24 | h1 { font-size: 1.6em; } 25 | h2 { font-size: 1.4em; } 26 | h3 { font-size: 1.2em; } 27 | h1 a { font-size: 1.0em; } 28 | h2 a { font-size: 1.0em; } 29 | h3 a { font-size: 1.0em; } 30 | a { 31 | text-decoration: none; 32 | } 33 | a:hover { 34 | text-decoration: underline; 35 | } 36 | 37 | /* ==== morning colors ==== */ 38 | body { 39 | color: #333; 40 | background-color: #F0F0F0; 41 | } 42 | pre { 43 | color: #224; 44 | background: #DDE; 45 | border: 1px solid #8AC; 46 | } 47 | h1, h1 a, 48 | h2, h2 a, 49 | h3, h3 a { 50 | color: #228; 51 | background: #CDF; 52 | } 53 | a { 54 | color: #08C; 55 | } 56 | a:hover { 57 | color: #06E; 58 | background: #DEF; 59 | } 60 | 61 | /* ==== evening colors ==== *\ 62 | body { 63 | color: #CCC; 64 | background-color: #226; 65 | } 66 | pre { 67 | color: #BDF; 68 | background: #447; 69 | border: 1px solid #46A; 70 | } 71 | h1, h1 a, 72 | h2, h2 a, 73 | h3, h3 a { 74 | color: #CCC; 75 | background: #359; 76 | } 77 | a { 78 | color: #6CF; 79 | } 80 | a:hover { 81 | color: #9EF; 82 | background: #448; 83 | } 84 | */ 85 | 86 | /* ==== sunny colors ==== *\ 87 | body { 88 | color: #333; 89 | background-color: #ffcd95; 90 | } 91 | pre { 92 | color: #422; 93 | background: #fdb50b; 94 | border: 1px solid #832809; 95 | } 96 | h1, h1 a, 97 | h2, h2 a, 98 | h3, h3 a { 99 | color: #672910; 100 | background: #ff9a0a; 101 | } 102 | a { 103 | color: #b94a48; 104 | } 105 | a:hover { 106 | color: #91310b; 107 | background: #fccb0d; 108 | } 109 | */ 110 | -------------------------------------------------------------------------------- /src/state/opamPinned.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Specific query and handling of pinned packages *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** Returns the version the package is pinned to. 18 | @raise Not_found when appropriate *) 19 | val version: 'a switch_state -> name -> version 20 | 21 | (** Returns the package with the pinned-to version from a pinned package name. 22 | @raise Not_found when appropriate *) 23 | val package: 'a switch_state -> name -> package 24 | 25 | (** Returns the package with the pinned-to version from a package name, if 26 | pinned *) 27 | val package_opt: 'a switch_state -> name -> package option 28 | 29 | (** The set of all pinned packages with their pinning versions *) 30 | val packages: 'a switch_state -> package_set 31 | 32 | (** Looks up an 'opam' file for the given named package in a source directory *) 33 | val find_opam_file_in_source: name -> dirname -> OpamFile.OPAM.t OpamFile.t option 34 | 35 | (** Finds all package definition files in a given source dir [opam], 36 | [pkgname.opam/opam], etc. *) 37 | val files_in_source: dirname -> (name option * OpamFile.OPAM.t OpamFile.t) list 38 | 39 | (** Finds back the location of the opam file this package definition was loaded 40 | from *) 41 | val orig_opam_file: OpamFile.OPAM.t -> OpamFile.OPAM.t OpamFile.t option 42 | -------------------------------------------------------------------------------- /admin-scripts/lint.ml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env opam-admin.top 2 | 3 | #directory "+../opam-lib";; 4 | open Opam_admin_top;; 5 | 6 | let includes = ref [] 7 | let excludes = ref [] 8 | let short = ref false 9 | let list = ref false 10 | 11 | let usage = 12 | "Arguments:\n\ 13 | \ -s\tshort format, don't print explanations\n\ 14 | \ -l\tlist format, only print package names\n\ 15 | \ [N]\tshow only the listed warnings\n\ 16 | \ -[N]\tskip any packages that trigger any of these warnings\n\ 17 | " 18 | 19 | let () = 20 | let args = match Array.to_list Sys.argv with 21 | | _::args -> args 22 | | [] -> [] 23 | in 24 | List.iter (function 25 | | "-s" -> short := true 26 | | "-l" -> list := true 27 | | a -> 28 | try 29 | if String.length a > 0 && a.[0] = '-' then 30 | excludes := 0 - int_of_string a :: !excludes 31 | else 32 | includes := int_of_string a :: !includes 33 | with Failure _ -> 34 | OpamConsole.msg "%s" usage; 35 | OpamStd.Sys.exit 2) 36 | args 37 | 38 | let () = 39 | OpamPackage.Map.iter (fun nv prefix -> 40 | let opam_file = OpamRepositoryPath.opam repo prefix nv in 41 | let w, _ = OpamFileTools.lint_file opam_file in 42 | if List.exists (fun (n,_,_) -> List.mem n !excludes) w then () else 43 | let w = 44 | if !includes = [] then w 45 | else List.filter (fun (n,_,_) -> List.mem n !includes) w 46 | in 47 | if w <> [] then 48 | if !list then 49 | print_endline (OpamPackage.to_string nv) 50 | else if !short then 51 | OpamConsole.msg "%s %s\n" (OpamPackage.to_string nv) 52 | (OpamStd.List.concat_map " " (fun (n,k,_) -> 53 | OpamConsole.colorise 54 | (match k with `Warning -> `yellow | `Error -> `red) 55 | (string_of_int n)) 56 | w) 57 | else 58 | OpamConsole.msg "\r\027[KIn %s:\n%s\n" 59 | (OpamPackage.to_string nv) 60 | (OpamFileTools.warns_to_string w)) 61 | (OpamRepository.packages_with_prefixes repo) 62 | -------------------------------------------------------------------------------- /src/client/opamMain.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Opam CLI main entry point *) 13 | 14 | open Cmdliner 15 | 16 | (** {2 Commands} *) 17 | 18 | (** Type of commands *) 19 | type command = unit Term.t * Term.info 20 | 21 | (** [run default commdands at_exit] build a binary which takes 22 | [commands] as subcommand and [default] as default argument 23 | (ie. which will be executed when no subcommand is 24 | given). [at_exit] is executed before the program exits. *) 25 | val run:command -> command list -> unit 26 | 27 | (** The default list of commands *) 28 | val commands: command list 29 | 30 | (** opam *) 31 | val default: command 32 | 33 | (** opam init *) 34 | val init: command 35 | 36 | (** opam list *) 37 | val list: ?force_search:bool -> unit -> command 38 | 39 | (** opam show *) 40 | val show: command 41 | 42 | (** opam install *) 43 | val install: command 44 | 45 | (** opam remove *) 46 | val remove: command 47 | 48 | (** opam reinstall *) 49 | val reinstall: command 50 | 51 | (** opam update *) 52 | val update: command 53 | 54 | (** opam upgrade *) 55 | val upgrade: command 56 | 57 | (** opam config *) 58 | val config: command 59 | 60 | (** opam repository *) 61 | val repository: command 62 | 63 | (** opam switch *) 64 | val switch: command 65 | 66 | (** opam pin *) 67 | val pin: ?unpin_only:bool -> unit -> command 68 | 69 | (** opam help *) 70 | val help: command 71 | -------------------------------------------------------------------------------- /src/tools/opam_admin_top.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Small lib for writing opam-repo admin scripts *) 13 | 14 | (** The current repo (taken from CWD !) *) 15 | val repo : OpamTypes.repository 16 | 17 | (** All defined packages in the current repo *) 18 | val packages : OpamPackage.Set.t 19 | 20 | open OpamFile 21 | 22 | type 'a action = [`Update of 'a | `Remove | `Keep ] 23 | 24 | (** Maps on the files of every package. Only changed files are written back to 25 | disk. *) 26 | val iter_packages_gen: 27 | ?quiet:bool -> 28 | (OpamPackage.t -> 29 | prefix:string option -> 30 | opam:OPAM.t -> 31 | descr:Descr.t option -> 32 | url:URL.t option -> 33 | dot_install:Dot_install.t option -> 34 | OPAM.t * Descr.t action * URL.t action * Dot_install.t action) 35 | -> unit 36 | 37 | (** Turn a list of glob patterns into a proper filtering function on 38 | package names. *) 39 | val filter_packages: string list -> (OpamPackage.t -> bool) 40 | 41 | (** Quicker interface when considering a single type of file *) 42 | val iter_packages: 43 | ?quiet:bool -> 44 | ?filter:(OpamPackage.t -> bool) -> 45 | ?f:(OpamPackage.t -> string option -> OPAM.t -> unit) -> 46 | ?opam:(OpamPackage.t -> OPAM.t -> OPAM.t) -> 47 | ?descr:(OpamPackage.t -> Descr.t -> Descr.t) -> 48 | ?url:(OpamPackage.t -> URL.t -> URL.t) -> 49 | ?dot_install:(OpamPackage.t -> Dot_install.t -> Dot_install.t) -> 50 | unit -> unit 51 | -------------------------------------------------------------------------------- /src/client/opamPinCommand.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Functions handling the "opam pin" subcommand *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** Pins a package to the given version, and writes to disk. Returns the updated 18 | state. The main difference with [source_pin] is that a definition overlay is 19 | not created. Therefore, the package must exist already. *) 20 | val version_pin: rw switch_state -> name -> version -> rw switch_state 21 | 22 | (** Sets the package as pinned to the given target. A package definition is 23 | looked for in the package source and current metadata (in this order). 24 | 25 | If [edit], or if no package definition is found, this opens an editor (with 26 | a template if no definition is available). 27 | 28 | If [force], don't abort even if the source can't be fetched from [target] *) 29 | val source_pin: 30 | rw switch_state -> name -> ?version:version -> ?edit:bool -> ?force:bool -> 31 | url option -> rw switch_state 32 | 33 | (** Let the user edit a pinned package's opam file. If given, the version is put 34 | into the template in advance. Writes and returns the updated switch 35 | state. *) 36 | val edit: rw switch_state -> ?version:version -> name -> rw switch_state 37 | 38 | (** Unpin packages *) 39 | val unpin: rw switch_state -> name list -> rw switch_state 40 | 41 | (** List the pinned packages to the user. *) 42 | val list: 'a switch_state -> short:bool -> unit 43 | -------------------------------------------------------------------------------- /doc/pages/About.md: -------------------------------------------------------------------------------- 1 | # opam 2 | 3 | ### Why opam ? 4 | 5 | [OCamlPro](http://www.ocamlpro.com/) has decided to start writing a brand new package manager for [OCaml](http://www.ocaml.org) in the beginning of 2012, after looking at the state of affairs in the OCaml community and not being completely satisfied with the existing solutions, especially regarding the management of dependency constraints between packages. Existing technologies such as [GODI](http://godi.camlcity.org/), [oasis](http://oasis.forge.ocamlcore.org/), [odb](http://oasis.ocamlcore.org/dev/odb/) and [ocamlbrew](https://github.com/hcarty/ocamlbrew) did contain lots of good ideas that have been shamelessly stolen but the final user-experience was not so great -- and due to disagreements with some of the architectural choices done in these tools, so it wasn't so easy to contribute to fix the existing flaws. Thus OCamlPro started to discuss the specification of a new package manager with folks from [Jane Street](http://www.janestreet.com/) who decided to fund the project and from the [Mancoosi project](http://www.mancoosi.org/) to integrate state-of-the-art dependency management technologies. 6 | 7 | After few months of hard-work, and continuous support and resources from [OCamlLabs](http://www.cl.cam.ac.uk/projects/ocamllabs/) and [INRIA](http://www.inria.fr/) (through funding by the [Feder DORM](http://zenika.github.io/DORM/) project), this effort finally gave birth to the [first official release](http://www.ocamlpro.com/blog/2013/03/14/opam-1.0.0.html) of opam in March 2013. 8 | 9 | ### Getting Support 10 | 11 | Opam has been created and is maintained by [OCamlPro](http://www.ocamlpro.com/). Bug reports and feature requests for the opam tool should be reported on [opam's issue-tracker](https://github.com/ocaml/opam/issues). Packaging issues or requests for a new package can be reported on the [official repository's issue-tracker](https://github.com/ocaml/opam-repository/issues). 12 | 13 | General queries for both the tool and the packages could be addressed on the [OCaml-platform mailing-list](http://lists.ocaml.org/listinfo/platform) and insights and evolution of opam internals can discussed on the [opam-devel mailing-list](http://lists.ocaml.org/listinfo/opam-devel). 14 | 15 | Standard commercial terms and support on opam, as well as training and consulting services, are provided by [OCamlPro](http://www.ocamlpro.com/). 16 | -------------------------------------------------------------------------------- /src/repository/opamRepositoryPath.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Defines the file hierarchy in repositories *) 13 | 14 | open OpamTypes 15 | 16 | (** Repository local path: {i $opam/repo/} *) 17 | val create: OpamFilename.Dir.t -> repository_name -> dirname 18 | 19 | (** Return the repo file *) 20 | val repo: dirname -> OpamFile.Repo.t OpamFile.t 21 | 22 | (** Packages folder: {i $repo/packages} *) 23 | val packages_dir: dirname -> dirname 24 | 25 | (** Package folder: {i $repo/packages/XXX/$NAME.$VERSION} *) 26 | val packages: dirname -> string option -> package -> dirname 27 | 28 | (** Return the OPAM file for a given package: 29 | {i $repo/packages/XXX/$NAME.$VERSION/opam} *) 30 | val opam: dirname -> string option -> package -> OpamFile.OPAM.t OpamFile.t 31 | 32 | (** Return the description file for a given package: 33 | {i $repo/packages/XXX/$NAME.VERSION/descr} *) 34 | val descr: dirname -> string option -> package -> OpamFile.Descr.t OpamFile.t 35 | 36 | (** urls {i $repo/package/XXX/$NAME.$VERSION/url} *) 37 | val url: dirname -> string option -> package -> OpamFile.URL.t OpamFile.t 38 | 39 | (** files {i $repo/packages/XXX/$NAME.$VERSION/files} *) 40 | val files: dirname -> string option -> package -> dirname 41 | 42 | (** Url constructor for parts of remote repositories, when applicable (http and 43 | rsync). Function take the repo's root url. *) 44 | module Remote: sig 45 | (** Remote repo file *) 46 | val repo: url -> url 47 | 48 | (** Remote package files: {i $remote/packages} *) 49 | val packages_url: url -> url 50 | 51 | (** Remote archive {i $remote/archives/$NAME.$VERSION.tar.gz} *) 52 | val archive: url -> package -> url 53 | end 54 | -------------------------------------------------------------------------------- /src/core/opamDirTrack.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** uniquely identifies a filesystem item value *) 12 | type digest 13 | 14 | (** Defines a change concerning a fs item; The [digest] parameter is the new 15 | value of the item *) 16 | type change = 17 | | Added of digest 18 | | Removed 19 | | Contents_changed of digest 20 | (** For links, corresponds to a change of target *) 21 | | Perm_changed of digest 22 | | Kind_changed of digest 23 | (** Used e.g. when a file is replaced by a directory, a link 24 | or a fifo *) 25 | 26 | type t = change OpamStd.String.Map.t 27 | 28 | (** Returns a printable, multi-line string *) 29 | val to_string: t -> string 30 | 31 | val digest_of_string: string -> digest 32 | val string_of_digest: digest -> string 33 | 34 | (** Wraps a job to track the changes that happened under [dirname] during its 35 | execution (changes done by the application of the job function to [()] are 36 | tracked too, for consistency with jobs without commands) *) 37 | val track: 38 | OpamFilename.Dir.t -> ?except:OpamFilename.Base.Set.t -> 39 | (unit -> 'a OpamProcess.job) -> ('a * t) OpamProcess.job 40 | 41 | (** Removes the added and kind-changed items unless their contents changed and 42 | [force] isn't set, and prints warnings for other changes unless [verbose] is 43 | set to [false]. Ignores non-existing files. 44 | [title] is used to prefix messages if specified. *) 45 | val revert: 46 | ?title:string -> ?verbose:bool -> ?force:bool -> ?dryrun:bool -> 47 | OpamFilename.Dir.t -> t -> unit 48 | 49 | (** Checks the items that were added or kind-changed in the given diff, and 50 | returns their status *) 51 | val check: 52 | OpamFilename.Dir.t -> t -> 53 | (OpamFilename.t * [`Unchanged | `Removed | `Changed]) list 54 | -------------------------------------------------------------------------------- /src/core/opamVersionCompare.mli: -------------------------------------------------------------------------------- 1 | (******************************************************************************) 2 | (* This file is part of the Dose library http://www.irill.org/software/dose *) 3 | (* *) 4 | (* Copyright (C) 2009-2011 Pietro Abate *) 5 | (* *) 6 | (* This library is free software: you can redistribute it and/or modify *) 7 | (* it under the terms of the GNU Lesser General Public License as *) 8 | (* published by the Free Software Foundation, either version 3 of the *) 9 | (* License, or (at your option) any later version. A special linking *) 10 | (* exception to the GNU Lesser General Public License applies to this *) 11 | (* library, see the COPYING file for more information. *) 12 | (* *) 13 | (* Work developed with the support of the Mancoosi Project *) 14 | (* http://www.mancoosi.org *) 15 | (* *) 16 | (******************************************************************************) 17 | 18 | (** Version comparison function used throughout. From the Dose suite. *) 19 | 20 | (** Functions for manipulating and comparing Debian version strings. 21 | Compliant with Debian policy version 3.9.2. and Debian developers 22 | reference version 3.4.6 *) 23 | 24 | (** {2 Comparing debian version strings} *) 25 | 26 | (** The following functions compare any two strings, that is these 27 | functions do not check whether the arguments are really legal 28 | debian versions. If the arguments are debian version strings, then 29 | the result is as required by debian policy. Note that two strings 30 | may be equivalent, that is denote the same debian version, even 31 | when they differ in syntax, as for instance "0:1.2.00" and 32 | "1.02-0". 33 | *) 34 | 35 | (** @return [true] iff the two strings define the same version. Hence, 36 | the result may be true even when the two string differ 37 | syntactically. *) 38 | val equal : string -> string -> bool 39 | 40 | (** [compare x y] returns 0 if x is eqivalent to y, -1 if x is smaller 41 | than y, and 1 if x is greater than y. This is consistent with 42 | [Pervasives.compare]. *) 43 | val compare : string -> string -> int 44 | -------------------------------------------------------------------------------- /src/state/opamGlobalState.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Loading and handling of the global state of an opam root *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** Loads the global state (from the opam root obtained through 18 | [OpamStateConfig.(!r.root)]) *) 19 | val load: 'a lock -> 'a global_state 20 | 21 | (** Loads the global state as [load], and calls the given function while keeping 22 | it locked (as per the [lock] argument), releasing the lock afterwards *) 23 | val with_: 'a lock -> ('a global_state -> 'b) -> 'b 24 | 25 | (** The set of all installed packages, in any switch *) 26 | val all_installed: 'a global_state -> package_set 27 | 28 | val switches: 'a global_state -> switch list 29 | 30 | val fold_switches: 31 | (switch -> switch_selections -> 'a -> 'a) -> 'b global_state -> 'a -> 'a 32 | 33 | (** Returns the map of installed instances of the package name towards the list 34 | of switches they are installed in *) 35 | val installed_versions: 'a global_state -> name -> switch list package_map 36 | 37 | (** Default list of repositories to get packages from, ordered by decreasing 38 | priority. This can be overriden by switch-specific selections, and does not 39 | have to include all configured repositories. *) 40 | val repos_list: 'a global_state -> repository_name list 41 | 42 | (** Releases any locks on the given global_state *) 43 | val unlock: 'a global_state -> unlocked global_state 44 | 45 | (** Calls the provided function, ensuring a temporary write lock on the given 46 | global state*) 47 | val with_write_lock: 48 | ?dontblock:bool -> 'a global_state -> 49 | (rw global_state -> 'b * 'c global_state) -> 50 | 'b * 'a global_state 51 | 52 | (** Writes back the global configuration file ~/.opam/config *) 53 | val write: rw global_state -> unit 54 | -------------------------------------------------------------------------------- /src/core/opamVersion.ml.in: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | type t = string 13 | 14 | let to_string x = x 15 | 16 | let of_string x = x 17 | 18 | let to_json x = `String x 19 | 20 | let compare v w = OpamVersionCompare.compare v w 21 | 22 | module O = struct 23 | type t = string 24 | let to_string = to_string 25 | let to_json = to_json 26 | let compare = compare 27 | end 28 | 29 | module Set = OpamStd.Set.Make(O) 30 | 31 | module Map = OpamStd.Map.Make(O) 32 | 33 | let current_raw = "@PACKAGE_VERSION@" 34 | 35 | let current = of_string current_raw 36 | 37 | let major v = 38 | try 39 | let i = String.index v '.' in 40 | of_string (String.sub v 0 i) 41 | with Not_found -> v 42 | 43 | let nopatch v = 44 | try 45 | let i = String.index v '.' in 46 | let i = String.index_from v (i+1) '.' in 47 | (String.sub v 0 i) 48 | with Not_found -> 49 | let rec f i = 50 | if i >= String.length v then v 51 | else match String.get v i with 52 | | '0'..'9' | '.' -> f (i+1) 53 | | _ -> String.sub v 0 i 54 | in 55 | f 0 56 | 57 | let current_nopatch = nopatch current_raw 58 | 59 | let message () = 60 | Printf.printf "\n\ 61 | %s version %s\n\ 62 | \n\ 63 | Copyright (C) 2012 OCamlPro - INRIA, 2013-2015 OCamlPro\n\ 64 | \n\ 65 | This is free software; see the source for copying conditions. There is NO\n\ 66 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" 67 | Sys.argv.(0) current_raw; 68 | exit 0 69 | 70 | let gitversion = ref None 71 | 72 | let set_git s = gitversion := Some s 73 | 74 | let git () = 75 | match !gitversion with 76 | | None -> None 77 | | Some v -> Some (of_string v) 78 | 79 | let full () = 80 | let git_version = match git () with 81 | | None -> "" 82 | | Some v -> Printf.sprintf " (%s)" (to_string v) in 83 | Printf.sprintf "%s%s" (to_string current) git_version 84 | 85 | let magic () = 86 | let hash = Hashtbl.hash (full ()) in 87 | String.sub (Printf.sprintf "%08X" hash) 0 8 88 | -------------------------------------------------------------------------------- /src/client/opamRepositoryCommand.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Functions handling the "opam repository" subcommand *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** List the selected repositories in the global default and/or selected 18 | switches. *) 19 | val list: 20 | 'a repos_state -> global:bool -> switches:switch list -> 21 | short:bool -> unit 22 | 23 | (** Lists all configured repositories, and, if not [short], the switches they 24 | are selected in. *) 25 | val list_all: 'a repos_state -> short:bool -> unit 26 | 27 | (** Add a new repository to ~/.opam/repos, without updating any selections *) 28 | val add: 29 | rw repos_state -> repository_name -> url -> trust_anchors option -> 30 | rw repos_state 31 | 32 | (** Remove a repository from ~/.opam/repos, without updating any selections *) 33 | val remove: rw repos_state -> repository_name -> rw repos_state 34 | 35 | (** Updates the global switch selection, used as default for switches that don't 36 | specify their selections (e.g. newly created switches) *) 37 | val update_global_selection: 38 | rw global_state -> (repository_name list -> repository_name list) -> 39 | rw global_state 40 | 41 | (** Updates the specified selections using the given functions, taking locks as 42 | required *) 43 | val update_selection: 44 | 'a global_state -> global:bool -> switches:switch list -> 45 | (repository_name list -> repository_name list) -> 46 | 'a global_state 47 | 48 | (** Change the registered address of a repo *) 49 | val set_url: 50 | rw repos_state -> repository_name -> url -> trust_anchors option -> 51 | rw repos_state 52 | 53 | (** Update the given repositories, as per [OpamUpdate.repositories], checks for 54 | their version and runs the upgrade script locally if they are for an earlier 55 | opam (the user is asked if the version is unknown). Returns [true] if no 56 | update or upgrade errors were encountered. *) 57 | val update_with_auto_upgrade: 58 | rw repos_state -> repository_name list -> bool * rw repos_state 59 | -------------------------------------------------------------------------------- /src/tools/opam_check.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (* Utility helper to check if a given set of packages is installed *) 13 | 14 | let usage = "opam-check [--root root] [-l label] +" 15 | 16 | let label = ref "" 17 | let root_dir_ref = ref "" 18 | let spec = Arg.align [ 19 | ("--root", Arg.Set_string root_dir_ref, " Set opam path"); 20 | ("-l" , Arg.Set_string label , " Set a test label"); 21 | ("--version", Arg.Unit OpamVersion.message , " Display version information"); 22 | ] 23 | 24 | let packages = ref [] 25 | let ano x = packages := x :: !packages 26 | 27 | let () = 28 | Arg.parse spec ano usage; 29 | let root_dir = match !root_dir_ref with 30 | | "" -> None 31 | | d -> Some (OpamFilename.Dir.of_string d) 32 | in 33 | OpamSystem.init(); 34 | OpamStd.Config.init(); 35 | OpamFormatConfig.init(); 36 | OpamRepositoryConfig.init(); 37 | OpamSolverConfig.init(); 38 | OpamStateConfig.init 39 | ?root_dir 40 | () 41 | 42 | 43 | let packages = OpamPackage.Set.of_list (List.map OpamPackage.of_string !packages) 44 | 45 | let installed () = 46 | let root = OpamStateConfig.(!r.root_dir) in 47 | let config = OpamFile.Config.read (OpamPath.config root) in 48 | let version = match OpamFile.Config.switch config with 49 | | Some sw -> sw 50 | | None -> failwith "No switch set" in 51 | let state = OpamFile.SwitchSelections.safe_read (OpamPath.Switch.selections root version) in 52 | state.OpamTypes.sel_installed 53 | 54 | let () = 55 | let installed = installed () in 56 | let diff1 = OpamPackage.Set.diff packages installed in 57 | let diff2 = OpamPackage.Set.diff installed packages in 58 | let diff = OpamPackage.Set.union diff1 diff2 in 59 | let label = if !label = "" then "" else Printf.sprintf "[%s] " !label in 60 | if not (OpamPackage.Set.is_empty diff) then ( 61 | OpamConsole.error "%swaiting for: %s" label (OpamPackage.Set.to_string diff1); 62 | OpamConsole.error "%sgot: %s" label (OpamPackage.Set.to_string diff2); 63 | exit 1 64 | ) 65 | -------------------------------------------------------------------------------- /src/client/opamConfigCommand.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Functions handling the "opam config" subcommand *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** Display the current environment. Booleans csh, sexp and fish set an alternative 18 | output (unspecified if more than one is true, sh-style by default). 19 | [inplace_path] changes how the PATH variable is updated when there is already 20 | an opam entry: either at the same rank, or pushed in front. *) 21 | val env: 22 | 'a switch_state -> csh:bool -> sexp:bool -> fish:bool -> inplace_path:bool -> 23 | unit 24 | 25 | (** Like [env] but allows to specify the precise env to print rather than 26 | compute it from a switch state *) 27 | val print_eval_env: csh:bool -> sexp:bool -> fish:bool -> env -> unit 28 | 29 | (** Display the content of all available variables; global summary if the list 30 | is empty, package name "-" is understood as global configuration *) 31 | val list: 32 | 'a global_state -> name list -> unit 33 | 34 | (** Display the content of a given variable *) 35 | val variable: 'a global_state -> full_variable -> unit 36 | 37 | (** Substitute files *) 38 | val subst: 'a global_state -> basename list -> unit 39 | 40 | (** Prints expansion of variables in string *) 41 | val expand: 'a global_state -> string -> unit 42 | 43 | (** Sets or unsets switch config variables *) 44 | val set: full_variable -> string option -> unit 45 | 46 | (** Sets or unsets global config variables *) 47 | val set_global: full_variable -> string option -> unit 48 | 49 | (** Update the global and user configuration to use OPAM. *) 50 | val setup: 51 | rw global_state -> 52 | ?dot_profile:OpamTypes.filename -> 53 | completion:bool -> 54 | shell:OpamTypes.shell -> 55 | user:bool -> global:bool -> unit 56 | 57 | (** Display the global and user configuration for OPAM. *) 58 | val setup_list: shell -> filename -> unit 59 | 60 | (** Execute a command in a subshell, after variable expansion *) 61 | val exec: [< unlocked ] global_state -> inplace_path:bool -> string list -> unit 62 | -------------------------------------------------------------------------------- /src/format/opamVariable.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** OPAM variables with scope (global or module), used in "opam" package 13 | definition files in "filters" *) 14 | 15 | (** {2 Variable names} *) 16 | 17 | include OpamStd.ABSTRACT 18 | 19 | (** Shortcut to variables *) 20 | type variable = t 21 | 22 | (** Variable contents *) 23 | type variable_contents = 24 | | B of bool 25 | | S of string 26 | 27 | (** Pretty print of variable contents *) 28 | val string_of_variable_contents: variable_contents -> string 29 | 30 | (** Variable contents constructors *) 31 | 32 | val string: string -> variable_contents 33 | val int: int -> variable_contents 34 | val bool: bool -> variable_contents 35 | val dirname: OpamFilename.Dir.t -> variable_contents 36 | 37 | module Full: sig 38 | 39 | (** Fully qualified variable. *) 40 | 41 | include OpamStd.ABSTRACT 42 | 43 | type scope = 44 | | Global (** Note: this is attributed to unqualified variables, and may 45 | also design self-referring ones *) 46 | | Self (** Variable in a package-specific file referring to that 47 | package [_:varname] *) 48 | | Package of OpamPackage.Name.t (** [pkgname:varname] *) 49 | 50 | (** Returns the scope of the variable *) 51 | val scope: t -> scope 52 | 53 | (** Returns the unqualified variable name *) 54 | val variable: t -> variable 55 | 56 | val is_global: t -> bool 57 | 58 | (** Return the package corresponding to the scope of the variable *) 59 | val package: ?self:OpamPackage.Name.t -> t -> OpamPackage.Name.t option 60 | 61 | (** Create a variable local for a given library/syntax extension *) 62 | val create: OpamPackage.Name.t -> variable -> t 63 | 64 | (** Create a global variable *) 65 | val global: variable -> t 66 | 67 | (** Create a variable in the [Self] scope *) 68 | val self: variable -> t 69 | 70 | (** Looks up for an environment override through the environment, by means of 71 | [OPAMVAR_glovar] or [OPAMVAR_pkg_pkgvar] *) 72 | val read_from_env: t -> variable_contents option 73 | 74 | end 75 | -------------------------------------------------------------------------------- /src/solver/opamActionGraph.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2014 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Handles graphs of actions (package changes), based on ocamlgraph *) 13 | 14 | open OpamTypes 15 | 16 | module type ACTION = sig 17 | type package 18 | module Pkg: GenericPackage with type t = package 19 | include OpamParallel.VERTEX with type t = package action 20 | val to_string: [< t ] -> string 21 | val to_aligned_strings: 22 | ?append:(package -> string) -> [< t ] list -> string list 23 | module Set: OpamStd.SET with type elt = package action 24 | module Map: OpamStd.MAP with type key = package action 25 | end 26 | 27 | module MakeAction (P: GenericPackage) : ACTION with type package = P.t and type t = P.t OpamTypes.action 28 | 29 | module type SIG = sig 30 | type package 31 | include OpamParallel.GRAPH with type V.t = package OpamTypes.action 32 | 33 | (** Reduces a graph of atomic or concrete actions (only removals, installs and 34 | builds) by turning removal+install to reinstalls or up/down-grades, best 35 | for display. Dependency ordering won't be as accurate though, as there is 36 | no proper ordering of (reinstall a, reinstall b) if b depends on a. The 37 | resulting graph contains at most one action per package name. 38 | 39 | There is no guarantee however that the resulting graph is acyclic. *) 40 | val reduce: t -> t 41 | 42 | (** Expand install actions, adding a build action preceding them. 43 | The argument [noop_remove] is a function that should return `true` 44 | for package where the `remove` action is known not to modify the 45 | filesystem (such as `conf-*` package). *) 46 | val explicit: ?noop_remove:(package -> bool) -> t -> t end 47 | 48 | module Make (A: ACTION) : SIG with type package = A.package 49 | 50 | (** Some messages that may be used for displaying actions. Single utf8 chars if 51 | the corresponding option is set, otherwise words. *) 52 | val action_strings: 53 | ?utf8:bool -> 'a action -> string 54 | 55 | (** Colorise string according to the action *) 56 | val action_color: 'a action -> string -> string 57 | -------------------------------------------------------------------------------- /src/state/opamStateConfig.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Configuration options for the state lib (record, global reference, setter, 12 | initialisation) *) 13 | 14 | open OpamTypes 15 | 16 | type t = private { 17 | root_dir: OpamFilename.Dir.t; 18 | current_switch: OpamSwitch.t option; 19 | switch_from: [ `Env | `Command_line | `Default ]; 20 | jobs: int Lazy.t; 21 | dl_jobs: int; 22 | build_test: bool; 23 | build_doc: bool; 24 | dryrun: bool; 25 | makecmd: string Lazy.t; 26 | } 27 | 28 | type 'a options_fun = 29 | ?root_dir:OpamFilename.Dir.t -> 30 | ?current_switch:OpamSwitch.t -> 31 | ?switch_from:[ `Env | `Command_line | `Default ] -> 32 | ?jobs:(int Lazy.t) -> 33 | ?dl_jobs:int -> 34 | ?build_test:bool -> 35 | ?build_doc:bool -> 36 | ?dryrun:bool -> 37 | ?makecmd:string Lazy.t -> 38 | 'a 39 | 40 | include OpamStd.Config.Sig 41 | with type t := t 42 | and type 'a options_fun := 'a options_fun 43 | 44 | (** Get the initial opam root value (from default, env or optional argument). 45 | This allows to get it before doing the init, which is useful to get the 46 | configuration file used to fill some options to init() *) 47 | val opamroot: ?root_dir:dirname -> unit -> dirname 48 | 49 | (** Loads the global configuration file, protecting against concurrent writes *) 50 | val load: dirname -> OpamFile.Config.t option 51 | 52 | (** Loads the config file from the OPAM root and updates default values for all 53 | related OpamXxxConfig modules. Doesn't read the env yet, the [init] 54 | functions should still be called afterwards. OpamFormat should be 55 | initialised beforehand, as it may impact the config file loading. 56 | 57 | Returns the config file that was found, if any *) 58 | val load_defaults: OpamFilename.Dir.t -> OpamFile.Config.t option 59 | 60 | (** Returns the current switch, failing with an error message is none is set. *) 61 | val get_switch: unit -> switch 62 | 63 | (** The function used to locate an external switch from parents of the current 64 | directory. Takes the opam root as parameter, and rejects any external switch 65 | configured with a different root *) 66 | val get_current_switch_from_cwd: OpamFilename.Dir.t -> switch option 67 | -------------------------------------------------------------------------------- /src/core/opamCoreConfig.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | (** Configuration options for the core lib (record, global reference and 12 | setter) *) 13 | 14 | type t = private { 15 | debug_level : int; 16 | (** Controls debug messages, 0 to disable *) 17 | verbose_level : int; 18 | (** Controls printing of external commands and output, 0 to disable, more 19 | means print more low-level commands *) 20 | color : [ `Always | `Never | `Auto ]; 21 | (** Console ANSI color control *) 22 | utf8 : [ `Extended | `Always | `Never | `Auto ]; 23 | (** Controls usage of UTF8 in OPAM-generated messages. Extended adds camel 24 | emojis *) 25 | disp_status_line: [ `Always | `Never | `Auto ]; 26 | (** Controls on-line display of parallel commands being run, using ANSI 27 | escapes *) 28 | answer : bool option; 29 | (** Affects interactive questions in OpamConsole: auto-answer with the given 30 | bool if Some *) 31 | safe_mode : bool; 32 | (** Fail on writes or delays, don't ask questions (for quick queries, e.g. 33 | for shell completion) *) 34 | log_dir : string; 35 | (** Where to store log and temporary files (output from commands...) *) 36 | keep_log_dir : bool; 37 | (** Whether to cleanup temporary and log files on exit *) 38 | errlog_length : int; 39 | (** The number of log lines displayed on process error. 0 for all *) 40 | merged_output : bool; 41 | (** If set, stderr of commands is merged into their stdout *) 42 | use_openssl : bool; 43 | (** If false, will use built-in hash functions without checking for an openssl 44 | executable first *) 45 | } 46 | 47 | type 'a options_fun = 48 | ?debug_level:int -> 49 | ?verbose_level:int -> 50 | ?color:[ `Always | `Never | `Auto ] -> 51 | ?utf8:[ `Extended | `Always | `Never | `Auto ] -> 52 | ?disp_status_line:[ `Always | `Never | `Auto ] -> 53 | ?answer:bool option -> 54 | ?safe_mode:bool -> 55 | ?log_dir:string -> 56 | ?keep_log_dir:bool -> 57 | ?errlog_length:int -> 58 | ?merged_output:bool -> 59 | ?use_openssl:bool -> 60 | 'a 61 | 62 | val default : t 63 | 64 | val set : t -> (unit -> t) options_fun 65 | 66 | val setk : (t -> 'a) -> t -> 'a options_fun 67 | 68 | val r : t ref 69 | 70 | val update : ?noop:_ -> (unit -> unit) options_fun 71 | -------------------------------------------------------------------------------- /shell/opam_installer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -ue 4 | 5 | # (c) Copyright Fabrice Le Fessant INRIA/OCamlPro 2013 6 | # (c) Copyright Louis Gesbert OCamlPro 2014-2015 7 | 8 | VERSION='1.2.2' 9 | 10 | default_ocaml=4.02.1 11 | 12 | usage() { 13 | cat <&2 36 | for s in "$@"; do echo $s; done 37 | exit 1 38 | } 39 | 40 | 41 | TMP=${TMPDIR:-/tmp} 42 | 43 | dlerror () { 44 | error "Couldn't download $url" \ 45 | "There may not yet be a binary release for your architecture or OS, sorry." 46 | } 47 | 48 | getopam() { 49 | opamfile=$2 50 | url=$1/$opamfile 51 | 52 | if which wget >/dev/null; then 53 | wget -q -O "$TMP/$opamfile" "$url" || dlerror 54 | else 55 | curl -s -L -o "$TMP/$opamfile" "$url" || dlerror 56 | fi 57 | } 58 | 59 | if [ $# -lt 1 ] || [ $# -gt 2 ] || [ "${1#-}" != "$1" ]; then 60 | echo "opam binary installer v. $VERSION" 61 | usage 62 | fi 63 | 64 | BINDIR=$1 65 | COMP=${2:-$default_ocaml} 66 | 67 | file="opam-$VERSION-$(uname -m || echo unknown)-$(uname -s || echo unknown)" 68 | 69 | echo Downloading opam... 70 | getopam "https://github.com/ocaml/opam/releases/download/$VERSION" $file 71 | 72 | mkdir -p "$BINDIR" 2>/dev/null || true 73 | if [ ! -w "$BINDIR" ]; then 74 | echo "You don't have write access to $BINDIR: sudo may ask for your password" 75 | if [ ! -d "$BINDIR" ]; then sudo mkdir -p "$BINDIR"; fi 76 | sudo install -g root -o root -m 755 $TMP/$file $BINDIR/opam 77 | else 78 | install -m 755 $TMP/$file $BINDIR/opam 79 | fi 80 | rm -f $TMP/$file 81 | 82 | OPAM=$(which opam || echo "$BINDIR/opam") 83 | if [ "$OPAM" != "$BINDIR/opam" ]; then 84 | echo "WARNING: you have a different version of opam installed at $OPAM" 85 | echo "It is highly recommended that you remove it." 86 | read -p "[press enter to continue]" x 87 | OPAM="$BINDIR/opam" 88 | fi 89 | 90 | if [ "$(id -u)" = "0" ]; then 91 | echo "Running as super-user: not running opam initialization." 92 | echo "You'll want to run \"$OPAM init --comp $COMP\" as user" 93 | else 94 | echo "Initializing with compiler $COMP" 95 | "$OPAM" init --comp "$COMP" 96 | fi 97 | 98 | echo "Installation done. If you need to uninstall, simply remove $BINDIR/opam" 99 | echo "and ~/.opam" 100 | -------------------------------------------------------------------------------- /src/state/opamFileTools.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2016 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Tools for manipulating and checking package definition ("opam") files *) 13 | 14 | open OpamTypes 15 | 16 | (** Create an OPAM package template filled with common options *) 17 | val template: package -> OpamFile.OPAM.t 18 | 19 | (** Runs several sanity checks on the opam file; returns a list of warnings. 20 | [`Error] level should be considered unfit for publication, while 21 | [`Warning] are advisory but may be accepted. The int is an identifier for 22 | this specific warning/error. *) 23 | val lint: OpamFile.OPAM.t -> (int * [`Warning|`Error] * string) list 24 | 25 | (** Same as [lint], but operates on a file, which allows catching parse 26 | errors too. You can specify an expected name and version *) 27 | val lint_file: OpamFile.OPAM.t OpamFile.typed_file -> 28 | (int * [`Warning|`Error] * string) list * OpamFile.OPAM.t option 29 | 30 | (** Same as [lint_file], but taking input from a channel *) 31 | val lint_channel: OpamFile.OPAM.t OpamFile.typed_file -> in_channel -> 32 | (int * [`Warning|`Error] * string) list * OpamFile.OPAM.t option 33 | 34 | (** Like [lint_file], but takes the file contents as a string *) 35 | val lint_string: OpamFile.OPAM.t OpamFile.typed_file -> string -> 36 | (int * [`Warning|`Error] * string) list * OpamFile.OPAM.t option 37 | 38 | (** Utility function to print validation results *) 39 | val warns_to_string: (int * [`Warning|`Error] * string) list -> string 40 | 41 | (** Read the opam metadata from a given directory (opam file, with possible 42 | overrides from url and descr files). Also includes the names and hashes 43 | of files below files/ *) 44 | val read_opam: dirname -> OpamFile.OPAM.t option 45 | 46 | (** Adds (or overrides) data from 'url' and 'descr' files found in the specified 47 | dir or the opam file's metadata dir. if [files_subdir_hashes] is [true], 48 | also adds the names and hashes of files found below 'files/' *) 49 | val add_aux_files: 50 | ?dir:dirname -> files_subdir_hashes:bool -> OpamFile.OPAM.t -> OpamFile.OPAM.t 51 | 52 | (** {2 Tools to manipulate the [OpamFile.OPAM.t] contents} *) 53 | val map_all_variables: 54 | (full_variable -> full_variable) -> OpamFile.OPAM.t -> OpamFile.OPAM.t 55 | -------------------------------------------------------------------------------- /src/state/opamRepositoryState.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** loading and handling of the repository state of an opam root (i.e. what is 13 | in ~/.opam/repo) *) 14 | 15 | open OpamTypes 16 | 17 | open OpamStateTypes 18 | 19 | (** Caching of repository loading (marshall of all parsed opam files) *) 20 | module Cache: sig 21 | val save: [< rw] repos_state -> unit 22 | val load: 23 | dirname -> 24 | (OpamFile.Repo.t repository_name_map * 25 | OpamFile.OPAM.t package_map repository_name_map) 26 | option 27 | val remove: unit -> unit 28 | end 29 | 30 | val load: 'a lock -> [< unlocked ] global_state -> 'a repos_state 31 | 32 | (** Loads the repository state as [load], and calls the given function while 33 | keeping it locked (as per the [lock] argument), releasing the lock 34 | afterwards *) 35 | val with_: 36 | 'a lock -> [< unlocked ] global_state -> ('a repos_state -> 'b) -> 'b 37 | 38 | (** Returns the repo of origin and metadata corresponding to a package, if 39 | found, from a sorted list of repositories (highest priority first) *) 40 | val find_package_opt: 'a repos_state -> repository_name list -> package -> 41 | (repository_name * OpamFile.OPAM.t) option 42 | 43 | (** Given the repos state, and a list of repos to use (highest priority first), 44 | build a map of all existing package definitions *) 45 | val build_index: 46 | 'a repos_state -> repository_name list -> OpamFile.OPAM.t OpamPackage.Map.t 47 | 48 | (** Finds a package repository definition from its name (assuming it's in 49 | ROOT/repos/) *) 50 | val get_repo: 'a repos_state -> repository_name -> repository 51 | 52 | (** Load all the metadata within the local mirror of the given repository, 53 | without cache *) 54 | val load_repo_opams: repository -> OpamFile.OPAM.t OpamPackage.Map.t 55 | 56 | (** Releases any locks on the given repos_state *) 57 | val unlock: 'a repos_state -> unlocked repos_state 58 | 59 | (** Calls the provided function, ensuring a temporary write lock on the given 60 | repository state*) 61 | val with_write_lock: 62 | ?dontblock:bool -> 'a repos_state -> (rw repos_state -> 'b * rw repos_state) -> 63 | 'b * 'a repos_state 64 | 65 | (** Writes the repositories config file back to disk *) 66 | val write_config: rw repos_state -> unit 67 | -------------------------------------------------------------------------------- /tests/init-repo.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | TEST_DIR=/tmp 4 | OPAM_ROOT=$TEST_DIR/OPAM.ROOT 5 | OPAM_REPO=$TEST_DIR/OPAM.REPO 6 | BIN=$TEST_DIR/OPAM.BIN 7 | REPO=test 8 | 9 | BINARIES=opam 10 | 11 | # opam in the path should not be a requirement 12 | ENV="OCAMLRUNPARAM=b OPAMDEBUG=2 OPAM_ROOT=$OPAM_ROOT PATH=$BIN:$PATH" 13 | ENV="OCAMLRUNPARAM=b OPAM_ROOT=$OPAM_ROOT PATH=$BIN:$PATH" 14 | OPAM="$ENV opam --yes --root $OPAM_ROOT" 15 | 16 | function binaries() { 17 | mkdir -p $BIN 18 | for bin in $BINARIES; do \ 19 | cp ../_obuild/$bin/$bin.asm $BIN/$bin ; \ 20 | done 21 | } 22 | 23 | function opam_clean() { 24 | rm -rf $ARCHIVES 25 | rm -rf $OPAM_ROOT $BIN 26 | rm -rf $OPAM_REPO 27 | } 28 | 29 | function opam_init() { 30 | mkdir -p $OPAM_REPO 31 | binaries 32 | eval $OPAM init -no-base-packages $REPO $OPAM_REPO -kind rsync 33 | } 34 | 35 | function opam_upload_stage1() { 36 | 37 | cd packages 38 | eval $OPAM upload -opam P1-1.opam -descr P1-1/README -archive P1-1.tar.gz -repo $REPO 39 | eval $OPAM upload -opam P2.opam -descr P2/README -archive P2.tar.gz -repo $REPO 40 | eval $OPAM upload -opam P3.opam -descr P3/README -archive P3.tar.gz -repo $REPO 41 | eval $OPAM upload -opam P4-1.opam -descr P4/README -archive P4.tar.gz -repo $REPO 42 | eval $OPAM upload -opam P5.opam -descr P5/README -archive P5.tar.gz -repo $REPO 43 | cd - 44 | 45 | cp compilers/* $OPAM_REPO/compilers/ 46 | # update the list of available packages with the one being updated 47 | eval $OPAM update 48 | } 49 | 50 | function opam_upload_stage2() { 51 | 52 | cd packages 53 | eval $OPAM upload -opam P1-2.opam -descr P1-2/README -archive P1-2.tar.gz -repo $REPO 54 | eval $OPAM upload -opam P4-2.opam -descr P4/README -archive P4.tar.gz -repo $REPO 55 | eval $OPAM upload -opam P4-3.opam -descr P4/README -archive P4.tar.gz -repo $REPO 56 | cd - 57 | 58 | # update the list of available packages with the one being updated 59 | eval $OPAM update 60 | } 61 | function usage() { 62 | DESCRIPTION="Opam unittest init functions" 63 | cat << EOF 64 | usage: $0 options 65 | 66 | $DESCRIPTION 67 | 68 | OPTIONS: 69 | -h Show this message 70 | -v Verbose 71 | -d Debug 72 | -i Init 73 | -c Clean 74 | EOF 75 | } 76 | 77 | VERBOSE= 78 | DEBUG= 79 | INIT= 80 | CLEAN= 81 | STAGE= 82 | 83 | while getopts "vhdcis:" flag 84 | do 85 | case "$flag" in 86 | d) set -x ; DEBUG=true;; 87 | v) VERBOSE=true ;; 88 | i) INIT=true ;; 89 | s) STAGE=$OPTARG ;; 90 | c) CLEAN=true ;; 91 | h) usage ; exit 0 ;; 92 | esac 93 | # echo "$flag" $OPTIND $OPTARG 94 | done 95 | 96 | if [ -n "$INIT" ]; then 97 | opam_clean 98 | opam_init 99 | fi 100 | 101 | if [ -n "$STAGE" ]; then 102 | if [ $STAGE = "1" ]; then 103 | opam_upload_stage1 104 | fi 105 | 106 | if [ $STAGE = "2" ]; then 107 | opam_upload_stage2 108 | fi 109 | fi 110 | 111 | if [ -n "$CLEAN" ]; then 112 | opam_clean 113 | fi 114 | 115 | exit 0 116 | 117 | 118 | -------------------------------------------------------------------------------- /src/state/opamPinned.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | open OpamTypes 13 | open OpamStateTypes 14 | open OpamFilename.Op 15 | 16 | let package st name = OpamPackage.package_of_name st.pinned name 17 | 18 | let package_opt st name = try Some (package st name) with Not_found -> None 19 | 20 | let version st name = (package st name).version 21 | 22 | let packages st = st.pinned 23 | 24 | let possible_definition_filenames dir name = [ 25 | dir / (OpamPackage.Name.to_string name ^ ".opam") // "opam"; 26 | dir // (OpamPackage.Name.to_string name ^ ".opam"); 27 | dir / "opam" // "opam"; 28 | dir // "opam" 29 | ] 30 | 31 | let find_opam_file_in_source name dir = 32 | OpamStd.Option.map OpamFile.make 33 | (OpamStd.List.find_opt OpamFilename.exists 34 | (possible_definition_filenames dir name)) 35 | 36 | let files_in_source d = 37 | let baseopam = OpamFilename.Base.of_string "opam" in 38 | let files = 39 | List.filter (fun f -> 40 | OpamFilename.basename f = baseopam || 41 | OpamFilename.check_suffix f ".opam") 42 | (OpamFilename.files d) @ 43 | OpamStd.List.filter_map (fun d -> 44 | if OpamFilename.(basename_dir d = Base.of_string "opam") || 45 | OpamStd.String.ends_with ~suffix:".opam" 46 | (OpamFilename.Dir.to_string d) 47 | then OpamFilename.opt_file OpamFilename.Op.(d//"opam") 48 | else None) 49 | (OpamFilename.dirs d) 50 | in 51 | List.map 52 | (fun f -> 53 | let name = 54 | let b = 55 | if OpamFilename.(basename f = baseopam) then 56 | OpamFilename.(Base.to_string (basename_dir (dirname f))) 57 | else 58 | OpamFilename.(Base.to_string (basename f)) 59 | in 60 | if b = "opam" then None else 61 | try 62 | Some (OpamPackage.Name.of_string 63 | (OpamStd.String.remove_suffix ~suffix:".opam" b)) 64 | with Failure _ -> None 65 | in 66 | name, OpamFile.make f) 67 | files 68 | 69 | let orig_opam_file opam = 70 | let open OpamStd.Option.Op in 71 | OpamFile.OPAM.metadata_dir opam >>= fun dir -> 72 | OpamStd.List.find_opt OpamFilename.exists [ 73 | dir // (OpamPackage.Name.to_string (OpamFile.OPAM.name opam) ^ ".opam"); 74 | dir // "opam" 75 | ] >>| 76 | OpamFile.make 77 | -------------------------------------------------------------------------------- /admin-scripts/depopts_to_conflicts.ml: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env opam-admin.top 2 | 3 | #directory "+../opam-lib";; 4 | open Opam_admin_top;; 5 | 6 | let contains_neq f = 7 | try 8 | OpamFormula.iter (function (_,cs) -> 9 | OpamFormula.iter (function (`Neq,_) -> raise Exit | _ -> ()) cs) 10 | f; 11 | false 12 | with Exit -> true 13 | ;; 14 | 15 | iter_packages ~opam:(fun _ opam -> 16 | let depopts = 17 | let formula = OpamFile.OPAM.depopts opam in 18 | let atoms = 19 | OpamFormula.fold_left 20 | (fun acc (n,(flags,_)) -> 21 | OpamFormula.Atom (n, (flags, OpamFormula.Empty)) :: acc) 22 | [] formula 23 | in 24 | OpamFormula.ors @@ 25 | OpamStd.List.remove_duplicates @@ 26 | List.rev atoms 27 | in 28 | let conflicts = (* add complement of the depopts as conflicts *) 29 | let module NM = OpamPackage.Name.Map in 30 | let depopts = (* get back a map (name => version_constraint) *) 31 | (* XXX this takes _all_ the atoms not considering con/disjunctions *) 32 | OpamFormula.fold_left (fun acc (name,(_,f)) -> 33 | try 34 | NM.add name ((OpamFormula.ors [f; NM.find name acc])) acc 35 | with Not_found -> NM.add name f acc) 36 | NM.empty 37 | (OpamFile.OPAM.depopts opam) in 38 | let neg_depopts = 39 | NM.fold (fun name f acc -> 40 | if f = OpamFormula.Empty then acc else 41 | let f = OpamFormula.(neg (fun (op,v) -> neg_relop op, v) f) in 42 | match OpamFormula.to_cnf (OpamFormula.Atom (name,f)) with 43 | | [] -> acc 44 | | [conj] -> conj @ acc 45 | | [x;y] when x = y -> x @ acc 46 | | cnf -> 47 | (* Formula is not a conjunction, we are left with no choice 48 | but to enumerate *) 49 | let f = 50 | OpamFormula.to_atom_formula @@ OpamFormula.ands @@ 51 | List.map OpamFormula.of_disjunction cnf in 52 | let conflict_packages = 53 | OpamPackage.Set.filter 54 | (fun pkg -> 55 | OpamFormula.eval (fun atom -> OpamFormula.check atom pkg) f) 56 | (OpamPackage.packages_of_name packages name) 57 | in 58 | OpamPackage.Set.fold (fun nv acc -> 59 | (OpamPackage.name nv, Some (`Eq, OpamPackage.version nv)) 60 | :: acc) 61 | conflict_packages acc) 62 | depopts [] in 63 | let conflicts = OpamFile.OPAM.conflicts opam in 64 | let add_conflicts = 65 | let c = OpamFormula.to_disjunction conflicts in 66 | List.filter (fun f -> not (List.mem f c)) neg_depopts in 67 | OpamFormula.ors (conflicts :: [OpamFormula.of_disjunction add_conflicts]) 68 | in 69 | let opam = OpamFile.OPAM.with_depopts opam depopts in 70 | let opam = OpamFile.OPAM.with_conflicts opam conflicts in 71 | let opam = 72 | if contains_neq conflicts then 73 | OpamFile.OPAM.with_opam_version opam (OpamVersion.of_string "1.2") 74 | else opam 75 | in 76 | opam) 77 | () 78 | ;; 79 | -------------------------------------------------------------------------------- /src/core/opamUrl.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** URL parsing and printing, with support for our different backends *) 13 | 14 | type version_control = [ `git | `darcs | `hg ] 15 | 16 | type backend = [ `http | `rsync | version_control ] 17 | 18 | val string_of_backend: backend -> string 19 | 20 | (** Tolerates lots of backward compatibility names; 21 | @raise Failure on unknown protocol *) 22 | val backend_of_string: string -> [> backend] 23 | 24 | type t = { 25 | transport: string; (** the part just before '://' *) 26 | path: string; (** the part after '://' *) 27 | hash: string option; (** the optional branch/ref specification, 28 | at the end after a '#' *) 29 | backend: backend; (** the backend that opam should use to handle this 30 | url *) 31 | } 32 | 33 | (** Same as [of_string], but allows enforcing the expected backend, and may 34 | otherwise guess version control from the suffix by default (for e.g. 35 | https://foo/bar.git) (this should be disabled when parsing from files) *) 36 | val parse: ?backend:backend -> ?handle_suffix:bool -> string -> t 37 | 38 | include OpamStd.ABSTRACT with type t := t 39 | 40 | (** Dummy filler url *) 41 | val empty: t 42 | 43 | (** Returns the url string without the VC part (i.e. "git+foo://bar" returns 44 | "foo://bar") *) 45 | val base_url: t -> string 46 | 47 | (** The last part of the url path, e.g. ["http://foo/bar/this"] or 48 | ["http://that.here/"] *) 49 | val basename: t -> string 50 | 51 | (** Returns the url with all path components but the first one (the hostname) 52 | dropped, e.g. ["http://some.host/some/path"] becomes ["http://some.host"] *) 53 | val root: t -> t 54 | 55 | val has_trailing_slash: t -> bool 56 | 57 | (** Check if the URL matches an existing local directory, and return it *) 58 | val local_dir: t -> OpamFilename.Dir.t option 59 | 60 | (** Check if the URL matches an existing local file, and return it *) 61 | val local_file: t -> OpamFilename.t option 62 | 63 | (** If the given url-string has no 'transport://' specification and corresponds 64 | to an existing local path, check for version-control clues at that path *) 65 | val guess_version_control: string -> [> version_control ] option 66 | 67 | module Op: sig 68 | 69 | (** Appends at the end of an URL path with '/' separator. Gets back to the 70 | root if the second argument starts with '/' *) 71 | val ( / ) : t -> string -> t 72 | 73 | end 74 | -------------------------------------------------------------------------------- /src/format/opamTypesBase.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Helper functions on the base types (from [OpamTypes]) *) 13 | 14 | (** This module contains basic utility functions and stringifiers for the 15 | basic OPAM types present in OpamTypes.ml *) 16 | open OpamTypes 17 | 18 | include module type of OpamCompat 19 | 20 | val string_of_std_path: std_path -> string 21 | val std_path_of_string: string -> std_path 22 | val all_std_paths: std_path list 23 | 24 | (** Extract a package from a package action. *) 25 | val action_contents: [< 'a action ] -> 'a 26 | 27 | val map_atomic_action: ('a -> 'b) -> 'a atomic_action -> 'b atomic_action 28 | val map_highlevel_action: ('a -> 'b) -> 'a highlevel_action -> 'b highlevel_action 29 | val map_concrete_action: ('a -> 'b) -> 'a concrete_action -> 'b concrete_action 30 | val map_action: ('a -> 'b) -> 'a action -> 'b action 31 | 32 | (** Extract a packages from a package action. This returns all concerned 33 | packages, including the old version for an up/down-grade. *) 34 | val full_action_contents: 'a action -> 'a list 35 | 36 | (** Pretty-prints the cause of an action *) 37 | val string_of_cause: ('pkg -> string) -> 'pkg cause -> string 38 | 39 | (** Pretty-print *) 40 | val string_of_shell: shell -> string 41 | 42 | (** The empty file position *) 43 | val pos_null: pos 44 | 45 | (** [pos_best pos1 pos2] returns the most detailed position between [pos1] and 46 | [pos2] (defaulting to [pos1]) *) 47 | val pos_best: pos -> pos -> pos 48 | 49 | (** Position in the given file, with unspecified line and column *) 50 | val pos_file: filename -> pos 51 | 52 | (** Prints a file position *) 53 | val string_of_pos: pos -> string 54 | 55 | (** Makes sure to keep only the last binding for a given variable; doesn't 56 | preserve order *) 57 | val env_array: env -> string array 58 | 59 | (** Parses the data suitable for a filter.FIdent from a string. May raise 60 | [Failure msg] on bad package names. A self-reference [_] parses to [None] *) 61 | val filter_ident_of_string: 62 | string -> name option list * variable * (string * string) option 63 | 64 | val string_of_filter_ident: 65 | name option list * variable * (string * string) option -> string 66 | 67 | val pkg_flag_of_string: string -> package_flag 68 | 69 | val string_of_pkg_flag: package_flag -> string 70 | 71 | val all_package_flags: package_flag list 72 | 73 | (** Map on a solver result *) 74 | val map_success: ('a -> 'b) -> ('a,'fail) result -> ('b,'fail) result 75 | -------------------------------------------------------------------------------- /src/core/opamCoreConfig.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | open OpamCompat 12 | 13 | type t = { 14 | debug_level: int; 15 | verbose_level: int; 16 | color: [ `Always | `Never | `Auto ]; 17 | utf8: [ `Extended | `Always | `Never | `Auto ]; 18 | disp_status_line: [ `Always | `Never | `Auto ]; 19 | answer: bool option; 20 | safe_mode: bool; 21 | log_dir: string; 22 | keep_log_dir: bool; 23 | errlog_length: int; 24 | merged_output: bool; 25 | use_openssl: bool; 26 | } 27 | 28 | type 'a options_fun = 29 | ?debug_level:int -> 30 | ?verbose_level:int -> 31 | ?color:[ `Always | `Never | `Auto ] -> 32 | ?utf8:[ `Extended | `Always | `Never | `Auto ] -> 33 | ?disp_status_line:[ `Always | `Never | `Auto ] -> 34 | ?answer:bool option -> 35 | ?safe_mode:bool -> 36 | ?log_dir:string -> 37 | ?keep_log_dir:bool -> 38 | ?errlog_length:int -> 39 | ?merged_output:bool -> 40 | ?use_openssl:bool -> 41 | 'a 42 | 43 | let default = { 44 | debug_level = 0; 45 | verbose_level = 0; 46 | color = `Auto; 47 | utf8 = `Auto; 48 | disp_status_line = `Auto; 49 | answer = None; 50 | safe_mode = false; 51 | log_dir = 52 | (let user = try Unix.getlogin() with Unix.Unix_error _ -> "xxx" in 53 | let base = Printf.sprintf "opam-%s-%d" user (Unix.getpid()) in 54 | Filename.(concat (get_temp_dir_name ()) base)); 55 | keep_log_dir = false; 56 | errlog_length = 12; 57 | merged_output = true; 58 | use_openssl = true; 59 | } 60 | 61 | let setk k t 62 | ?debug_level 63 | ?verbose_level 64 | ?color 65 | ?utf8 66 | ?disp_status_line 67 | ?answer 68 | ?safe_mode 69 | ?log_dir 70 | ?keep_log_dir 71 | ?errlog_length 72 | ?merged_output 73 | ?use_openssl 74 | = 75 | let (+) x opt = match opt with Some x -> x | None -> x in 76 | k { 77 | debug_level = t.debug_level + debug_level; 78 | verbose_level = t.verbose_level + verbose_level; 79 | color = t.color + color; 80 | utf8 = t.utf8 + utf8; 81 | disp_status_line = t.disp_status_line + disp_status_line; 82 | answer = t.answer + answer; 83 | safe_mode = t.safe_mode + safe_mode; 84 | log_dir = t.log_dir + log_dir; 85 | keep_log_dir = t.keep_log_dir + keep_log_dir; 86 | errlog_length = t.errlog_length + errlog_length; 87 | merged_output = t.merged_output + merged_output; 88 | use_openssl = t.use_openssl + use_openssl 89 | } 90 | 91 | let set t = setk (fun x () -> x) t 92 | 93 | (* Global configuration reference *) 94 | 95 | let r = ref default 96 | 97 | let update ?noop:_ = setk (fun cfg () -> r := cfg) !r 98 | -------------------------------------------------------------------------------- /src/repository/opamVCS.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Layer for handling version control sources through a functor *) 13 | 14 | open OpamTypes 15 | 16 | (** Each backend should implement this signature. *) 17 | module type VCS = sig 18 | 19 | val name: OpamUrl.backend 20 | 21 | (** Test whether the given repository is correctly initialized. *) 22 | val exists: dirname -> bool 23 | 24 | (** Init a repository. *) 25 | val init: dirname -> url -> unit OpamProcess.job 26 | 27 | (** Fetch changes from upstream. This is supposed to put the changes 28 | in a staging area. 29 | Be aware that the remote URL might have been changed, so make sure 30 | to update accordingly. *) 31 | val fetch: dirname -> url -> unit OpamProcess.job 32 | 33 | (** Reset the master branch of the repository to match the remote repository 34 | state. This might still fetch more data (git submodules...), so is 35 | unsuitable for running after validation. *) 36 | val reset: dirname -> url -> unit OpamProcess.job 37 | 38 | (** Returns the pending modifications in the form of a patch file, or None if 39 | [dirname] is up to date with what was last fetched. *) 40 | val diff: dirname -> url -> filename option OpamProcess.job 41 | 42 | (** Returns true if the last fetched state is equal to the current, on-disk 43 | state *) 44 | val is_up_to_date: dirname -> url -> bool OpamProcess.job 45 | 46 | (** Returns an backend-specific identifier for the current revision. *) 47 | val revision: dirname -> string option OpamProcess.job 48 | 49 | (** Returns the list of files under version control *) 50 | val versionned_files: dirname -> string list OpamProcess.job 51 | 52 | (** Returns the absolute directory name for vc data (e.g. 53 | [.../project/.git]) *) 54 | val vc_dir: dirname -> dirname 55 | 56 | (** Returns the currently selected branch handle. It should be valid as the 57 | [hash] field of [OpamUrl.t]. *) 58 | val current_branch: dirname -> string option OpamProcess.job 59 | 60 | (** Returns true if the working tree state is different from the state 61 | recorded in the VCS as current. This differs from [is_up_to_date], which 62 | compares specifically to the last fetched state. This should always be 63 | [false] after [reset] has been called. *) 64 | val is_dirty: dirname -> bool OpamProcess.job 65 | end 66 | 67 | (** Create a backend from a [VCS] implementation. *) 68 | module Make(VCS: VCS): OpamRepositoryBackend.S 69 | -------------------------------------------------------------------------------- /src/client/opamAction.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Handles concrete actions on packages, like installations and removals *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** [download t pkg] downloads the source of the package [pkg] into its locally 18 | cached source dir. Returns [Some errmsg] on error, [None] on success. 19 | 20 | This doesn't update dev packages that already have a locally cached 21 | source. *) 22 | val download_package: 23 | rw switch_state -> package -> string option OpamProcess.job 24 | 25 | (** [prepare_package_source t pkg dir] updates the given source [dir] with the 26 | extra downloads, overlays and patches from the package's metadata 27 | applied. *) 28 | val prepare_package_source: 29 | rw switch_state -> package -> dirname -> exn option OpamProcess.job 30 | 31 | (** [build_package t build_dir pkg] builds the package [pkg] within [build_dir]. 32 | Returns [None] on success, [Some exn] on error. 33 | See {!download_package} and {!prepare_package_source} for the previous 34 | steps. *) 35 | val build_package: 36 | rw switch_state -> ?test:bool -> ?doc:bool -> dirname -> package -> 37 | exn option OpamProcess.job 38 | 39 | (** [install_package t pkg] installs an already built package. Returns 40 | [None] on success, [Some exn] on error. Do not update OPAM's 41 | metadata. See {!build_package} to build the package. *) 42 | val install_package: 43 | rw switch_state -> ?doc:bool -> ?build_dir:dirname -> package -> 44 | exn option OpamProcess.job 45 | 46 | (** Find out if the package source is needed for uninstall *) 47 | val removal_needs_download: 'a switch_state -> package -> bool 48 | 49 | (** Removes a package. If [changes] is unspecified, it is read from the 50 | package's change file. if [force] is specified, remove files marked as added 51 | in [changes] even if the files have been modified since. *) 52 | val remove_package: 53 | rw switch_state -> ?silent:bool -> 54 | ?changes:OpamDirTrack.t -> ?force:bool -> 55 | package -> unit OpamProcess.job 56 | 57 | (** Returns [true] whenever [remove_package] is a no-op. *) 58 | val noop_remove_package: 59 | rw switch_state -> package -> bool 60 | 61 | (** Removes auxiliary files related to a package, after checking that 62 | they're not needed *) 63 | val cleanup_package_artefacts: rw switch_state -> package -> unit 64 | 65 | (** Compute the set of packages which will need to be downloaded to apply a 66 | solution. Takes a graph of atomic actions. *) 67 | val sources_needed: 'a switch_state -> OpamSolver.ActionGraph.t -> package_set 68 | -------------------------------------------------------------------------------- /src/repository/opamRepository.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Operations on repositories (update, fetch...) based on the different 13 | backends implemented in separate modules *) 14 | 15 | open OpamTypes 16 | 17 | (** Get the list of packages *) 18 | val packages: repository -> package_set 19 | 20 | (** Get the list of packages (and their possible prefix) *) 21 | val packages_with_prefixes: repository -> string option package_map 22 | 23 | (** {2 Repository backends} *) 24 | 25 | (** Initialize {i $opam/repo/$repo} *) 26 | val init: dirname -> repository_name -> unit OpamProcess.job 27 | 28 | (** Update {i $opam/repo/$repo}. Raises [Failure] in case the update couldn't be 29 | achieved. *) 30 | val update: repository -> unit OpamProcess.job 31 | 32 | (** Fetch an URL and put the resulting tree into the supplied directory. The URL 33 | must either point to a tree (VCS, rsync) or to a known archive type. In case 34 | of an archive, the cache is used and supplied the hashes verified, then the 35 | archive uncompressed. In case of a version-controlled URL, it's checked out, 36 | or synchronised directly if local and [working_dir] was set. *) 37 | val pull_tree: 38 | string -> ?cache_dir:dirname -> ?cache_urls:url list -> ?working_dir:bool -> 39 | dirname -> OpamHash.t list -> url list -> 40 | unit download OpamProcess.job 41 | 42 | (** Same as [pull_url], but for fetching a single file. *) 43 | val pull_file: 44 | string -> ?cache_dir:dirname -> ?cache_urls:url list -> ?silent_hits:bool -> 45 | filename -> OpamHash.t list -> url list -> 46 | unit download OpamProcess.job 47 | 48 | (** Same as [pull_file], but without a destination file: just ensures the file 49 | is present in the cache. *) 50 | val pull_file_to_cache: 51 | string -> cache_dir:dirname -> ?cache_urls:url list -> 52 | OpamHash.t list -> url list -> unit download OpamProcess.job 53 | 54 | (** Get the optional revision associated to a backend (git hash, etc.). *) 55 | val revision: dirname -> url -> version option OpamProcess.job 56 | 57 | (** Get the version-control branch for that url. Only applicable for local, 58 | version controlled URLs. Returns [None] in other cases. *) 59 | val current_branch: url -> string option OpamProcess.job 60 | 61 | (** Returns true if the url points to a local, version-controlled directory that 62 | has uncommitted changes *) 63 | val is_dirty: url -> bool OpamProcess.job 64 | 65 | (** Find a backend *) 66 | val find_backend: repository -> (module OpamRepositoryBackend.S) 67 | val find_backend_by_kind: OpamUrl.backend -> (module OpamRepositoryBackend.S) 68 | -------------------------------------------------------------------------------- /.travis-ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -xue 2 | 3 | OPAMBSVERSION=1.2.2 4 | OPAMBSROOT=$HOME/.opam.bootstrap 5 | PATH=~/local/bin:$PATH; export PATH 6 | 7 | TARGET="$1"; shift 8 | 9 | # Install the build requirements into $OPAMBSROOT using the opam binary from the 10 | # prepare step 11 | install-bootstrap () { 12 | opam init --root=$OPAMBSROOT --yes --no-setup --compiler=$OCAML_VERSION 13 | eval $(opam config env --root=$OPAMBSROOT) 14 | if [ "$OPAM_TEST" = "1" ]; then 15 | opam install ocamlfind lwt.2.5.2 cohttp.0.20.2 ssl cmdliner dose3 jsonm opam-file-format --yes 16 | # Allow use of ocamlfind packages in ~/local/lib 17 | FINDCONF=$(ocamlfind printconf conf) 18 | sed "s%^path=.*%path=\"$HOME/local/lib:$(opam config var lib)\"%" $FINDCONF >$FINDCONF.1 19 | mv $FINDCONF.1 $FINDCONF 20 | else 21 | opam install ocamlbuild --yes 22 | fi 23 | rm -f "$OPAMBSROOT"/log/* 24 | } 25 | 26 | case "$TARGET" in 27 | prepare) 28 | mkdir -p ~/local/bin 29 | wget -q -O ~/local/bin/opam \ 30 | "https://github.com/ocaml/opam/releases/download/$OPAMBSVERSION/opam-$OPAMBSVERSION-$(uname -m)-$(uname -s)" 31 | chmod a+x ~/local/bin/opam 32 | exit 0 33 | ;; 34 | install) 35 | # Note: this part is cached, and must be idempotent 36 | # Re-init opam from scratch if the install fails 37 | if [ -d $OPAMBSROOT ] 38 | then install-bootstrap || { rm -rf $OPAMBSROOT; install-bootstrap; } 39 | else install-bootstrap 40 | fi 41 | exit 0 42 | ;; 43 | build) 44 | ;; 45 | *) 46 | echo "bad command $TARGET"; exit 1 47 | esac 48 | 49 | export OPAMYES=1 50 | export OCAMLRUNPARAM=b 51 | 52 | # Git should be configured properly to run the tests 53 | git config --global user.email "travis@example.com" 54 | git config --global user.name "Travis CI" 55 | 56 | ( # Run subshell in bootstrap root env to build 57 | eval $(opam config env --root=$OPAMBSROOT) 58 | 59 | [ "$(ocaml -vnum)" = "$OCAML_VERSION" ] || exit 12 60 | 61 | ./configure --prefix ~/local 62 | 63 | if [ "$OPAM_TEST" != "1" ]; then make lib-ext; fi 64 | make all opam-check 65 | 66 | rm -f ~/local/bin/opam 67 | make install 68 | 69 | if [ "$OPAM_TEST" = "1" ]; then 70 | make libinstall LIBINSTALL_DIR=$HOME/local/lib 71 | # Compile and run opam-rt 72 | cd ~/build 73 | wget https://github.com/ocaml/opam-rt/archive/$TRAVIS_PULL_REQUEST_BRANCH.tar.gz -O opam-rt.tar.gz || \ 74 | wget https://github.com/ocaml/opam-rt/archive/master.tar.gz -O opam-rt.tar.gz 75 | tar xvfz opam-rt.tar.gz 76 | cd opam-rt-* 77 | make 78 | else 79 | # Note: these tests require a "system" compiler and will use the one in $OPAMBSROOT 80 | OPAMEXTERNALSOLVER="$EXTERNAL_SOLVER" make -C tests || (tail -2000 tests/fulltest-*.log; exit 1) 81 | fi 82 | ) 83 | 84 | ( # Finally run the tests, in a clean environment 85 | export OPAMKEEPLOGS=1 86 | 87 | if [ "$OPAM_TEST" = "1" ]; then 88 | cd ~/build/opam-rt-* 89 | OPAMEXTERNALSOLVER="$EXTERNAL_SOLVER" make KINDS="local git" run 90 | else 91 | # Test basic actions 92 | opam init 93 | eval $(opam config env) 94 | opam install lwt 95 | opam list 96 | opam config report 97 | fi 98 | ) 99 | -------------------------------------------------------------------------------- /src/state/opamPackageVar.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Resolution and handling of opam variables + filters *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** Lists of available switch-global variables and their description *) 18 | val global_variable_names: (string * string) list 19 | 20 | (** Lists of predefined package variables and their description *) 21 | val package_variable_names: (string * string) list 22 | 23 | (** Variables that are pre-defined in the dependency filtered-formula scope, and 24 | which resolution is delayed to after the universe is computed (these are the 25 | only ones allowed in the universe, and resolved by 26 | [OpamSolver.filter_deps]) *) 27 | val predefined_depends_variables: full_variable list 28 | 29 | (** Resolves globally available variables only *) 30 | val resolve_global: 'a global_state -> full_variable -> variable_contents option 31 | 32 | (** Resolves global variables within the context of a switch. If a package is 33 | specified, "name" and "version" as taken to exclusively resolve to the 34 | current package name and version. *) 35 | val resolve_switch: 36 | ?package:package -> 37 | 'a switch_state -> full_variable -> variable_contents option 38 | 39 | (** Resolves filter variables, including global, switch and package variables ; 40 | a map of locally defined variables can be supplied, as well as the opam file 41 | of origin, which is used to resolve self-references (implicit ["%{bin}%"] or 42 | explicit ["%{_:bin}%"] *) 43 | val resolve: 44 | 'a switch_state -> ?opam:OpamFile.OPAM.t -> 45 | ?local:OpamVariable.variable_contents option OpamVariable.Map.t -> 46 | OpamFilter.env 47 | 48 | (** Like [resolve_switch], but takes more specific parameters so that it can be 49 | used before the switch state is fully loaded *) 50 | val resolve_switch_raw: 51 | ?package:package -> 52 | 'a global_state -> switch -> OpamFile.Switch_config.t -> full_variable -> 53 | variable_contents option 54 | 55 | val is_dev_package: 'a switch_state -> OpamFile.OPAM.t -> bool 56 | 57 | (** The defaults are [true] for [build], false for [dev] and defined by 58 | OpamStateConfig for [test] and [bool]. *) 59 | val filter_depends_formula: 60 | ?build:bool -> ?test:bool -> ?doc:bool -> ?dev:bool -> ?default:bool -> 61 | env:OpamFilter.env -> 62 | filtered_formula -> formula 63 | 64 | (** Assumes [filter_default=false] by default, i.e. dependencies with undefined 65 | filters are discarded. *) 66 | val all_depends: 67 | ?build:bool -> ?test:bool -> ?doc:bool -> ?dev:bool -> ?filter_default:bool -> 68 | ?depopts:bool -> 69 | 'a switch_state -> OpamFile.OPAM.t -> formula 70 | -------------------------------------------------------------------------------- /src/client/opamSwitchCommand.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Functions handling the "opam switch" subcommand *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** Install a new switch, with the given packages set as compiler. The given 18 | [global_state] is unlocked as soon as possible, i.e. after registering the 19 | existence of the new switch. [update_config] sets the switch as current 20 | globally, unless it is external *) 21 | val install: 22 | rw global_state -> 23 | ?rt:'a repos_state -> 24 | ?synopsis:string -> 25 | ?repos:repository_name list -> 26 | update_config:bool -> 27 | packages:atom conjunction -> switch -> 28 | unlocked global_state * rw switch_state 29 | 30 | (** Install a compiler's base packages *) 31 | val install_compiler_packages: 32 | rw switch_state -> atom conjunction -> rw switch_state 33 | 34 | (** Import a file which contains the packages to install. *) 35 | val import: 36 | rw switch_state -> 37 | OpamFile.SwitchExport.t OpamFile.t option -> 38 | rw switch_state 39 | 40 | (** Export a file which contains the installed packages. If full is specified 41 | and true, export metadata of all installed packages (excluding overlay 42 | files) as part of the export. [None] means export to stdout. *) 43 | val export: ?full:bool -> OpamFile.SwitchExport.t OpamFile.t option -> unit 44 | 45 | (** Remove the given compiler switch, and returns the updated state (unchanged 46 | in case [confirm] is [true] and the user didn't confirm) *) 47 | val remove: rw global_state -> ?confirm:bool -> switch -> rw global_state 48 | 49 | (** Changes the currently active switch *) 50 | val switch: 'a lock -> rw global_state -> switch -> 'a switch_state 51 | 52 | (** Reinstall the given compiler switch. *) 53 | val reinstall: rw switch_state -> rw switch_state 54 | 55 | (** Sets the packages configured as the current switch compiler base *) 56 | val set_compiler: 57 | rw switch_state -> (name * version option) list -> rw switch_state 58 | 59 | (** Display the current compiler switch. *) 60 | val show: unit -> unit 61 | 62 | (** List all the available compiler switches. *) 63 | val list: 'a global_state -> print_short:bool -> unit 64 | 65 | (** Returns all available compiler packages from a repo state *) 66 | val get_compiler_packages: 67 | ?repos:repository_name list -> 'a repos_state -> package_set 68 | 69 | (** Guess the compiler from the switch name: within compiler packages, 70 | match [name] against "pkg.version", "pkg", and, as a last resort, 71 | "version" (for compat with older opams, eg. 'opam switch 4.02.3') *) 72 | val guess_compiler_package: 73 | ?repos:repository_name list -> 'a repos_state -> string -> atom list 74 | -------------------------------------------------------------------------------- /src/core/opamJson.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | include Jsonm 12 | 13 | (* String conversion *) 14 | exception Escape of ((int * int) * (int * int)) * error 15 | type t = 16 | [ `Null | `Bool of bool | `Float of float| `String of string 17 | | `A of t list | `O of (string * t) list ] 18 | 19 | let json_of_src ?encoding src = 20 | let dec d = match decode d with 21 | | `Lexeme l -> l 22 | | `Error e -> raise (Escape (decoded_range d, e)) 23 | | `End | `Await -> assert false 24 | in 25 | let rec value v k d = match v with 26 | | `Os -> obj [] k d | `As -> arr [] k d 27 | | `Null | `Bool _ | `String _ | `Float _ as v -> k v d 28 | | _ -> assert false 29 | and arr vs k d = match dec d with 30 | | `Ae -> k (`A (List.rev vs)) d 31 | | v -> value v (fun v -> arr (v :: vs) k) d 32 | and obj ms k d = match dec d with 33 | | `Oe -> k (`O (List.rev ms)) d 34 | | `Name n -> value (dec d) (fun v -> obj ((n, v) :: ms) k) d 35 | | _ -> assert false 36 | in 37 | let d = decoder ?encoding src in 38 | try `JSON (value (dec d) (fun v _ -> v) d) with 39 | | Escape (r, e) -> `Error (r, e) 40 | 41 | let of_string str: t = 42 | match json_of_src (`String str) with 43 | | `JSON j -> j 44 | | `Error _ -> failwith "json_of_string" 45 | 46 | let json_to_dst ~minify dst (json:t) = 47 | let enc e l = ignore (encode e (`Lexeme l)) in 48 | let rec value v k e = match v with 49 | | `A vs -> arr vs k e 50 | | `O ms -> obj ms k e 51 | | `Null | `Bool _ | `Float _ | `String _ as v -> enc e v; k e 52 | and arr vs k e = enc e `As; arr_vs vs k e 53 | and arr_vs vs k e = match vs with 54 | | v :: vs' -> value v (arr_vs vs' k) e 55 | | [] -> enc e `Ae; k e 56 | and obj ms k e = enc e `Os; obj_ms ms k e 57 | and obj_ms ms k e = match ms with 58 | | (n, v) :: ms -> enc e (`Name n); value v (obj_ms ms k) e 59 | | [] -> enc e `Oe; k e 60 | in 61 | let e = encoder ~minify dst in 62 | let finish e = ignore (encode e `End) in 63 | match json with 64 | | `A _ | `O _ as json -> value json finish e 65 | | _ -> invalid_arg "invalid json text" 66 | 67 | let to_string (json:t) = 68 | let buf = Buffer.create 1024 in 69 | json_to_dst ~minify:false (`Buffer buf) json; 70 | Buffer.contents buf 71 | 72 | let json_buffer = ref [] 73 | 74 | let append key json = 75 | json_buffer := (key,json) :: !json_buffer 76 | 77 | let flush oc = 78 | json_to_dst ~minify:false (`Channel oc) 79 | (`O (List.rev !json_buffer)) 80 | 81 | (*--------------------------------------------------------------------------- 82 | Copyright (c) 2012 Daniel C. Bünzli 83 | 84 | Permission to use, copy, modify, and/or distribute this software for any 85 | purpose with or without fee is hereby granted, provided that the above 86 | copyright notice and this permission notice appear in all copies. 87 | ---------------------------------------------------------------------------*) 88 | -------------------------------------------------------------------------------- /src/core/opamHash.ml: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2016 OCamlPro *) 4 | (* *) 5 | (* All rights reserved. This file is distributed under the terms of the *) 6 | (* GNU Lesser General Public License version 2.1, with the special *) 7 | (* exception on linking described in the file LICENSE. *) 8 | (* *) 9 | (**************************************************************************) 10 | 11 | open OpamCompat 12 | 13 | type kind = [ `MD5 | `SHA256 | `SHA512 ] 14 | 15 | let default_kind = `MD5 16 | 17 | type t = kind * string 18 | 19 | let kind = fst 20 | let contents = snd 21 | 22 | let pfx_sep_char = '=' 23 | let pfx_sep_str = String.make 1 pfx_sep_char 24 | 25 | let string_of_kind = function 26 | | `MD5 -> "md5" 27 | | `SHA256 -> "sha256" 28 | | `SHA512 -> "sha512" 29 | 30 | let kind_of_string s = match String.lowercase_ascii s with 31 | | "md5" -> `MD5 32 | | "sha256" -> `SHA256 33 | | "sha512" -> `SHA512 34 | | _ -> invalid_arg "OpamHash.kind_of_string" 35 | 36 | let is_hex_str len = 37 | Re.execp Re.(compile (repn xdigit len (Some len))) 38 | 39 | let len = function 40 | | `MD5 -> 32 41 | | `SHA256 -> 64 42 | | `SHA512 -> 128 43 | 44 | let valid kind = is_hex_str (len kind) 45 | 46 | let make kind s = 47 | if valid kind s then kind, String.lowercase_ascii s 48 | else invalid_arg ("OpamHash.make_"^string_of_kind kind) 49 | 50 | let md5 = make `MD5 51 | let sha256 = make `SHA256 52 | let sha512 = make `SHA512 53 | 54 | let of_string_opt s = 55 | try 56 | let kind, s = 57 | match OpamStd.String.cut_at s pfx_sep_char with 58 | | None -> `MD5, s 59 | | Some (skind, s) -> kind_of_string skind, s 60 | in 61 | if valid kind s then Some (kind, String.lowercase_ascii s) 62 | else None 63 | with Invalid_argument _ -> None 64 | 65 | let of_string s = 66 | match of_string_opt s with 67 | | Some h -> h 68 | | None -> invalid_arg "OpamHash.of_string" 69 | 70 | let to_string (kind,s) = 71 | String.concat pfx_sep_str [string_of_kind kind; s] 72 | 73 | let to_json s = `String (to_string s) 74 | 75 | let to_path (kind,s) = 76 | [string_of_kind kind; String.sub s 0 2; s] 77 | 78 | let compute ?(kind=default_kind) file = match kind with 79 | | `MD5 -> md5 (Digest.to_hex (Digest.file file)) 80 | | (`SHA256 | `SHA512) as kind -> 81 | try 82 | if not OpamCoreConfig.(!r.use_openssl) then raise Exit else 83 | match 84 | OpamSystem.read_command_output ["openssl"; string_of_kind kind; file] 85 | with 86 | | [l] -> 87 | let len = len kind in 88 | make kind (String.sub l (String.length l - len) len) 89 | | _ -> failwith "openssl error" 90 | with OpamSystem.Command_not_found _ | Exit -> 91 | make kind (OpamSHA.hash kind file) 92 | 93 | let check_file f (kind, _ as h) = compute ~kind f = h 94 | 95 | let mismatch f (kind, _ as h) = 96 | let hf = compute ~kind f in 97 | if hf = h then None else Some hf 98 | 99 | module O = struct 100 | type _t = t 101 | type t = _t 102 | let to_string = to_string 103 | let to_json = to_json 104 | let compare = compare 105 | end 106 | 107 | module Set = OpamStd.Set.Make(O) 108 | 109 | module Map = OpamStd.Map.Make(O) 110 | -------------------------------------------------------------------------------- /src/state/opamSwitchAction.mli: -------------------------------------------------------------------------------- 1 | (**************************************************************************) 2 | (* *) 3 | (* Copyright 2012-2015 OCamlPro *) 4 | (* Copyright 2012 INRIA *) 5 | (* *) 6 | (* All rights reserved. This file is distributed under the terms of the *) 7 | (* GNU Lesser General Public License version 2.1, with the special *) 8 | (* exception on linking described in the file LICENSE. *) 9 | (* *) 10 | (**************************************************************************) 11 | 12 | (** Switch-related actions and changes *) 13 | 14 | open OpamTypes 15 | open OpamStateTypes 16 | 17 | (** Initialises a new switch with the given name in the given opam root, 18 | registers it in the global config and returns the updated global state *) 19 | val create_empty_switch: 20 | rw global_state -> ?synopsis:string -> ?repos:repository_name list -> 21 | switch -> rw global_state 22 | 23 | (** Writes the current state file to disk (installed, pinned, root packages etc.). 24 | Unless [OpamStateConfig.(!r.dryrun)] *) 25 | val write_selections: rw switch_state -> unit 26 | 27 | (** Updates the defined default switch and loads its state; fails and exits with 28 | a message if the switch is external *) 29 | val set_current_switch: 30 | 'a lock -> rw global_state -> ?rt:'b repos_state -> switch -> 'a switch_state 31 | 32 | (** Create the default global_config structure for a switch, including default 33 | prefix *) 34 | val gen_switch_config: 35 | dirname -> ?synopsis:string -> ?repos:repository_name list -> 36 | switch -> OpamFile.Switch_config.t 37 | 38 | (** (Re-)install the configuration for a given root and switch *) 39 | val install_switch_config: dirname -> switch -> OpamFile.Switch_config.t -> unit 40 | 41 | (** Add the package metadata to the switch-local cache of installed packages *) 42 | val install_metadata: rw switch_state -> package -> unit 43 | 44 | (** Remove the metadata of the package from the switch-local cache of installed 45 | packages *) 46 | val remove_metadata: rw switch_state -> package_set -> unit 47 | 48 | (** Update the on-disk set of packages marked to reinstall on the current switch 49 | (excepting compiler packages, and pinned packages if [unpinned_only] is 50 | set) *) 51 | val add_to_reinstall: 52 | rw switch_state -> unpinned_only:bool -> package_set -> rw switch_state 53 | 54 | (** Updates the package selections and switch config to take into account the 55 | given newly installed package. The updated state is written to disk unless 56 | [OpamStateConfig.(!r.dry_run)] and returned. *) 57 | val add_to_installed: 58 | rw switch_state -> ?root:bool -> package -> rw switch_state 59 | 60 | (** Updates the package selections and switch config to take into account the 61 | removed package. The updated state is written to disk unless 62 | [OpamStateConfig.(!r.dry_run)], and returned. If [keep_as_root], the package 63 | isn't removed from the switch state [installed_roots] set. *) 64 | val remove_from_installed: 65 | ?keep_as_root:bool -> rw switch_state -> package -> rw switch_state 66 | 67 | (** Update the switch selections with the supplied optional arguments. Changes 68 | are written to disk and returned *) 69 | val update_switch_state: 70 | ?installed: package_set -> 71 | ?installed_roots: package_set -> 72 | ?reinstall: package_set -> 73 | ?pinned: package_set -> 74 | rw switch_state -> rw switch_state 75 | -------------------------------------------------------------------------------- /admin-scripts/extract_mini_repository.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | set -e 4 | 5 | if [ $# = 0 ]; then 6 | cat < /dev/null || true 95 | done 96 | 97 | ## Convert the required compilers as packages 98 | 99 | "${SOURCE_DIR}"/compilers-to-packages.ml 100 | 101 | ## Fetch the packages and compilers archives 102 | 103 | for version in ${COMPILERS}; do 104 | opam admin make --resolve --compiler ${version} ocaml.${version} ${PACKAGES} 105 | done 106 | 107 | ## Remove the unrequired package "versions 108 | 109 | unrequired_version() { 110 | case "$1" in 111 | base-*) 112 | return 1;; 113 | *) 114 | for version in archives/* 115 | do 116 | if [ "${version}" = "archives/$1+opam.tar.gz" ]; then return 1; fi 117 | done 118 | esac 119 | return 0 120 | } 121 | 122 | for dir in packages/*/* 123 | do 124 | if unrequired_version "${dir##packages/*/}"; then 125 | rm -r "${dir}" 126 | fi 127 | done 128 | 129 | # Remove empty directories in "packages/" 130 | 131 | for dir in packages/* 132 | do 133 | rmdir "${dir}" 2> /dev/null || true 134 | done 135 | 136 | ## Remove unrequired files 137 | 138 | rm -f .gitignore .travis-ci-install.sh .travis-ci.sh .travis.yml README.md 139 | 140 | ## Build the archive 141 | 142 | cd "${WORK_DIR}" 143 | tar czf "${TARGET_DIR}/opam-mini-repository.tar.gz" ${REPO_DIR_NAME} 144 | --------------------------------------------------------------------------------