├── .github └── workflows │ └── main.yml ├── .gitignore ├── .travis.yml ├── CHANGES.md ├── LICENSE ├── Makefile ├── README.md ├── crunch.ml ├── dune ├── dune-project ├── opam-bundle.opam ├── shell ├── bootstrap.sh ├── common.sh ├── compile.sh ├── configure.sh └── self_extract.sh ├── src ├── dune └── opamBundleMain.ml └── tests ├── dune ├── real ├── odoc.t └── opam-bundle.t └── stub ├── basic.t ├── env.t ├── packages.t └── repos.t /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Opam bundle 2 | 3 | on: 4 | pull_request: 5 | push: 6 | 7 | jobs: 8 | build: 9 | strategy: 10 | fail-fast: true 11 | matrix: 12 | os: 13 | - ubuntu-latest 14 | ocaml-compiler: 15 | - 4.08.x 16 | - 4.09.x 17 | - 4.10.x 18 | - 4.11.x 19 | - 4.12.x 20 | - 4.13.x 21 | - 4.14.x 22 | 23 | runs-on: ${{ matrix.os }} 24 | 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v3 28 | 29 | - name: Use OCaml ${{ matrix.ocaml-compiler }} 30 | uses: ocaml/setup-ocaml@v2 31 | with: 32 | ocaml-compiler: ${{ matrix.ocaml-compiler }} 33 | 34 | - run: opam install . --deps-only --with-test 35 | - run: opam exec -- make 36 | - run: opam exec -- make stub-tests 37 | - run: opam exec -- make real-tests 38 | if: matrix.ocaml-compiler == '4.14.x' 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | opam-bundle 2 | *.*a 3 | *.cm* 4 | *.o 5 | src/opamBundleScripts.ml 6 | *.install 7 | _build/ 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | install: wget https://raw.githubusercontent.com/ocaml/ocaml-travisci-skeleton/master/.travis-docker.sh 3 | script: bash -ex .travis-docker.sh 4 | services: 5 | - docker 6 | sudo: false 7 | env: 8 | global: 9 | - PACKAGE="ocp-sha" 10 | - PRE_INSTALL_HOOK="cd /home/opam/opam-repository && git pull origin master && opam update -u -y" 11 | matrix: 12 | - DISTRO=debian-stable OCAML_VERSION=4.02.3 13 | - DISTRO=debian-testing OCAML_VERSION=4.03.0 14 | - DISTRO=debian-unstable OCAML_VERSION=4.04.0 15 | - DISTRO=ubuntu-12.04 OCAML_VERSION=4.02.3 16 | - DISTRO=ubuntu-16.04 OCAML_VERSION=4.04.0 17 | - DISTRO=centos-6 OCAML_VERSION=4.04.0 18 | - DISTRO=centos-7 OCAML_VERSION=4.03.0 19 | - DISTRO=fedora-24 OCAML_VERSION=4.02.3 20 | - DISTRO=alpine OCAML_VERSION=4.04.0 21 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | ### 0.3 2 | - ported to opam 2.0.0~beta5 (in particular, for the new `depexts:`) 3 | - use the arch, os, etc. variables inferred by opam 4 | 5 | ### 0.2 6 | - pass `--with-doc`, `--with-test` along in the generated bootstrap/install 7 | scripts 8 | - check for bootstrapping prerequisites (`cc`, `make`, etc.) before starting 9 | - fixed calls to `sudo` 10 | - fixed escaping bugs on some versions of dash (and probably other shells too) 11 | - fixed nested error messages 12 | - list inferred system packages for user to take over if automatic installation 13 | fails 14 | - on generation, print the resulting host system constraints together with the 15 | package selection 16 | - allow specifying `package@URL` to bundle specific package sources, 17 | independently of repositories 18 | - worked around camlp4 issues related to our use of the "system" compiler 19 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | build: 4 | dune build 5 | cp _build/install/default/bin/opam-bundle . 6 | 7 | stub-tests: 8 | dune build @runtest tests/stub 9 | 10 | real-tests: 11 | dune build @runtest tests/real 12 | 13 | .PHONY: tests 14 | tests: stub-tests real-tests 15 | test: tests 16 | 17 | .PHONY: clean 18 | clean: 19 | dune clean 20 | 21 | distclean: clean 22 | rm -rf _build 23 | rm opam-bundle 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | opam-bundle(1) Opam-bundle Manual opam-bundle(1) 3 | 4 | NAME 5 | opam-bundle - Creates standalone source bundle from opam packages 6 | 7 | SYNOPSIS 8 | opam-bundle [OPTION]... PACKAGE... 9 | 10 | DESCRIPTION 11 | This utility can extract a set of packages from opam repositories, and 12 | bundle them together in a comprehensive source archive, with the 13 | scripts needed to bootstrap OCaml, opam, and install the packages on a 14 | fresh, network-less system. 15 | 16 | The opam-depext plugin is included to try and get the required system 17 | dependencies on the target system (which might, in this case, require 18 | network, depending on the system configuration). 19 | 20 | The generated bundle includes three scripts, each one calling the 21 | previous ones if necessary: 22 | 23 | bootstrap.sh 24 | Compiles OCaml and opam and gets them ready in a local prefix 25 | 26 | configure.sh 27 | Initialises an opam root within the bundle directory, and gets the 28 | required system depdendencies 29 | 30 | compile.sh 31 | Compiles the required packages using the bootstrapped opam. If a 32 | prefix was specified, and for packages listed on the command-line 33 | of opam-bundle, wrappers are installed to the prefix for installed 34 | binaries. These execute the programs within the in-bundle opam 35 | root, with the proper opam environment. 36 | 37 | For example, assuming foo is a package that installs a bar binary, from 38 | a bundle generated using opam-bundle foo, a user on a fresh system 39 | could run tar xzf foo-bundle.tar.gz && ./foo-bundle/compile.sh ~/local 40 | to get a usable bar binary within ~/local/bin (if the user does not 41 | have write permission to the given prefix, the script will use sudo). 42 | 43 | Note that the extracted bundle itself should not be moved for the 44 | wrappers to keep working. Besides the wrappers, nothing is written 45 | outside of the directory where the bundle was untarred. 46 | 47 | ARGUMENTS 48 | PACKAGE (required) 49 | List of packages to include in the bundle. Their dependencies will 50 | be included as well, but only listed packages will have wrappers 51 | installed. Packages can be specified as NAME[CONSTRAINT][@URL], 52 | where CONSTRAINT is an optional version constraint starting with 53 | one of . or =, !=, >, >=, < or <=, and @URL can be specified to use 54 | the package source from the given URL (in which case, the 55 | constraint, if any, must be . or =). 56 | 57 | OPTIONS 58 | -d, --with-doc 59 | Include the packages' doc-only dependencies in the bundle, and make 60 | the bundle generate their documentation. 61 | 62 | --debug 63 | Display debug information about what's going on. 64 | 65 | --environment[=VAL] (default=) 66 | Use the given opam environment, in the form of a list of 67 | comma-separated 'var=value' bindings, when resolving variables. 68 | This is used when computing the set of available packages, where 69 | opam uses variables arch, os, os-distribution, os-version and 70 | os-family: if undefined, the variables are inferred from the 71 | current system. If set without argument, an empty environment is 72 | used: this can be used to ensure the generated bundle won't have 73 | arch or OS constraints. 74 | 75 | --help[=FMT] (default=auto) 76 | Show this help in format FMT. The value FMT must be one of `auto', 77 | `pager', `groff' or `plain'. With `auto', the format is `pager` or 78 | `plain' whenever the TERM env var is `dumb' or undefined. 79 | 80 | -o VAL, --output=VAL 81 | Output the bundle to the given file. 82 | 83 | --ocaml=VAL 84 | Select a version of OCaml to include. It will be used for 85 | bootstrapping, and must be able to compile opam. 86 | 87 | --opam=VAL 88 | Select a version of opam to include. That version must be released 89 | with an upstream "full-archive" available online, and be at least 90 | 2.0.0~rc2, to support all the required features. 91 | 92 | --repository=URL 93 | URLs of the repositories to use (highest priority first). Note that 94 | it is required that the OCaml package at the selected version is 95 | included (see --ocaml), with the hierarchy and alternatives as on 96 | the default repository ('ocaml-base-compiler', 'ocaml-system' and 97 | 'ocaml-config' packages, with the 'ocaml' wrapper virtual package). 98 | This makes it possible to bootstrap opam and compile the requested 99 | packages with a single compilation of OCaml. 100 | 101 | --self 102 | Generate a self-extracting script besides the .tar.gz bundle 103 | 104 | -t, --with-test 105 | Include the packages' test-only dependencies in the bundle, and 106 | make the bundle run the tests on installation. 107 | 108 | -y, --yes 109 | Confirm all prompts without asking. 110 | 111 | Opam-bundle opam-bundle(1) 112 | ``` 113 | -------------------------------------------------------------------------------- /crunch.ml: -------------------------------------------------------------------------------- 1 | let add_file f = 2 | let basename = Filename.basename f in 3 | let name = 4 | String.map (function 5 | | 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' as c -> c 6 | | _ -> '_') 7 | basename 8 | in 9 | let f = open_in f in 10 | let buf = Buffer.create 4096 in 11 | (try while true do Buffer.add_channel buf f 4096 done with End_of_file -> ()); 12 | close_in f; 13 | Printf.printf "let %s =\n%S\n\n" name (Buffer.contents buf); 14 | basename, name 15 | 16 | let () = 17 | let files = List.tl (Array.to_list Sys.argv) in 18 | let nf = List.map add_file files in 19 | Printf.printf "let all_scripts = [\n %s\n]\n" 20 | (String.concat "\n " 21 | (List.map (fun (f, name) -> Printf.sprintf "%S, %s;" f name) nf)) 22 | -------------------------------------------------------------------------------- /dune: -------------------------------------------------------------------------------- 1 | (rule 2 | (target opam-bundle.1) 3 | (deps %{bin:opam-bundle}) 4 | (action 5 | (with-stdout-to %{target} 6 | (run %{deps} --help=groff)))) 7 | 8 | (install 9 | (section man) 10 | (files opam-bundle.1) 11 | (package opam-bundle)) 12 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.7) 2 | (name opam-bundle) 3 | (cram enable) 4 | -------------------------------------------------------------------------------- /opam-bundle.opam: -------------------------------------------------------------------------------- 1 | opam-version: "2.0" 2 | name: "opam-bundle" 3 | version: "0.4" 4 | maintainer: "Louis Gesbert " 5 | authors: "Louis Gesbert " 6 | license: "GPL-3.0-only" 7 | tags: "org:ocamlpro" 8 | homepage: "https://github.com/AltGr/opam-bundle" 9 | bug-reports: "https://github.com/AltGr/opam-bundle/issues" 10 | depends: [ 11 | "ocaml" {build} 12 | "ocamlfind" {build} 13 | "dune" {build & >= "2.8.5"} 14 | "cmdliner" {build & >= "1.1.0"} 15 | "opam-client" {build & >= "2.1.0"} 16 | ] 17 | build: [ "dune" "build" "-j" jobs "-p" name "@runtest" {with-test} ] 18 | dev-repo: "git+https://github.com/AltGr/opam-bundle" 19 | flags: plugin 20 | synopsis: "A tool that creates stand-alone source bundles from opam packages" 21 | description: """ 22 | opam-bundle is a command-line tool that, given a selection of packages, 23 | generates a .tar.gz (and optionally a self-extracting) archive containing their 24 | sources, and everything needed to bootstrap and compile them: 25 | - the sources of their dependencies 26 | - the sources of the chosen version of OCaml 27 | - the sources of opam 28 | - a set of scripts to bootstrap, check and install external dependencies, 29 | compile all the above, install the packages within a sandbox, and optionally 30 | put wrapper scripts within your PATH 31 | 32 | This is expected to be done as normal user, with constrained calls to `sudo` 33 | when needed for depexts and wrappers installation. 34 | """ 35 | -------------------------------------------------------------------------------- /shell/bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ue 2 | 3 | . "$(dirname "$0")/common.sh" 4 | 5 | start 6 | 7 | title "Bootstrap: checking for prerequisites" 8 | 9 | # Avoid interference from an existing opam installation 10 | eval $(opam env --revert 2>/dev/null) >/dev/null 2>&1 || true 11 | unset OPAMSWITCH 12 | 13 | MISSING= 14 | check_prereq() { 15 | NAME="$1" 16 | printf "Checking for $*... " 17 | while [ $# -gt 0 ]; do 18 | if type "$1" >/dev/null 2>&1 ; then break; fi 19 | shift 20 | done 21 | if [ $# -gt 0 ]; then 22 | printf "\033[32mfound\033[m\n" 23 | else 24 | printf "\033[31mnot found\033[m\n" 25 | MISSING="$MISSING $NAME" 26 | fi 27 | } 28 | check_prereq cc 29 | check_prereq make 30 | check_prereq wget curl 31 | check_prereq patch 32 | check_prereq unzip 33 | check_prereq bunzip2 34 | check_prereq rsync 35 | 36 | if [ -n "$MISSING" ]; then 37 | printf "This source bundle requires the following tools to bootstrap, and they are\n" 38 | printf "absent from this system. Please install them first:\n $MISSING\n\n" 39 | finished 40 | exit 10 41 | fi 42 | 43 | apply_patches() { 44 | for patch in $(ls ../patches/*.patch | sort); do 45 | patch -p1 < $patch 46 | done 47 | } 48 | 49 | if [ -x "$PREFIX/bin/ocamlc" ]; then 50 | echo "Already compiled OCaml found" 51 | else 52 | title "Bootstrap: compiling OCaml" 53 | 54 | echo "This may take a while. Output is in $LOG" 55 | logged_cmd "Uncompressing" tar xzf repo/archives/ocaml-base-compiler."%{ocamlv}%"/*.tar.gz 56 | cd "ocaml-%{ocamlv}%" 57 | if [ -d "../patches" ] ; then 58 | logged_cmd "Applying patches" apply_patches 59 | fi 60 | logged_cmd "Configuring" ./configure -prefix "$PREFIX" 61 | logged_cmd "Compiling" make world world.opt 62 | logged_cmd "Installing to temp prefix" make install 63 | cd "$DIR" 64 | rm -rf "ocaml-%{ocamlv}%" 65 | fi 66 | 67 | if [ -x "$PREFIX/bin/opam" ]; then 68 | echo "Already compiled opam found" 69 | else 70 | title "Bootstrap: compiling opam" 71 | 72 | echo "This may take a while. Output is in $LOG" 73 | logged_cmd "Uncompressing" tar xzf "%{opam_archive}%" 74 | cd $(basename "%{opam_archive}%" .tar.gz) 75 | logged_cmd "Configuring" ./configure --prefix "$PREFIX" 76 | logged_cmd "Compiling extra dependencies" make lib-ext 77 | logged_cmd "Compiling" make 78 | logged_cmd "Installing to temp prefix" make install 79 | cd "$DIR" 80 | rm -rf $(basename "%{opam_archive}%" .tar.gz) 81 | fi 82 | 83 | finished 84 | -------------------------------------------------------------------------------- /shell/common.sh: -------------------------------------------------------------------------------- 1 | DIR=$( cd $(dirname "$0") && pwd ) 2 | PREFIX="$DIR/bootstrap" 3 | OPAMROOT="$DIR/opam" 4 | LOG="$DIR/$(basename "$0" .sh).log" 5 | 6 | rm -f "$LOG" 7 | 8 | title() { 9 | printf "\n\033[33m================\033[m %-45s \033[33m================\033[m\n\n" "$*" 10 | } 11 | logged_cmd() { 12 | local R=0 13 | printf "$1... " 14 | shift 15 | echo "+ [ $1 ] $*" >>$LOG 16 | "$@" >>$LOG 2>&1 || R=$? 17 | echo >>$LOG 18 | if [ $R -eq 0 ]; then printf "\033[32mdone\033[m\n"; return 19 | else echo; return $R 20 | fi 21 | } 22 | 23 | start() { 24 | trap "printf '\nSomething went wrong, see log in $LOG\n'" EXIT 25 | } 26 | 27 | finished() { 28 | trap - EXIT 29 | } 30 | 31 | export PATH="$PREFIX/bin:$PATH" 32 | export CAML_LD_LIBRARY_PATH="$PREFIX/lib/ocaml/stublibs" 33 | export OPAMROOT 34 | cd $DIR 35 | -------------------------------------------------------------------------------- /shell/compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ue 2 | 3 | . "$(dirname "$0")/common.sh" 4 | 5 | usage() { 6 | echo "Usage: $0 [OPTIONS] PREFIX" 7 | echo " Bootstraps and compiles %{install_packages}% within $DIR," 8 | echo " then installs wrappers to the given PREFIX if specified." 9 | echo 10 | echo "Options:" 11 | echo " -h --help show this help" 12 | echo " -l --list list the opam packages included" 13 | echo " -y --yes don't stop for confirmation" 14 | exit $1 15 | } 16 | 17 | DESTDIR= 18 | YES= 19 | while [ $# -gt 0 ]; do 20 | case "$1" in 21 | -h|--help) usage 0;; 22 | -l|--list) echo "%{install_packages}%"; exit 0;; 23 | -y|--yes) YES=1;; 24 | -*) usage 2;; 25 | *) 26 | if [ -z "$DESTDIR" ]; then DESTDIR=$1 27 | else usage 2; fi 28 | esac 29 | shift 30 | done 31 | 32 | if [ "X${DIR#/tmp}" != "X$DIR" ] && [ -z "$YES" ]; then 33 | echo "ERROR: you are going to install into /tmp. Everything is likely to get wiped" 34 | echo " on reboot." 35 | echo " Move to a more permanent location, or use '--yes' to force." 36 | exit 1 37 | fi 38 | 39 | if [ -z "$DESTDIR" ]; then 40 | echo "This bundle will compile the application to $DIR, WITHOUT installing" 41 | echo "wrappers anywhere else." 42 | else 43 | echo "This bundle will compile the application to $DIR, and put wrappers into" 44 | echo "$DESTDIR/bin. You will need to retain $DIR for the wrappers to work." 45 | fi 46 | 47 | if [ -z "$YES" ]; then printf "\nPress enter to continue... "; read _; fi 48 | 49 | "$DIR/configure.sh" 50 | 51 | start 52 | 53 | title "Compile: installing packages" 54 | 55 | echo "Output is in $LOG" 56 | 57 | # Redirect sudo to extract the commands 58 | rm -f "$DIR/needs_sudo" 59 | cat >${PREFIX}/bin/sudo <>"$DIR/needs_sudo" 62 | exit 1 63 | EOF 64 | chmod +x ${PREFIX}/bin/sudo 65 | 66 | R=0 67 | logged_cmd "Compiling packages" opam install --yes %{install_packages}% %{doc?--with-doc:}% %{test?--with-test:}% || R=$? 68 | 69 | rm -f ${PREFIX}/bin/sudo 70 | 71 | if [ "$R" -eq 10 ] && [ -s "$DIR/needs_sudo" ]; then 72 | echo "You will be asked for 'sudo' access to install required system dependencies" 73 | echo "through your package system:" 74 | xargs -a "$DIR/needs_sudo" -L 1 echo " " 75 | printf "Press enter to continue... " 76 | read _ 77 | xargs -a "$DIR/needs_sudo" -L 1 sudo 78 | rm -f "$DIR/needs_sudo" 79 | logged_cmd "Compiling packages" opam install --yes %{install_packages}% %{doc?--with-doc:}% %{test?--with-test:}% 80 | elif [ "$R" -ne 0 ]; then 81 | exit "$R" 82 | fi 83 | 84 | 85 | logged_cmd "Cleaning up" opam clean --yes 86 | 87 | if [ -z "$DESTDIR" ]; then 88 | echo 89 | echo "All compiled within $DIR. To use the compiled packages:" 90 | echo 91 | echo " - either re-run $0 with a PREFIX argument to install command wrappers" 92 | echo " (it won't recompile everything)" 93 | echo 94 | echo ' - or run the following to update the environment in the current shell, so that' 95 | echo ' they are in your PATH:' 96 | echo " export PATH=\"$PREFIX/bin:\$PATH\"; eval \$(opam env --root \"$OPAMROOT\" --set-root)" 97 | echo 98 | finished 99 | exit 0 100 | fi 101 | 102 | if [ -w "$DESTDIR/bin" ] || mkdir -p "$DESTDIR/bin" >/dev/null 2>&1 && [ -w "$DESTDIR/bin" ]; then 103 | SUDO="" 104 | else 105 | echo "No write access to $DESTDIR/bin, will use 'sudo'." 106 | SUDO="sudo --" 107 | fi 108 | bin_prefix=$(opam var bin) 109 | opam show --list-files %{install_packages}% | grep "^$bin_prefix" | $SUDO sh -uec " 110 | mkdir -p '$DESTDIR/bin' 111 | while read -r bin; do 112 | WRAPPER=\"$DESTDIR/bin/\$(basename \"\$bin\")\" 113 | if [ -e \"\$WRAPPER\" ]; then 114 | echo \"Warning: \$WRAPPER exists already, not overwriting.\" 115 | else 116 | cat <\"\$WRAPPER\" 117 | #!/bin/sh -e 118 | export PATH=\"$PREFIX/bin:\\\$PATH\" 119 | exec \"$PREFIX/bin/opam\" exec --root \"$OPAMROOT\" --readonly -- \"\$bin\" \"\\\$@\" 120 | EOF 121 | chmod a+x \"\$WRAPPER\" 122 | printf \"Wrapper \\033[1m\$(basename \$bin)\\033[m installed successfully.\\n\" 123 | fi 124 | done 125 | " 126 | finished 127 | -------------------------------------------------------------------------------- /shell/configure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ue 2 | 3 | . "$(dirname "$0")/common.sh" 4 | 5 | "$DIR/bootstrap.sh" 6 | 7 | start 8 | 9 | if [ -d "$OPAMROOT/default" ]; then 10 | echo "Already initialised opam sandbox found" 11 | else 12 | title "Configure: initialising opam" 13 | 14 | echo "Output is in $LOG" 15 | 16 | if [ ! -f "$OPAMROOT/config" ]; then 17 | logged_cmd "Initialising" opam init --bare --no-setup --yes --disable-sandboxing $DIR/repo 18 | fi 19 | logged_cmd "Creating sandbox" opam switch create default ocaml-bootstrap 20 | ln -sf "$PREFIX/lib/ocaml" "$(opam var lib)/ocaml" 21 | fi 22 | 23 | finished 24 | -------------------------------------------------------------------------------- /shell/self_extract.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -ue 2 | 3 | dd bs=%{blocksize}% if="$0" skip=%{blocks}% 2>/dev/null | tar xz 4 | exec $(basename $0 .sh)/compile.sh "$@" 5 | -------------------------------------------------------------------------------- /src/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name opamBundleMain) 3 | (public_name opam-bundle) 4 | (modes (native exe)) 5 | (flags -w A-4-44-70) 6 | (modules opamBundleMain opamBundleScripts) 7 | (libraries opam-client cmdliner opam-repository)) 8 | 9 | (rule 10 | (targets opamBundleScripts.ml) 11 | (deps (source_tree ../shell) ../crunch.ml) 12 | (action 13 | (with-stdout-to %{targets} 14 | (run ocaml ../crunch.ml %{deps})))) 15 | -------------------------------------------------------------------------------- /src/opamBundleMain.ml: -------------------------------------------------------------------------------- 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 | open OpamTypes 12 | open OpamStateTypes 13 | open OpamProcess.Job.Op 14 | 15 | let ocaml_base_compiler_package_name = OpamPackage.Name.of_string "ocaml-base-compiler" 16 | 17 | let bootstrap_packages ocamlv = [ 18 | ocaml_base_compiler_package_name, Some (`Eq, ocamlv); 19 | ] 20 | 21 | let system_ocaml_package_name = OpamPackage.Name.of_string "ocaml-system" 22 | 23 | let wrapper_ocaml_package_name = OpamPackage.Name.of_string "ocaml" 24 | 25 | let ocaml_config_package_name = OpamPackage.Name.of_string "ocaml-config" 26 | 27 | (* This package will be created solely for the bundle, and replaces 28 | ocaml-system *) 29 | let bootstrap_ocaml_package_name = OpamPackage.Name.of_string "ocaml-bootstrap" 30 | let bootstrap_ocaml_package ocamlv = 31 | OpamPackage.create bootstrap_ocaml_package_name ocamlv 32 | 33 | let additional_user_packages ocamlv = [ 34 | OpamSolution.eq_atom_of_package (bootstrap_ocaml_package ocamlv); 35 | ] 36 | 37 | let hardcoded_env ocamlv opamv = [ 38 | OpamVariable.of_string "sys-ocaml-version", 39 | (lazy (Some (S (OpamPackage.Version.to_string ocamlv))), 40 | "Pre-selected OCaml version"); 41 | OpamVariable.of_string "opam-version", 42 | (lazy (Some (S (OpamPackage.Version.to_string opamv))), 43 | "Pre-selected opam version"); 44 | ] 45 | 46 | (* Used to optimise solving times: we know we'll never need those (since we 47 | require a definite version, and hardcode the use of ocaml-base-compiler for 48 | bootstrap (and ocaml-bootstrap for reuse) *) 49 | let exclude_packages ocamlv = [ 50 | OpamPackage.Name.of_string "ocaml", Some (`Neq, ocamlv); 51 | OpamPackage.Name.of_string "ocaml-variants", None; 52 | OpamPackage.Name.of_string "ocaml-system", None; 53 | ] 54 | 55 | let opam_archive_url opamv = 56 | let tag = 57 | OpamStd.String.map (function '~' -> '-' | c -> c) 58 | (OpamPackage.Version.to_string opamv) 59 | in 60 | Printf.sprintf 61 | "https://github.com/ocaml/opam/releases/download/%s/opam-full-%s.tar.gz" 62 | tag tag 63 | |> OpamUrl.of_string 64 | 65 | let output_extension = "tar.gz" 66 | 67 | let stdlib_output = output 68 | 69 | let create_bundle ocamlv opamv repo debug output env test doc yes self_extract 70 | packages_targets = 71 | OpamClientConfig.opam_init 72 | ~debug_level:(if debug then 1 else 0) 73 | ~yes:(if yes then Some true else None) 74 | (); 75 | let packages = List.map fst packages_targets in 76 | let ocamlv = match ocamlv with 77 | | Some v -> 78 | OpamConsole.formatted_msg "OCaml version is set to %s.\n" 79 | (OpamConsole.colorise `bold @@ OpamPackage.Version.to_string v); 80 | v 81 | | None -> 82 | let v = 83 | try 84 | OpamPackage.Version.of_string @@ 85 | List.hd (OpamSystem.read_command_output ["ocamlc"; "-vnum"]) 86 | with e -> OpamStd.Exn.fatal e; OpamPackage.Version.of_string "4.04.1" 87 | in 88 | OpamConsole.formatted_msg "No OCaml version selected, will use %s.\n" 89 | (OpamConsole.colorise `bold @@ OpamPackage.Version.to_string v); 90 | v 91 | in 92 | let opamv = 93 | match Option.map OpamPackage.Version.to_string opamv with 94 | | Some v -> 95 | let v = match v with 96 | | "2.0" -> "2.0.10" 97 | | "2.1" -> "2.1.4" 98 | | _ -> v 99 | in 100 | OpamConsole.formatted_msg "Opam version is set to %s.\n" 101 | (OpamConsole.colorise `bold v); 102 | OpamPackage.Version.of_string v 103 | | None -> 104 | let default = "2.1.4" in 105 | OpamConsole.formatted_msg "No opam version selected, will use %s.\n" 106 | (OpamConsole.colorise `bold default); 107 | OpamPackage.Version.of_string default 108 | in 109 | let output = match output, packages with 110 | | Some f, _ -> 111 | if not (String.contains (OpamFilename.(Base.to_string (basename f))) '.') 112 | then OpamFilename.add_extension f output_extension 113 | else f 114 | | None, (name, _)::_ -> 115 | OpamFilename.of_string 116 | (OpamPackage.Name.to_string name ^"-bundle."^output_extension) 117 | | None, [] -> assert false 118 | in 119 | let bundle_name = 120 | Filename.basename @@ 121 | OpamFilename.remove_suffix 122 | (OpamFilename.Base.of_string ("."^output_extension)) 123 | output 124 | in 125 | let env = 126 | match env with 127 | | Some [] -> 128 | (* System variables are always defined in opam, we need to 129 | fill them to simulate empty environment and avoid undefined 130 | variables. *) 131 | OpamConsole.note "Empty environment"; 132 | OpamSysPoll.variables 133 | |> List.map (fun (v,_) -> v, (lazy (Some (S "")), "Empty environment")) 134 | |> OpamVariable.Map.of_list 135 | | Some e -> 136 | let comment = "Manually defined" in 137 | List.map (fun s -> 138 | match OpamStd.String.cut_at s '=' with 139 | | Some (var,value) -> 140 | OpamVariable.of_string var, (lazy (Some (S value)), comment) 141 | | None -> 142 | OpamVariable.of_string s, (lazy (Some (B true)), comment)) 143 | e 144 | |> OpamVariable.Map.of_list 145 | |> OpamVariable.Map.union (fun _poll cli -> cli) 146 | (OpamVariable.Map.of_list 147 | (List.map (fun (v,x) -> v, (x, "Inferred from current system")) 148 | OpamSysPoll.variables)) 149 | | None -> 150 | let e = 151 | List.map (fun (v,x) -> v, (x, "Inferred from current system")) 152 | OpamSysPoll.variables 153 | in 154 | OpamConsole.formatted_msg 155 | "No environment specified, will use the following for package \ 156 | resolution (based on the host system):\n%s" 157 | (OpamStd.Format.itemize (fun (v, (lazy c, _)) -> 158 | Printf.sprintf "%s = %S" 159 | (OpamConsole.colorise `bold @@ OpamVariable.to_string v) 160 | (OpamStd.Option.to_string 161 | OpamVariable.string_of_variable_contents c)) 162 | e); 163 | OpamVariable.Map.of_list e 164 | in 165 | let env = 166 | OpamVariable.Map.union (fun a _ -> a) 167 | env 168 | (OpamVariable.Map.of_list (hardcoded_env ocamlv opamv)) 169 | in 170 | let packages_filter = 171 | let module L = OpamListCommand in 172 | OpamFormula.ands [ 173 | Atom L.Available; 174 | OpamFormula.ors [ 175 | Atom (L.Solution (L.default_dependency_toggles, 176 | bootstrap_packages ocamlv)); 177 | Atom (L.Solution ({L.default_dependency_toggles with L.test; doc}, 178 | packages @ additional_user_packages ocamlv)); 179 | ] 180 | ] 181 | in 182 | OpamFilename.with_tmp_dir @@ fun tmp -> 183 | let opam_root = OpamFilename.Op.(tmp / "root") in 184 | OpamStateConfig.update ~root_dir:opam_root (); 185 | (* let repos_dir = OpamFilename.Op.(tmp / "repos") in *) 186 | (* *** *) 187 | OpamConsole.header_msg "Initialising repositories"; 188 | let gen_repo_name repos_map base = 189 | let rec uniq i = 190 | let name = 191 | OpamRepositoryName.of_string 192 | (Printf.sprintf "%s%s" base 193 | (if i = 0 then "" else string_of_int i)) 194 | in 195 | if OpamRepositoryName.Map.mem name repos_map then uniq (i+1) 196 | else name 197 | in 198 | uniq 0 199 | in 200 | let repos_list_rev, repos_map = 201 | List.fold_left (fun (repos_list_rev, repos_map) url -> 202 | let name = 203 | match OpamStd.String.split url.OpamUrl.path '/' with 204 | | s::_ -> gen_repo_name repos_map s 205 | | [] -> gen_repo_name repos_map "repository" 206 | in 207 | let repo = { 208 | repo_name = name; 209 | repo_url = url; 210 | repo_trust = None; 211 | } in 212 | repo.repo_name :: repos_list_rev, 213 | OpamRepositoryName.Map.add repo.repo_name repo repos_map) 214 | ([], OpamRepositoryName.Map.empty) 215 | repo 216 | in 217 | let repos_list = List.rev repos_list_rev in 218 | let dl_cache = 219 | let std_opamroot = OpamStateConfig.opamroot () in 220 | [OpamUrl.parse ~backend:`rsync 221 | (OpamFilename.Dir.to_string 222 | (OpamRepositoryPath.download_cache std_opamroot))] 223 | in 224 | let gt = { 225 | global_lock = OpamSystem.lock_none; 226 | root = opam_root; 227 | config = 228 | OpamFile.Config.empty 229 | |> OpamFile.Config.with_repositories repos_list 230 | |> OpamFile.Config.with_dl_cache dl_cache; 231 | global_variables = env; 232 | } in 233 | let rt = { 234 | repos_global = (gt :> unlocked global_state); 235 | repos_lock = OpamSystem.lock_none; 236 | repositories = repos_map; 237 | repos_definitions = 238 | OpamRepositoryName.Map.map (fun r -> 239 | OpamFile.Repo.safe_read 240 | OpamRepositoryPath.(repo (root gt.root r.repo_name)) |> 241 | OpamFile.Repo.with_root_url r.repo_url) 242 | repos_map; 243 | repo_opams = OpamRepositoryName.Map.empty; 244 | repos_tmp = Hashtbl.create 1; 245 | } in 246 | let failed_repos, rt = 247 | OpamRepositoryCommand.update_with_auto_upgrade rt 248 | (OpamRepositoryName.Map.keys repos_map) 249 | in 250 | if failed_repos <> [] then 251 | OpamConsole.error_and_exit `Sync_error 252 | "Could not fetch some repositories: %s" 253 | (OpamStd.List.to_string OpamRepositoryName.to_string failed_repos); 254 | (* *** Custom packages *) 255 | let custom_opams = 256 | let index = OpamRepositoryState.build_index rt repos_list in 257 | (* Renaming ocaml-system to ocaml-bootstrap avoids confusion from other 258 | packages *) 259 | let find_def nv = 260 | match OpamPackage.Map.find_opt nv index with 261 | | None -> 262 | OpamConsole.error_and_exit `Not_found 263 | "Package %s not found in the repositories" 264 | (OpamPackage.to_string nv) 265 | | Some opam -> opam 266 | in 267 | let bootstrap_ocaml_opam = 268 | find_def (OpamPackage.create system_ocaml_package_name ocamlv) |> 269 | OpamFile.OPAM.with_name bootstrap_ocaml_package_name |> 270 | OpamFile.OPAM.with_synopsis 271 | "OCaml compiler generated during the opam-bundle bootstrap phase" 272 | in 273 | let fix_compiler_depends opam = 274 | OpamFile.OPAM.with_depends 275 | (OpamFormula.map (fun (name, c as at) -> 276 | if name = system_ocaml_package_name then 277 | Atom (bootstrap_ocaml_package_name, c) 278 | else Atom at) 279 | (OpamFile.OPAM.depends opam)) 280 | opam 281 | in 282 | let ocaml_config_packages = 283 | OpamPackage.Map.filter (function 284 | | package when OpamPackage.Name.equal ocaml_config_package_name 285 | @@ OpamPackage.name package -> 286 | fun _ -> true 287 | | _ -> fun _ -> false) index |> 288 | OpamPackage.Map.map fix_compiler_depends 289 | in 290 | let wrapper_package = 291 | OpamPackage.create wrapper_ocaml_package_name ocamlv 292 | in 293 | let wrapper_ocaml_opam = 294 | find_def wrapper_package |> fix_compiler_depends 295 | in 296 | OpamPackage.Map.union (fun a _ -> a) 297 | ocaml_config_packages 298 | @@ OpamPackage.Map.of_list [ 299 | bootstrap_ocaml_package ocamlv, bootstrap_ocaml_opam; 300 | wrapper_package, wrapper_ocaml_opam; 301 | ] 302 | in 303 | let external_opams, virtual_pins = 304 | if List.for_all (fun (_,target) -> target = None) packages_targets then 305 | OpamPackage.Map.empty, OpamPackage.Map.empty 306 | else 307 | let srcs = OpamFilename.Op.(tmp / "sources") in 308 | OpamConsole.header_msg "Getting external packages"; 309 | let pkgs_urls = 310 | OpamStd.List.filter_map (function 311 | | _, None -> None 312 | | (name, None), Some target -> Some ((name, None), target) 313 | | (name, Some (`Eq, v)), Some target -> 314 | Some ((name, Some v), target) 315 | | _ -> invalid_arg "Only equality constraints are supported") 316 | packages_targets 317 | in 318 | let pkgs_src = 319 | OpamParallel.map ~jobs:OpamStateConfig.(!r.dl_jobs) 320 | ~command:(fun ((name, v), url) -> 321 | let srcdir = 322 | OpamFilename.Op.(srcs / OpamPackage.Name.to_string name) 323 | in 324 | OpamRepository.pull_tree (OpamPackage.Name.to_string name) 325 | srcdir [] [url] @@| function 326 | | Not_available (s, _) -> 327 | OpamConsole.error_and_exit `Sync_error 328 | "Could not obtain %s from %s%s" 329 | (OpamPackage.Name.to_string name) 330 | (OpamUrl.to_string url) 331 | (OpamStd.Option.to_string (fun s -> ": "^s) s) 332 | | Up_to_date _ | Result _ -> (name, v), srcdir) 333 | pkgs_urls 334 | in 335 | let pkgs_opams_archives = 336 | pkgs_src |> List.map @@ fun ((name, v), src) -> 337 | let allpkgs () = 338 | OpamRepositoryName.Map.fold 339 | (fun _ m s -> OpamPackage.Set.union (OpamPackage.keys m) s) 340 | rt.repo_opams OpamPackage.Set.empty 341 | in 342 | let nv, opam = 343 | match OpamPinned.find_opam_file_in_source name src with 344 | | Some f -> 345 | OpamConsole.note 346 | "Will use package definition found in source for %s" 347 | (OpamPackage.Name.to_string name); 348 | let o = OpamFile.OPAM.read f in 349 | let o = OpamFormatUpgrade.opam_file ~filename:f o in 350 | let v = 351 | match v, OpamFile.OPAM.version_opt o with 352 | | Some v_user, Some v_pkg when v_user <> v_pkg -> 353 | OpamConsole.warning 354 | "The package declares itself as version %s, but will use %s, \ 355 | as specified" 356 | (OpamPackage.Version.to_string v_pkg) 357 | (OpamPackage.Version.to_string v_user); 358 | v_user 359 | | Some v, _ | _, Some v -> v 360 | | None, None -> 361 | let v = 362 | try OpamPackage.version 363 | (OpamPackage.max_version (allpkgs ()) name) 364 | with Not_found -> OpamPackage.Version.of_string "~dev" 365 | in 366 | OpamConsole.warning 367 | "No version information found for %s. Will use %s" 368 | (OpamPackage.Name.to_string name) 369 | (OpamPackage.Version.to_string v); 370 | v 371 | in 372 | OpamPackage.create name v, OpamFile.OPAM.with_version v o 373 | | None -> 374 | match v with 375 | | Some v -> 376 | (let nv = OpamPackage.create name v in 377 | match OpamRepositoryState.find_package_opt rt repos_list nv with 378 | | Some (repo, o) -> 379 | OpamConsole.note 380 | "Sources for %s don't contain a package definition, will use \ 381 | the one found in the repository at %s" 382 | (OpamPackage.to_string nv) 383 | (OpamUrl.to_string 384 | (OpamRepositoryName.Map.find repo rt.repositories).repo_url); 385 | nv, o 386 | | None -> 387 | OpamConsole.error_and_exit `Not_found 388 | "Specified sources for %s don't contain a package definition, \ 389 | and none was found in the repositories" 390 | (OpamPackage.to_string nv) 391 | (* note: we could improve by allowing to lookup current 392 | pins at this point *)) 393 | | None -> 394 | try 395 | let nv = OpamPackage.max_version (allpkgs ()) name in 396 | match OpamRepositoryState.find_package_opt rt repos_list nv with 397 | | Some (repo, o) -> 398 | OpamConsole.note 399 | "Sources for %s don't contain a package definition, will \ 400 | assume version %s and use metadata and build instructions \ 401 | from the repository at %s" 402 | (OpamPackage.Name.to_string name) 403 | (OpamConsole.colorise `bold (OpamPackage.version_to_string nv)) 404 | (OpamUrl.to_string 405 | (OpamRepositoryName.Map.find repo rt.repositories).repo_url); 406 | nv, o 407 | | None -> assert false 408 | with Not_found -> 409 | OpamConsole.error_and_exit `Not_found 410 | "Specified sources for %s don't contain a package definition, \ 411 | and none was found in the repositories" 412 | (OpamPackage.Name.to_string name) 413 | in 414 | let archive = 415 | OpamFilename.Op.(srcs // (OpamPackage.to_string nv^".tar.gz")) 416 | in 417 | OpamFilename.mkdir (OpamFilename.dirname archive); 418 | OpamProcess.Job.run @@ 419 | OpamSystem.make_command "tar" 420 | ~dir:(OpamFilename.Dir.to_string srcs) 421 | ["czf"; OpamFilename.to_string archive; 422 | OpamFilename.remove_prefix_dir srcs src] 423 | @@> (fun r -> Done (OpamSystem.raise_on_process_error r)); 424 | nv, opam, archive 425 | in 426 | let opams = 427 | List.fold_left 428 | (fun set (nv, opam, _) -> OpamPackage.Map.add nv opam set) 429 | OpamPackage.Map.empty 430 | pkgs_opams_archives 431 | in 432 | let virtual_pins = 433 | List.fold_left (fun acc (nv,_,archive) -> 434 | OpamPackage.Map.add nv archive acc) 435 | OpamPackage.Map.empty pkgs_opams_archives 436 | in 437 | opams, virtual_pins 438 | in 439 | let custom_repo = gen_repo_name rt.repositories "custom" in 440 | let repos_list = custom_repo :: repos_list in 441 | let rt = 442 | { rt with 443 | repo_opams = 444 | OpamRepositoryName.Map.add custom_repo 445 | (OpamPackage.Map.union (fun o _ -> o) custom_opams external_opams) 446 | rt.repo_opams; 447 | } 448 | in 449 | let packages = 450 | (* Enforce the pinned-to versions in the request *) 451 | let pins = OpamPackage.keys virtual_pins in 452 | List.map (fun (name, _ as at) -> 453 | try (name, (Some (`Eq, (OpamPackage.package_of_name pins name).version))) 454 | with Not_found -> at) 455 | packages 456 | in 457 | (* *** *) 458 | OpamConsole.header_msg "Resolving package set"; 459 | let st = 460 | OpamSwitchState.load_virtual ~repos_list gt rt 461 | in 462 | let available = 463 | OpamPackage.Map.filter (fun package opam -> 464 | OpamFilter.eval_to_bool ~default:false 465 | (OpamPackageVar.resolve_switch_raw ~package gt 466 | OpamSwitch.unset OpamFile.Switch_config.empty) 467 | (OpamFile.OPAM.available opam)) 468 | st.opams 469 | |> OpamPackage.keys 470 | in 471 | let st = { st with available_packages = lazy available } in 472 | let unavailable = 473 | let required_atoms = 474 | bootstrap_packages ocamlv @ 475 | packages @ 476 | additional_user_packages ocamlv 477 | in 478 | List.filter (fun (name, _ as atom) -> 479 | not @@ OpamPackage.Set.exists 480 | (OpamFormula.check atom) 481 | (OpamPackage.packages_of_name available name)) 482 | required_atoms 483 | in 484 | if unavailable <> [] then 485 | OpamConsole.error_and_exit `Not_found 486 | "The following packages do not exist in the specified repositories, or \ 487 | are not available with the given configuration:\n%s" 488 | (OpamStd.Format.itemize 489 | (fun (name, cstr as atom) -> 490 | Printf.sprintf "%s: %s" 491 | (OpamFormula.short_string_of_atom atom) 492 | (OpamSwitchState.unavailable_reason st ~default:"not found" 493 | (name, match cstr with None -> OpamFormula.Empty | Some c -> Atom c))) 494 | unavailable); 495 | let st = (* this is just an optimisation, to relieve the solver *) 496 | let filter = 497 | let excl = 498 | OpamFormula.ors 499 | (List.map (fun a -> Atom a) (exclude_packages ocamlv)) 500 | in 501 | OpamPackage.Set.filter (fun nv -> 502 | not @@ OpamFormula.eval (fun at -> OpamFormula.check at nv) excl) 503 | in 504 | { st with 505 | packages = filter st.packages; 506 | available_packages = lazy (filter (Lazy.force st.available_packages)); 507 | } 508 | in 509 | let include_packages = 510 | try OpamListCommand.filter ~base:st.packages st packages_filter 511 | with Failure msg -> 512 | OpamConsole.error "Sorry, no consistent installation could be found \ 513 | including the requested packages."; 514 | OpamConsole.errmsg "%s" msg; 515 | OpamStd.Sys.exit_because `No_solution; 516 | in 517 | let install_packages = 518 | OpamFormula.packages_of_atoms include_packages packages 519 | in 520 | if OpamPackage.Set.is_empty include_packages then 521 | OpamConsole.error_and_exit `No_solution 522 | "No packages match the selection criteria"; 523 | OpamConsole.formatted_msg "The following packages will be included:\n%s" 524 | (OpamStd.Format.itemize (fun nv -> 525 | let color = 526 | if OpamPackage.Set.mem nv install_packages then [`bold; `underline] 527 | else [`bold] 528 | in 529 | OpamConsole.colorise' color (OpamPackage.name_to_string nv) ^"."^ 530 | OpamPackage.version_to_string nv) 531 | (OpamPackage.Set.elements include_packages)); 532 | let avail_constraint = 533 | let rec filter_to_list = function 534 | | FBool true -> [] 535 | | FAnd (f1, f2) -> filter_to_list f1 @ filter_to_list f2 536 | | f -> [f] 537 | in 538 | OpamPackage.Set.fold (fun nv acc -> 539 | FAnd (acc, OpamFile.OPAM.available (OpamSwitchState.opam st nv))) 540 | include_packages (FBool true) |> 541 | OpamFilter.partial_eval (fun v -> 542 | match OpamVariable.Full.to_string v with 543 | | "opam-version" -> Some (S (OpamPackage.Version.to_string opamv)) 544 | | "sys-ocaml-version" -> Some (S (OpamPackage.Version.to_string ocamlv)) 545 | | _ -> None) |> 546 | filter_to_list |> 547 | List.fold_left (fun acc f -> 548 | if List.mem f acc then acc else f::acc) 549 | [] |> 550 | List.fold_left (fun acc f -> 551 | if acc = FBool true then f else FAnd (f,acc)) 552 | (FBool true) 553 | in 554 | if avail_constraint = FBool true then 555 | OpamConsole.formatted_msg 556 | "According to the packages' metadata, the bundle should be installable \ 557 | on %s arch/OS.\n" 558 | (OpamConsole.colorise `bold "any") 559 | else 560 | OpamConsole.formatted_msg 561 | "The bundle will be installable on systems matching the following: %s\n" 562 | (OpamConsole.colorise `bold (OpamFilter.to_string avail_constraint)); 563 | OpamConsole.note 564 | "Opam system sandboxing (introduced in 2.0) will be disabled in the \ 565 | bundle. You need to trust that the build scripts of the included packages \ 566 | don't write outside of their build directory and dest dir."; 567 | if not @@ OpamConsole.confirm "Continue ?" then 568 | OpamStd.Sys.exit_because `Aborted; 569 | (* *** *) 570 | OpamConsole.header_msg "Getting all archives"; 571 | let bundle_dir = OpamFilename.Op.(tmp / bundle_name) in 572 | let compiler_patches_dir = OpamFilename.Op.(bundle_dir / "patches") in 573 | let target_repo = OpamFilename.Op.(bundle_dir / "repo") in 574 | let cache_dirname = "cache" in 575 | let target_cache = OpamFilename.Op.(target_repo / cache_dirname) in 576 | let links_dirname = "archives" in 577 | let target_links = OpamFilename.Op.(target_repo / links_dirname) in 578 | OpamFilename.mkdir target_repo; 579 | OpamFilename.mkdir target_cache; 580 | OpamFilename.mkdir target_links; 581 | let repo_file = 582 | OpamFile.Repo.create 583 | ~dl_cache:[cache_dirname] 584 | () 585 | in 586 | OpamFile.Repo.write (OpamRepositoryPath.repo target_repo) repo_file; 587 | let target_dest f nv = 588 | f target_repo (Some (OpamPackage.name_to_string nv)) nv 589 | in 590 | OpamPackage.Set.iter (fun nv -> 591 | let opam = OpamSwitchState.opam st nv in 592 | let orig_dir = 593 | match OpamFile.OPAM.get_metadata_dir 594 | ~repos_roots:(OpamRepositoryPath.root gt.root) opam with 595 | | Some dir -> dir 596 | | None -> assert false 597 | in 598 | let opam_f = OpamFile.make OpamFilename.Op.(orig_dir // "opam") in 599 | let files_dir = OpamFilename.Op.(orig_dir / "files") in 600 | let opam = OpamSwitchState.opam st nv in 601 | OpamFile.OPAM.write_with_preserved_format ~format_from:opam_f 602 | (target_dest OpamRepositoryPath.opam nv) opam; 603 | if OpamFilename.exists_dir files_dir then 604 | OpamFilename.copy_dir 605 | ~src:files_dir 606 | ~dst:(target_dest OpamRepositoryPath.files nv)) 607 | include_packages; 608 | let pull_to_cache nv = 609 | let link ?extra urlf target = 610 | let name = 611 | OpamStd.Option.default 612 | (OpamUrl.basename (OpamFile.URL.url urlf)) 613 | extra 614 | in 615 | let link = 616 | OpamFilename.Op.(target_links / OpamPackage.to_string nv // name) 617 | in 618 | OpamFilename.link ~relative:true ~target ~link 619 | in 620 | let dl_job ?extra urlf = 621 | let source_string = 622 | Printf.sprintf "%s of %s from %s" 623 | (match extra with None -> "Source" | Some n -> "Extra source "^n) 624 | (OpamPackage.to_string nv) (OpamUrl.to_string (OpamFile.URL.url urlf)) 625 | in 626 | let name = match extra with 627 | | None -> OpamPackage.to_string nv 628 | | Some s -> Printf.sprintf "%s/%s" (OpamPackage.name_to_string nv) s 629 | in 630 | match OpamFile.URL.checksum urlf with 631 | | [] -> 632 | OpamFilename.with_tmp_dir_job @@ fun dldir -> 633 | let f = OpamFilename.Op.(dldir // OpamPackage.to_string nv) in 634 | OpamRepository.pull_file name f [] 635 | (OpamFile.URL.url urlf :: OpamFile.URL.mirrors urlf) 636 | @@| (function 637 | | Not_available (msg, _) -> 638 | OpamConsole.error_and_exit `Sync_error 639 | "%s could not be obtained%s" 640 | source_string (OpamStd.Option.to_string (fun s -> ": "^s) msg) 641 | | Result () | Up_to_date () -> 642 | let hash = OpamHash.compute (OpamFilename.to_string f) in 643 | let dst = OpamRepository.cache_file target_cache hash in 644 | OpamFilename.mkdir (OpamFilename.dirname dst); 645 | OpamFilename.move ~src:f ~dst; 646 | OpamConsole.warning 647 | "%s had no recorded checksum: adding %s" 648 | source_string (OpamHash.to_string hash); 649 | link ?extra urlf dst; 650 | OpamFile.URL.with_checksum [hash] urlf) 651 | | (hash::_) as cksums -> 652 | let dst = OpamRepository.cache_file target_cache hash in 653 | OpamRepository.pull_file_to_cache name 654 | ~cache_dir:target_cache ~cache_urls:dl_cache cksums 655 | (OpamFile.URL.url urlf :: OpamFile.URL.mirrors urlf) 656 | @@| (function 657 | | Not_available (msg, _) -> 658 | OpamConsole.error_and_exit `Sync_error 659 | "%s could not be obtained%s" 660 | source_string (OpamStd.Option.to_string (fun s -> ": "^s) msg) 661 | | Result (_) | Up_to_date (_) -> 662 | link ?extra urlf dst; 663 | urlf) 664 | in 665 | let opam = OpamSwitchState.opam st nv in 666 | let opam0 = opam in 667 | (match OpamPackage.Map.find_opt nv virtual_pins with 668 | | Some archive -> 669 | let hash = OpamHash.compute (OpamFilename.to_string archive) in 670 | let dst = OpamRepository.cache_file target_cache hash in 671 | OpamFilename.copy ~src:archive ~dst; 672 | let urlf = 673 | OpamFile.URL.create ~checksum:[hash] 674 | (OpamUrl.parse ~backend:`http 675 | ("archives/"^OpamFilename.(Base.to_string (basename archive)))) 676 | in 677 | link urlf dst; 678 | Done (OpamFile.OPAM.with_url urlf opam) 679 | | None -> 680 | match OpamFile.OPAM.url opam with 681 | | None -> Done opam 682 | | Some urlf -> 683 | dl_job urlf @@| fun urlf -> OpamFile.OPAM.with_url urlf opam) 684 | @@+ fun opam -> 685 | OpamProcess.Job.seq_map 686 | (fun (name, urlf) -> 687 | dl_job ~extra:(OpamFilename.Base.to_string name) urlf @@| fun urlf -> 688 | name, urlf) 689 | (OpamFile.OPAM.extra_sources opam) 690 | @@| fun extra_sources -> 691 | let opam = OpamFile.OPAM.with_extra_sources extra_sources opam in 692 | (* checking compiler patches *) 693 | if OpamPackage.Name.equal (OpamPackage.name nv) ocaml_base_compiler_package_name 694 | then begin 695 | let extra_sources = OpamFile.OPAM.extra_sources opam in 696 | let extra_files = OpamStd.Option.default [] @@ OpamFile.OPAM.extra_files opam in 697 | let patches = List.map fst @@ OpamFile.OPAM.patches opam in 698 | if patches <> [] then OpamFilename.mkdir compiler_patches_dir; 699 | List.iteri (fun i basename -> 700 | let src = 701 | match List.find_opt (fun (name,_) -> name = basename) extra_sources with 702 | | Some (_, url) -> (* extra-sources *) 703 | let hash = List.hd @@ OpamFile.URL.checksum url in 704 | OpamRepository.cache_file target_cache hash 705 | | None -> 706 | (match List.find_opt (fun (name,_) -> name = basename) extra_files with 707 | | Some _ -> (* extra-files *) 708 | OpamFilename.Op.(target_dest OpamRepositoryPath.files nv 709 | // OpamFilename.Base.to_string basename) 710 | | None -> 711 | OpamConsole.error_and_exit `Not_found 712 | "Patch %s is not found in extra-files or extra-sources." 713 | (OpamFilename.Base.to_string basename)) 714 | in 715 | let name = Format.sprintf "patch%d.patch" i in 716 | OpamFilename.copy ~src ~dst:OpamFilename.Op.(compiler_patches_dir // name)) 717 | patches 718 | end; 719 | if opam <> opam0 then 720 | OpamFile.OPAM.write_with_preserved_format 721 | (target_dest OpamRepositoryPath.opam nv) opam 722 | in 723 | let randomised_pkglist = 724 | (* Some pseudo-randomisation to avoid downloading all files from 725 | the same host simultaneously *) 726 | List.sort (fun nv1 nv2 -> 727 | match compare (Hashtbl.hash nv1) (Hashtbl.hash nv2) with 728 | | 0 -> compare nv1 nv2 729 | | n -> n) 730 | (OpamPackage.Set.elements include_packages) 731 | in 732 | OpamParallel.iter ~jobs:OpamStateConfig.(!r.dl_jobs) 733 | ~command:pull_to_cache 734 | randomised_pkglist; 735 | (* *** *) 736 | OpamConsole.header_msg "Getting bootstrap packages"; 737 | let opam_url = opam_archive_url opamv in 738 | let opam_archive = 739 | OpamFilename.Op.(bundle_dir // OpamUrl.basename opam_url) 740 | in 741 | OpamProcess.Job.run @@ 742 | OpamRepository.pull_file (OpamUrl.basename opam_url) opam_archive 743 | [(*todo:checksums*)] 744 | [opam_url] 745 | @@| (function 746 | | Not_available (msg, _) -> 747 | OpamConsole.error_and_exit `Sync_error 748 | "Opam archive at %s could not be obtained%s" 749 | (OpamUrl.to_string opam_url) 750 | (OpamStd.Option.to_string (fun s -> ": "^s) msg) 751 | | Result () | Up_to_date () -> ()); 752 | (* *** *) 753 | OpamConsole.header_msg "Building bundle"; 754 | let include_scripts = 755 | ["common.sh"; "bootstrap.sh"; "configure.sh"; "compile.sh"; ] 756 | in 757 | let scripts = 758 | let env v = match OpamVariable.Full.to_string v with 759 | | "ocamlv" -> Some (S (OpamPackage.Version.to_string ocamlv)) 760 | | "opam_archive" -> Some (S (OpamUrl.basename opam_url)) 761 | | "install_packages" -> 762 | Some (S (OpamStd.List.concat_map " " OpamPackage.to_string 763 | (OpamPackage.Set.elements install_packages))) 764 | | "doc" -> Some (B doc) 765 | | "test" -> Some (B test) 766 | | _ -> None 767 | in 768 | List.map (fun name -> 769 | name, OpamFilter.expand_string env 770 | (List.assoc name OpamBundleScripts.all_scripts)) 771 | include_scripts 772 | in 773 | List.iter (fun name -> 774 | let script = List.assoc name scripts in 775 | let file = OpamFilename.Op.(bundle_dir // name) in 776 | OpamFilename.write file script; 777 | if name <> "common.sh" then OpamFilename.chmod file 0o755) 778 | include_scripts; 779 | OpamProcess.Job.run 780 | (OpamSystem.make_command ~dir:(OpamFilename.Dir.to_string tmp) 781 | "tar" ["czf"; OpamFilename.to_string output; bundle_name] 782 | @@> fun result -> 783 | OpamSystem.raise_on_process_error result; 784 | OpamConsole.formatted_msg "Done. Bundle generated as %s\n" 785 | (OpamFilename.to_string output); 786 | Done ()); 787 | if self_extract then 788 | let file = 789 | OpamFilename.of_string 790 | (OpamFilename.remove_suffix 791 | (OpamFilename.Base.of_string ("."^output_extension)) 792 | output 793 | ^ ".sh") 794 | in 795 | let script = OpamBundleScripts.self_extract_sh in 796 | let blocksize = 512 in 797 | let rec count_blocks blocks = 798 | let env v = match OpamVariable.Full.to_string v with 799 | | "blocksize" -> Some (S (string_of_int blocksize)) 800 | | "blocks" -> Some (S (string_of_int blocks)) 801 | | _ -> None 802 | in 803 | let s = OpamFilter.expand_string env script in 804 | if String.length s > blocksize * blocks then count_blocks (blocks + 1) 805 | else s, blocks 806 | in 807 | let script, blocks = count_blocks 1 in 808 | let ic = open_in (OpamFilename.to_string output) in 809 | let oc = open_out (OpamFilename.to_string file) in 810 | output_string oc script; 811 | seek_out oc (blocksize * blocks); 812 | let sz = 4096 in 813 | let buf = Bytes.create sz in 814 | let rec copy () = 815 | let len = input ic buf 0 sz in 816 | if len <> 0 then (stdlib_output oc buf 0 len; copy ()) 817 | in 818 | copy (); 819 | close_in ic; 820 | close_out oc; 821 | OpamFilename.chmod file 0o755; 822 | OpamConsole.formatted_msg "Self-extracting archive generated as %s\n" 823 | (OpamFilename.to_string file) 824 | 825 | 826 | (* -- command-line handling -- *) 827 | 828 | open Cmdliner 829 | 830 | let pkg_version_conv = 831 | Arg.conv ~docv:"VERSION" ( 832 | (fun s -> 833 | try Ok (OpamPackage.Version.of_string s) with Failure s -> 834 | Error (`Msg s)), 835 | (fun ppf v -> Format.pp_print_string ppf (OpamPackage.Version.to_string v)) 836 | ) 837 | 838 | let atom_with_target_conv = 839 | Arg.conv ~docv:"PACKAGE" ( 840 | (fun s -> 841 | let atom, target = match OpamStd.String.cut_at s '@' with 842 | | None -> s, None 843 | | Some (atom, target) -> atom, Some target 844 | in 845 | match Arg.conv_parser OpamArg.atom atom with 846 | | Error _ as e -> e 847 | | Ok ((_, cstr) as atom) -> 848 | match target with 849 | | None -> Ok (atom, None) 850 | | Some target -> 851 | match cstr with 852 | | None | Some (`Eq, _) -> 853 | (try Ok (atom, Some (OpamUrl.parse target)) 854 | with Failure s -> Error (`Msg s)) 855 | | _ -> Error (`Msg "Only equality version constraints can be \ 856 | specified together with a target URL")), 857 | (fun ppf (atom, target) -> 858 | Format.fprintf ppf "%a%s" 859 | (Arg.conv_printer OpamArg.atom) atom 860 | (OpamStd.Option.to_string (fun u -> "@" ^ OpamUrl.to_string u) target)) 861 | ) 862 | 863 | let ocamlv_arg = 864 | Arg.(value & opt (some pkg_version_conv) None & info ["ocaml"] ~doc: 865 | "Select a version of OCaml to include. It will be used for \ 866 | bootstrapping, and must be able to compile opam.") 867 | 868 | let opamv_arg = 869 | Arg.(value & opt (some pkg_version_conv) None & info ["opam"] ~doc: 870 | "Select a version of opam to include. That version must be released \ 871 | with an upstream \"full-archive\" available online, and be at least \ 872 | 2.0.0~rc2, to support all the required features.") 873 | 874 | let repo_arg = 875 | Arg.(value & opt_all OpamArg.url [OpamInitDefaults.repository_url] & 876 | info ["repository"] ~docv:"URL" ~doc: 877 | "URLs of the repositories to use (highest priority first). Note that \ 878 | it is required that the OCaml package at the selected version is \ 879 | included (see $(b,--ocaml)), with the hierarchy and alternatives as \ 880 | on the default repository ('ocaml-base-compiler', 'ocaml-system' and \ 881 | 'ocaml-config' packages, with the 'ocaml' wrapper virtual package). \ 882 | This makes it possible to bootstrap opam and compile the requested \ 883 | packages with a single compilation of OCaml.") 884 | 885 | let debug_arg = 886 | Arg.(value & flag & info ["debug"] ~doc: 887 | "Display debug information about what's going on.") 888 | 889 | let output_arg = 890 | Arg.(value & opt (some OpamArg.filename) None & info ["output";"o"] ~doc: 891 | "Output the bundle to the given file.") 892 | 893 | let env_arg = 894 | (* TODO: make repeatable to ensure multiple environments will work! *) 895 | Arg.(value & opt (some (list string)) ~vopt:(Some []) None & 896 | info ["environment"] ~doc: 897 | "Use the given opam environment, in the form of a list of \ 898 | comma-separated 'var=value' bindings, when resolving variables. This \ 899 | is used when computing the set of available packages, where opam \ 900 | uses variables $(i,arch), $(i,os), $(i,os-distribution), \ 901 | $(i,os-version) and $(i,os-family): if undefined, the variables are \ 902 | inferred from the current system. If set without argument, an empty \ 903 | environment is used: this can be used to ensure the generated bundle \ 904 | won't have arch or OS constraints.") 905 | 906 | let with_test_arg = 907 | Arg.(value & flag & info ["t";"with-test"] ~doc: 908 | "Include the packages' test-only dependencies in the bundle, and make \ 909 | the bundle run the tests on installation.") 910 | 911 | let with_doc_arg = 912 | Arg.(value & flag & info ["d";"with-doc"] ~doc: 913 | "Include the packages' doc-only dependencies in the bundle, and \ 914 | make the bundle generate their documentation.") 915 | 916 | let yes_arg = 917 | Arg.(value & flag & info ["y";"yes"] ~doc: 918 | "Confirm all prompts without asking.") 919 | 920 | let self_extract_arg = 921 | Arg.(value & flag & info ["self"] ~doc: 922 | "Generate a self-extracting script besides the .tar.gz bundle") 923 | 924 | let packages_arg = 925 | Arg.(non_empty & pos_all atom_with_target_conv [] & 926 | info [] ~docv:"PACKAGE" ~doc: 927 | "List of packages to include in the bundle. Their dependencies will \ 928 | be included as well, but only listed packages will have wrappers \ 929 | installed. Packages can be specified as $(i,NAME[CONSTRAINT][@URL]), \ 930 | where $(i,CONSTRAINT) is an optional version constraint starting \ 931 | with one of $(i,.) or $(i,=), $(i,!=), $(i,>), $(i,>=), $(i,<) or \ 932 | $(i,<=), and $(i,@URL) can be specified to use the package source \ 933 | from the given URL (in which case, the constraint, if any, must be \ 934 | $(i,.) or $(i,=)).") 935 | 936 | let man = [ 937 | `S "DESCRIPTION"; 938 | `P "This utility can extract a set of packages from opam repositories, and \ 939 | bundle them together in a comprehensive source archive, with the scripts \ 940 | needed to bootstrap OCaml, opam, and install the packages on a fresh, \ 941 | network-less system."; 942 | `P "The opam-depext plugin is included to try and get the required system \ 943 | dependencies on the target system (which might, in this case, require \ 944 | network, depending on the system configuration)."; 945 | `P "The generated bundle includes three scripts, each one calling the \ 946 | previous ones if necessary:"; 947 | `I ("$(i,bootstrap.sh)", 948 | "Compiles OCaml and opam and gets them ready in a local prefix"); 949 | `I ("$(i,configure.sh)", 950 | "Initialises an opam root within the bundle directory, and gets the \ 951 | required system depdendencies"); 952 | `I ("$(i,compile.sh)", 953 | "Compiles the required packages using the bootstrapped opam. If a prefix \ 954 | was specified, and for packages listed on the command-line of $(tname), \ 955 | wrappers are installed to the prefix for installed binaries. These \ 956 | execute the programs within the in-bundle opam root, with the proper \ 957 | opam environment."); 958 | `P "For example, assuming $(i,foo) is a package that installs a $(i,bar) \ 959 | binary, from a bundle generated using $(tname)$(b, foo), a user on a \ 960 | fresh system could run $(b,tar xzf foo-bundle.tar.gz && \ 961 | ./foo-bundle/compile.sh ~/local) to get a usable $(i,bar) binary within \ 962 | $(b,~/local/bin) (if the user does not have write permission to the \ 963 | given prefix, the script will use $(b,sudo))."; 964 | `P "Note that the extracted bundle itself should not be moved for the \ 965 | wrappers to keep working. Besides the wrappers, nothing is written \ 966 | outside of the directory where the bundle was untarred."; 967 | ] 968 | 969 | let create_bundle_command = 970 | Term.(const create_bundle $ ocamlv_arg $ opamv_arg $ repo_arg $ debug_arg $ 971 | output_arg $ env_arg $ with_test_arg $ with_doc_arg $ yes_arg $ 972 | self_extract_arg $ 973 | packages_arg) 974 | 975 | let info = Cmd.info "opam-bundle" ~man ~doc: 976 | "Creates standalone source bundle from opam packages" 977 | 978 | let () = 979 | OpamSystem.init (); 980 | try 981 | match Cmd.eval_value ~catch:false (Cmd.v info create_bundle_command) with 982 | | Error _ -> exit 1 983 | | _ -> exit 0 984 | with 985 | | e -> 986 | flush stdout; 987 | flush stderr; 988 | if (OpamConsole.debug ()) then 989 | Printf.eprintf "'%s' failed.\n" 990 | (String.concat " " (Array.to_list Sys.argv)); 991 | let exit_code = ref 1 in 992 | begin match e with 993 | | OpamStd.Sys.Exit i -> 994 | exit_code := i; 995 | if (OpamConsole.debug ()) && i <> 0 then 996 | Printf.eprintf "%s" (OpamStd.Exn.pretty_backtrace e) 997 | | OpamSystem.Internal_error _ -> 998 | Printf.eprintf "%s\n" (Printexc.to_string e) 999 | | OpamSystem.Process_error result -> 1000 | Printf.eprintf "%s Command %S failed:\n%s\n" 1001 | (OpamConsole.colorise `red "[ERROR]") 1002 | (try List.assoc "command" result.OpamProcess.r_info with 1003 | | Not_found -> "") 1004 | (Printexc.to_string e); 1005 | Printf.eprintf "%s" (OpamStd.Exn.pretty_backtrace e); 1006 | | Sys.Break 1007 | | OpamParallel.Errors (_, (_, Sys.Break)::_, _) -> 1008 | exit_code := 130 1009 | | Sys_error e when e = "Broken pipe" -> 1010 | (* workaround warning 52, this is a fallback (we already handle the 1011 | signal) and there is no way around at the moment *) 1012 | exit_code := 141 1013 | | Failure msg -> 1014 | Printf.eprintf "Fatal error: %s\n" msg; 1015 | Printf.eprintf "%s" (OpamStd.Exn.pretty_backtrace e); 1016 | | _ -> 1017 | Printf.eprintf "Fatal error:\n%s\n" (Printexc.to_string e); 1018 | Printf.eprintf "%s" (OpamStd.Exn.pretty_backtrace e); 1019 | end; 1020 | exit !exit_code 1021 | -------------------------------------------------------------------------------- /tests/dune: -------------------------------------------------------------------------------- 1 | (cram 2 | (applies_to :whole_subtree) 3 | (deps %{bin:opam-bundle})) 4 | -------------------------------------------------------------------------------- /tests/real/odoc.t: -------------------------------------------------------------------------------- 1 | This test verify bundling of real package `odoc` with compiler version 4.02.3 and opam version 2.0. 2 | 3 | $ export OPAMNOENVNOTICE=1 4 | $ export OPAMYES=1 5 | $ export OPAMROOT=$PWD/OPAMROOT 6 | $ export OPAMSTATUSLINE=never 7 | $ export OPAMVERBOSE=-1 8 | $ opam-bundle odoc --ocaml=4.02.3 --opam=2.0 --self --yes 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 9 | OCaml version is set to 4.02.3. 10 | Opam version is set to 2.0.10. 11 | No environment specified, will use the following for package resolution (based on the host system): 12 | - arch = $ARCH 13 | - os = $OS 14 | - os-distribution = $OSDISTRIB 15 | - os-version = $OSVERSION 16 | - os-family = $OSFAMILLY 17 | 18 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 19 | [opam.ocaml.org] Initialised 20 | 21 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 22 | The following packages will be included: 23 | - astring.0.8.3 24 | - base-bigarray.base 25 | - base-bytes.base 26 | - base-ocamlbuild.base 27 | - base-threads.base 28 | - base-unix.base 29 | - camlp-streams.5.0.1 30 | - cmdliner.1.0.2 31 | - cppo.1.6.9 32 | - dune.3.7.1 33 | - fmt.0.8.5 34 | - fpath.0.7.2 35 | - ocaml.4.02.3 36 | - ocaml-base-compiler.4.02.3 37 | - ocaml-bootstrap.4.02.3 38 | - ocaml-config.1 39 | - ocaml-secondary-compiler.4.08.1-1 40 | - ocamlbuild.0 41 | - ocamlfind.1.9.1 42 | - ocamlfind-secondary.1.9.1 43 | - odoc.2.2.0 44 | - odoc-parser.2.0.0 45 | - re.1.10.3 46 | - result.1.4 47 | - seq.0.3.1 48 | - topkg.1.0.0 49 | - tyxml.4.5.0 50 | - uchar.0.0.2 51 | - uutf.1.0.2 52 | The bundle will be installable on systems matching the following: !(os = $OS 53 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 54 | Continue ? [Y/n] y 55 | 56 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 57 | 58 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 59 | 60 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 61 | Done. Bundle generated as $TESTCASE_ROOT/odoc-bundle.tar.gz 62 | Self-extracting archive generated as $TESTCASE_ROOT/odoc-bundle.sh 63 | $ sh ./odoc-bundle.sh -y 64 | This bundle will compile the application to $TESTCASE_ROOT/odoc-bundle, WITHOUT installing 65 | wrappers anywhere else. 66 | 67 | ================ Bootstrap: checking for prerequisites ================ 68 | 69 | Checking for cc... found 70 | Checking for make... found 71 | Checking for wget curl... found 72 | Checking for patch... found 73 | Checking for unzip... found 74 | Checking for bunzip2... found 75 | Checking for rsync... found 76 | 77 | ================ Bootstrap: compiling OCaml ================ 78 | 79 | This may take a while. Output is in $TESTCASE_ROOT/odoc-bundle/bootstrap.log 80 | Uncompressing... done 81 | Applying patches... done 82 | Configuring... done 83 | Compiling... done 84 | Installing to temp prefix... done 85 | 86 | ================ Bootstrap: compiling opam ================ 87 | 88 | This may take a while. Output is in $TESTCASE_ROOT/odoc-bundle/bootstrap.log 89 | Uncompressing... done 90 | Configuring... done 91 | Compiling extra dependencies... done 92 | Compiling... done 93 | Installing to temp prefix... done 94 | 95 | ================ Configure: initialising opam ================ 96 | 97 | Output is in $TESTCASE_ROOT/odoc-bundle/configure.log 98 | Initialising... done 99 | Creating sandbox... done 100 | 101 | ================ Compile: installing packages ================ 102 | 103 | Output is in $TESTCASE_ROOT/odoc-bundle/compile.log 104 | Compiling packages... done 105 | Cleaning up... done 106 | 107 | All compiled within $TESTCASE_ROOT/odoc-bundle. To use the compiled packages: 108 | 109 | - either re-run odoc-bundle/compile.sh with a PREFIX argument to install command wrappers 110 | (it won't recompile everything) 111 | 112 | - or run the following to update the environment in the current shell, so that 113 | they are in your PATH: 114 | export PATH="$TESTCASE_ROOT/odoc-bundle/bootstrap/bin:$PATH"; eval $(opam env --root "$TESTCASE_ROOT/odoc-bundle/opam" --set-root) 115 | 116 | $ sh ./odoc-bundle/compile.sh ../ODOC 117 | This bundle will compile the application to $TESTCASE_ROOT/odoc-bundle, and put wrappers into 118 | ../ODOC/bin. You will need to retain $TESTCASE_ROOT/odoc-bundle for the wrappers to work. 119 | 120 | Press enter to continue... 121 | ================ Bootstrap: checking for prerequisites ================ 122 | 123 | Checking for cc... found 124 | Checking for make... found 125 | Checking for wget curl... found 126 | Checking for patch... found 127 | Checking for unzip... found 128 | Checking for bunzip2... found 129 | Checking for rsync... found 130 | Already compiled OCaml found 131 | Already compiled opam found 132 | Already initialised opam sandbox found 133 | 134 | ================ Compile: installing packages ================ 135 | 136 | Output is in $TESTCASE_ROOT/odoc-bundle/compile.log 137 | Compiling packages... done 138 | Cleaning up... done 139 | Wrapper odoc installed successfully. 140 | $ ODOC/bin/odoc 141 | Available subcommands: compile, link, html-generate, support-files, man-generate, latex-generate, html-url, latex-url, support-files-targets, errors, html-targets, man-targets, latex-targets, compile-deps, compile-targets, html-fragment, html, man, latex, link-deps, css, html-deps 142 | See --help for more information. 143 | -------------------------------------------------------------------------------- /tests/real/opam-bundle.t: -------------------------------------------------------------------------------- 1 | This test verify bundling of real package `opam-bundle` of version 0.4. 2 | 3 | $ export OPAMNOENVNOTICE=1 4 | $ export OPAMYES=1 5 | $ export OPAMROOT=$PWD/OPAMROOT 6 | $ export OPAMSTATUSLINE=never 7 | $ export OPAMVERBOSE=-1 8 | $ opam-bundle "opam-bundle@https://github.com/AltGr/opam-bundle/archive/refs/tags/0.4.tar.gz" opam-client.2.0.10 --self --opam=2.1 --ocaml=4.14.0 --yes 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 9 | OCaml version is set to 4.14.0. 10 | Opam version is set to 2.1.4. 11 | No environment specified, will use the following for package resolution (based on the host system): 12 | - arch = $ARCH 13 | - os = $OS 14 | - os-distribution = $OSDISTRIB 15 | - os-version = $OSVERSION 16 | - os-family = $OSFAMILLY 17 | 18 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 19 | [opam.ocaml.org] Initialised 20 | 21 | <><> Getting external packages ><><><><><><><><><><><><><><><><><><><><><><><><> 22 | [NOTE] Will use package definition found in source for opam-bundle 23 | 24 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 25 | The following packages will be included: 26 | - base-bigarray.base 27 | - base-bytes.base 28 | - base-threads.base 29 | - base-unix.base 30 | - cmdliner.1.2.0 31 | - cppo.1.6.9 32 | - cudf.0.10 33 | - dose3.5.0.1-2 34 | - dune.3.7.1 35 | - extlib.1.7.7-1 36 | - mccs.1.1+14 37 | - ocaml.4.14.0 38 | - ocaml-base-compiler.4.14.0 39 | - ocaml-bootstrap.4.14.0 40 | - ocaml-config.2 41 | - ocaml-options-vanilla.1 42 | - ocamlbuild.0.14.2 43 | - ocamlfind.1.9.6 44 | - ocamlgraph.2.0.0 45 | - opam-bundle.0.4 46 | - opam-client.2.0.10 47 | - opam-core.2.0.10 48 | - opam-file-format.2.1.6 49 | - opam-format.2.0.10 50 | - opam-repository.2.0.10 51 | - opam-solver.2.0.10 52 | - opam-state.2.0.10 53 | - re.1.10.4 54 | - seq.base 55 | - stdlib-shims.0.3.0 56 | The bundle will be installable on systems matching the following: os != "win32" 57 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 58 | Continue ? [Y/n] y 59 | 60 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 61 | 62 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 63 | 64 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 65 | Done. Bundle generated as $TESTCASE_ROOT/opam-bundle-bundle.tar.gz 66 | Self-extracting archive generated as $TESTCASE_ROOT/opam-bundle-bundle.sh 67 | $ sh ./opam-bundle-bundle.sh -y 68 | This bundle will compile the application to $TESTCASE_ROOT/opam-bundle-bundle, WITHOUT installing 69 | wrappers anywhere else. 70 | 71 | ================ Bootstrap: checking for prerequisites ================ 72 | 73 | Checking for cc... found 74 | Checking for make... found 75 | Checking for wget curl... found 76 | Checking for patch... found 77 | Checking for unzip... found 78 | Checking for bunzip2... found 79 | Checking for rsync... found 80 | 81 | ================ Bootstrap: compiling OCaml ================ 82 | 83 | This may take a while. Output is in $TESTCASE_ROOT/opam-bundle-bundle/bootstrap.log 84 | Uncompressing... done 85 | Configuring... done 86 | Compiling... done 87 | Installing to temp prefix... done 88 | 89 | ================ Bootstrap: compiling opam ================ 90 | 91 | This may take a while. Output is in $TESTCASE_ROOT/opam-bundle-bundle/bootstrap.log 92 | Uncompressing... done 93 | Configuring... done 94 | Compiling extra dependencies... done 95 | Compiling... done 96 | Installing to temp prefix... done 97 | 98 | ================ Configure: initialising opam ================ 99 | 100 | Output is in $TESTCASE_ROOT/opam-bundle-bundle/configure.log 101 | Initialising... done 102 | Creating sandbox... done 103 | 104 | ================ Compile: installing packages ================ 105 | 106 | Output is in $TESTCASE_ROOT/opam-bundle-bundle/compile.log 107 | Compiling packages... done 108 | Cleaning up... done 109 | 110 | All compiled within $TESTCASE_ROOT/opam-bundle-bundle. To use the compiled packages: 111 | 112 | - either re-run opam-bundle-bundle/compile.sh with a PREFIX argument to install command wrappers 113 | (it won't recompile everything) 114 | 115 | - or run the following to update the environment in the current shell, so that 116 | they are in your PATH: 117 | export PATH="$TESTCASE_ROOT/opam-bundle-bundle/bootstrap/bin:$PATH"; eval $(opam env --root "$TESTCASE_ROOT/opam-bundle-bundle/opam" --set-root) 118 | 119 | $ sh ./opam-bundle-bundle/compile.sh ../BUNDLE 120 | This bundle will compile the application to $TESTCASE_ROOT/opam-bundle-bundle, and put wrappers into 121 | ../BUNDLE/bin. You will need to retain $TESTCASE_ROOT/opam-bundle-bundle for the wrappers to work. 122 | 123 | Press enter to continue... 124 | ================ Bootstrap: checking for prerequisites ================ 125 | 126 | Checking for cc... found 127 | Checking for make... found 128 | Checking for wget curl... found 129 | Checking for patch... found 130 | Checking for unzip... found 131 | Checking for bunzip2... found 132 | Checking for rsync... found 133 | Already compiled OCaml found 134 | Already compiled opam found 135 | Already initialised opam sandbox found 136 | 137 | ================ Compile: installing packages ================ 138 | 139 | Output is in $TESTCASE_ROOT/opam-bundle-bundle/compile.log 140 | Compiling packages... done 141 | Cleaning up... done 142 | Wrapper opam-bundle installed successfully. 143 | $ BUNDLE/bin/opam-bundle 144 | opam-bundle: required argument PACKAGE is missing 145 | Usage: opam-bundle [OPTION]… PACKAGE… 146 | Try 'opam-bundle --help' for more information. 147 | [1] 148 | -------------------------------------------------------------------------------- /tests/stub/basic.t: -------------------------------------------------------------------------------- 1 | This test verify basic functionalities of `opam-bundle`. Every package used is a stub package. 2 | More complex tests on various options could be found in *stub* directory. Tests with real repositories 3 | and packages are under *complex* directory. 4 | 5 | Repo initial setup with two packages `foo` and `bar` that depends on `foo` and other required packages. 6 | $ export OPAMNOENVNOTICE=1 7 | $ export OPAMYES=1 8 | $ export OPAMROOT=$PWD/OPAMROOT 9 | $ export OPAMSTATUSLINE=never 10 | $ export OPAMVERBOSE=-1 11 | $ cat > compile << EOF 12 | > #!/bin/sh 13 | > echo "I'm launching \$(basename \${0}) \$@!" 14 | > EOF 15 | $ chmod +x compile 16 | $ tar czf compile.tar.gz compile 17 | $ SHA=`openssl sha256 compile.tar.gz | cut -d ' ' -f 2` 18 | OCaml archive setup 19 | $ mkdir ocaml-4.14.0 20 | $ cat > ocaml-4.14.0/configure << EOF 21 | > set -uex 22 | > sed -i "s:PREFIX:\$2:g" Makefile 23 | > echo "configured" 24 | > EOF 25 | $ chmod +x ocaml-4.14.0/configure 26 | $ cat > ocaml-4.14.0/Makefile << EOF 27 | > world: 28 | > echo "make world" 29 | > world.opt: 30 | > echo "world opt" 31 | > install: 32 | > mkdir -p PREFIX/bin/ 33 | > cp ocaml PREFIX/bin/ 34 | > cp ocamlc PREFIX/bin/ 35 | > cp ocamlopt PREFIX/bin/ 36 | > cp $(which opam) PREFIX/bin/ 37 | > EOF 38 | $ cat > ocaml-4.14.0/ocaml << EOF 39 | > echo "I'm compiling \$1!" 40 | > EOF 41 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlc 42 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlopt 43 | $ tar czf ocaml.tar.gz ocaml-4.14.0 44 | $ OCAMLSHA=`openssl sha256 ocaml.tar.gz | cut -d ' ' -f 2` 45 | Repo setup 46 | $ mkdir -p REPO/packages/ 47 | $ cat > REPO/repo << EOF 48 | > opam-version: "2.0" 49 | > EOF 50 | Foo package. 51 | $ mkdir -p REPO/packages/foo/foo.1 52 | $ cat > REPO/packages/foo/foo.1/opam << EOF 53 | > opam-version: "2.0" 54 | > build: [ "sh" "compile" name ] 55 | > install: [ 56 | > [ "cp" "compile" "%{bin}%/%{name}%" ] 57 | > ] 58 | > url { 59 | > src: "file://./compile.tar.gz" 60 | > checksum: "sha256=$SHA" 61 | > } 62 | > EOF 63 | Bar package. 64 | $ mkdir -p REPO/packages/bar/bar.1 65 | $ cat > REPO/packages/bar/bar.1/opam << EOF 66 | > opam-version: "2.0" 67 | > build: [ "sh" "compile" name ] 68 | > install: [ 69 | > [ "cp" "compile" "%{bin}%/%{name}%" ] 70 | > ] 71 | > depends: [ "foo" ] 72 | > url { 73 | > src: "file://./compile.tar.gz" 74 | > checksum: "sha256=$SHA" 75 | > } 76 | > EOF 77 | Ocaml-system.4.14.0 package. 78 | $ mkdir -p REPO/packages/ocaml-system/ocaml-system.4.14.0 79 | $ cat > REPO/packages/ocaml-system/ocaml-system.4.14.0/opam << EOF 80 | > opam-version: "2.0" 81 | > EOF 82 | Ocaml-config.2 package. 83 | $ mkdir -p REPO/packages/ocaml-config/ocaml-config.2 84 | $ cat > REPO/packages/ocaml-config/ocaml-config.2/opam << EOF 85 | > opam-version: "2.0" 86 | > EOF 87 | Ocaml.4.14.0 package. 88 | $ mkdir -p REPO/packages/ocaml/ocaml.4.14.0 89 | $ cat > REPO/packages/ocaml/ocaml.4.14.0/opam << EOF 90 | > opam-version: "2.0" 91 | > depends: [ 92 | > ("ocaml-system" | "ocaml-base-compiler") 93 | > "ocaml-config" 94 | > ] 95 | > url { 96 | > src: "file://./compile.tar.gz" 97 | > checksum: "sha256=$SHA" 98 | > } 99 | > EOF 100 | Ocaml-base-compiler.4.14.0 package. 101 | $ mkdir -p REPO/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0 102 | $ cat > REPO/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam << EOF 103 | > opam-version: "2.0" 104 | > build: [ "sh" "compile" name ] 105 | > install: [ 106 | > [ "chmod" "+x" "compile" ] 107 | > [ "cp" "compile" "%{bin}%/ocaml" ] 108 | > ] 109 | > url { 110 | > src: "file://./ocaml.tar.gz" 111 | > checksum: "sha256=$OCAMLSHA" 112 | > } 113 | > EOF 114 | Opam setup 115 | $ mkdir $OPAMROOT 116 | $ opam init --bare ./REPO --no-setup --bypass-checks 117 | No configuration file found, using built-in defaults. 118 | 119 | <><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> 120 | [default] Initialised 121 | $ opam switch create one --empty 122 | 123 | 124 | 125 | Running opam-bundle with sanitized output that contains remplaced platform specific information. 126 | 127 | 128 | ============================== Test 1 ============================== 129 | 130 | 131 | Bundle single package `foo`. 132 | 133 | $ opam-bundle foo.1 --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 134 | OCaml version is set to 4.14.0. 135 | No opam version selected, will use 2.1.4. 136 | No environment specified, will use the following for package resolution (based on the host system): 137 | - arch = $ARCH 138 | - os = $OS 139 | - os-distribution = $OSDISTRIB 140 | - os-version = $OSVERSION 141 | - os-family = $OSFAMILLY 142 | 143 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 144 | [home] Initialised 145 | 146 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 147 | The following packages will be included: 148 | - foo.1 149 | - ocaml-base-compiler.4.14.0 150 | - ocaml-bootstrap.4.14.0 151 | According to the packages' metadata, the bundle should be installable on any arch/OS. 152 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 153 | Continue ? [Y/n] y 154 | 155 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 156 | 157 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 158 | 159 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 160 | Done. Bundle generated as $TESTCASE_ROOT/foo-bundle.tar.gz 161 | $ tar xvf foo-bundle.tar.gz | grep -v sha256 | sort 162 | foo-bundle/ 163 | foo-bundle/bootstrap.sh 164 | foo-bundle/common.sh 165 | foo-bundle/compile.sh 166 | foo-bundle/configure.sh 167 | foo-bundle/opam-full-2.1.4.tar.gz 168 | foo-bundle/repo/ 169 | foo-bundle/repo/archives/ 170 | foo-bundle/repo/archives/foo.1/ 171 | foo-bundle/repo/archives/foo.1/compile.tar.gz 172 | foo-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 173 | foo-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 174 | foo-bundle/repo/cache/ 175 | foo-bundle/repo/packages/ 176 | foo-bundle/repo/packages/foo/ 177 | foo-bundle/repo/packages/foo/foo.1/ 178 | foo-bundle/repo/packages/foo/foo.1/opam 179 | foo-bundle/repo/packages/ocaml-base-compiler/ 180 | foo-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 181 | foo-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 182 | foo-bundle/repo/packages/ocaml-bootstrap/ 183 | foo-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 184 | foo-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 185 | foo-bundle/repo/repo 186 | $ sh ./foo-bundle/compile.sh 187 | This bundle will compile the application to $TESTCASE_ROOT/foo-bundle, WITHOUT installing 188 | wrappers anywhere else. 189 | 190 | Press enter to continue... 191 | ================ Bootstrap: checking for prerequisites ================ 192 | 193 | Checking for cc... found 194 | Checking for make... found 195 | Checking for wget curl... found 196 | Checking for patch... found 197 | Checking for unzip... found 198 | Checking for bunzip2... found 199 | Checking for rsync... found 200 | 201 | ================ Bootstrap: compiling OCaml ================ 202 | 203 | This may take a while. Output is in $TESTCASE_ROOT/foo-bundle/bootstrap.log 204 | Uncompressing... done 205 | Configuring... done 206 | Compiling... done 207 | Installing to temp prefix... done 208 | Already compiled opam found 209 | 210 | ================ Configure: initialising opam ================ 211 | 212 | Output is in $TESTCASE_ROOT/foo-bundle/configure.log 213 | Initialising... done 214 | Creating sandbox... done 215 | 216 | ================ Compile: installing packages ================ 217 | 218 | Output is in $TESTCASE_ROOT/foo-bundle/compile.log 219 | Compiling packages... done 220 | Cleaning up... done 221 | 222 | All compiled within $TESTCASE_ROOT/foo-bundle. To use the compiled packages: 223 | 224 | - either re-run ./foo-bundle/compile.sh with a PREFIX argument to install command wrappers 225 | (it won't recompile everything) 226 | 227 | - or run the following to update the environment in the current shell, so that 228 | they are in your PATH: 229 | export PATH="$TESTCASE_ROOT/foo-bundle/bootstrap/bin:$PATH"; eval $(opam env --root "$TESTCASE_ROOT/foo-bundle/opam" --set-root) 230 | 231 | $ opam exec --root ./foo-bundle/opam -- foo 232 | I'm launching foo ! 233 | 234 | 235 | ============================== Test 2 ============================== 236 | 237 | 238 | Bundle package `bar` that depends on `foo`. 239 | 240 | $ opam-bundle bar.1 --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 241 | OCaml version is set to 4.14.0. 242 | No opam version selected, will use 2.1.4. 243 | No environment specified, will use the following for package resolution (based on the host system): 244 | - arch = $ARCH 245 | - os = $OS 246 | - os-distribution = $OSDISTRIB 247 | - os-version = $OSVERSION 248 | - os-family = $OSFAMILLY 249 | 250 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 251 | [home] Initialised 252 | 253 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 254 | The following packages will be included: 255 | - bar.1 256 | - foo.1 257 | - ocaml-base-compiler.4.14.0 258 | - ocaml-bootstrap.4.14.0 259 | According to the packages' metadata, the bundle should be installable on any arch/OS. 260 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 261 | Continue ? [Y/n] y 262 | 263 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 264 | 265 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 266 | 267 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 268 | Done. Bundle generated as $TESTCASE_ROOT/bar-bundle.tar.gz 269 | $ tar xvf bar-bundle.tar.gz | grep -v sha256 | sort 270 | bar-bundle/ 271 | bar-bundle/bootstrap.sh 272 | bar-bundle/common.sh 273 | bar-bundle/compile.sh 274 | bar-bundle/configure.sh 275 | bar-bundle/opam-full-2.1.4.tar.gz 276 | bar-bundle/repo/ 277 | bar-bundle/repo/archives/ 278 | bar-bundle/repo/archives/bar.1/ 279 | bar-bundle/repo/archives/bar.1/compile.tar.gz 280 | bar-bundle/repo/archives/foo.1/ 281 | bar-bundle/repo/archives/foo.1/compile.tar.gz 282 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 283 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 284 | bar-bundle/repo/cache/ 285 | bar-bundle/repo/packages/ 286 | bar-bundle/repo/packages/bar/ 287 | bar-bundle/repo/packages/bar/bar.1/ 288 | bar-bundle/repo/packages/bar/bar.1/opam 289 | bar-bundle/repo/packages/foo/ 290 | bar-bundle/repo/packages/foo/foo.1/ 291 | bar-bundle/repo/packages/foo/foo.1/opam 292 | bar-bundle/repo/packages/ocaml-base-compiler/ 293 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 294 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 295 | bar-bundle/repo/packages/ocaml-bootstrap/ 296 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 297 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 298 | bar-bundle/repo/repo 299 | $ sh ./bar-bundle/compile.sh ../BAR 300 | This bundle will compile the application to $TESTCASE_ROOT/bar-bundle, and put wrappers into 301 | ../BAR/bin. You will need to retain $TESTCASE_ROOT/bar-bundle for the wrappers to work. 302 | 303 | Press enter to continue... 304 | ================ Bootstrap: checking for prerequisites ================ 305 | 306 | Checking for cc... found 307 | Checking for make... found 308 | Checking for wget curl... found 309 | Checking for patch... found 310 | Checking for unzip... found 311 | Checking for bunzip2... found 312 | Checking for rsync... found 313 | 314 | ================ Bootstrap: compiling OCaml ================ 315 | 316 | This may take a while. Output is in $TESTCASE_ROOT/bar-bundle/bootstrap.log 317 | Uncompressing... done 318 | Configuring... done 319 | Compiling... done 320 | Installing to temp prefix... done 321 | Already compiled opam found 322 | 323 | ================ Configure: initialising opam ================ 324 | 325 | Output is in $TESTCASE_ROOT/bar-bundle/configure.log 326 | Initialising... done 327 | Creating sandbox... done 328 | 329 | ================ Compile: installing packages ================ 330 | 331 | Output is in $TESTCASE_ROOT/bar-bundle/compile.log 332 | Compiling packages... done 333 | Cleaning up... done 334 | Wrapper bar installed successfully. 335 | $ opam exec --root ./bar-bundle/opam -- bar 336 | I'm launching bar ! 337 | $ opam exec --root ./bar-bundle/opam -- foo 338 | I'm launching foo ! 339 | $ find BAR | sort 340 | BAR 341 | BAR/bin 342 | BAR/bin/bar 343 | $ BAR/bin/bar 344 | I'm launching bar ! 345 | 346 | Cleaning up 347 | $ rm -r BAR bar-bundle bar-bundle.tar.gz 348 | 349 | 350 | 351 | ============================== Test 3 ============================== 352 | 353 | 354 | Bundle package `bar` that depends on `foo` with self-extracting script. 355 | 356 | $ opam-bundle bar.1 --self --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 357 | OCaml version is set to 4.14.0. 358 | No opam version selected, will use 2.1.4. 359 | No environment specified, will use the following for package resolution (based on the host system): 360 | - arch = $ARCH 361 | - os = $OS 362 | - os-distribution = $OSDISTRIB 363 | - os-version = $OSVERSION 364 | - os-family = $OSFAMILLY 365 | 366 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 367 | [home] Initialised 368 | 369 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 370 | The following packages will be included: 371 | - bar.1 372 | - foo.1 373 | - ocaml-base-compiler.4.14.0 374 | - ocaml-bootstrap.4.14.0 375 | According to the packages' metadata, the bundle should be installable on any arch/OS. 376 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 377 | Continue ? [Y/n] y 378 | 379 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 380 | 381 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 382 | 383 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 384 | Done. Bundle generated as $TESTCASE_ROOT/bar-bundle.tar.gz 385 | Self-extracting archive generated as $TESTCASE_ROOT/bar-bundle.sh 386 | 387 | $ sh ./bar-bundle.sh -y 388 | This bundle will compile the application to $TESTCASE_ROOT/bar-bundle, WITHOUT installing 389 | wrappers anywhere else. 390 | 391 | ================ Bootstrap: checking for prerequisites ================ 392 | 393 | Checking for cc... found 394 | Checking for make... found 395 | Checking for wget curl... found 396 | Checking for patch... found 397 | Checking for unzip... found 398 | Checking for bunzip2... found 399 | Checking for rsync... found 400 | 401 | ================ Bootstrap: compiling OCaml ================ 402 | 403 | This may take a while. Output is in $TESTCASE_ROOT/bar-bundle/bootstrap.log 404 | Uncompressing... done 405 | Configuring... done 406 | Compiling... done 407 | Installing to temp prefix... done 408 | Already compiled opam found 409 | 410 | ================ Configure: initialising opam ================ 411 | 412 | Output is in $TESTCASE_ROOT/bar-bundle/configure.log 413 | Initialising... done 414 | Creating sandbox... done 415 | 416 | ================ Compile: installing packages ================ 417 | 418 | Output is in $TESTCASE_ROOT/bar-bundle/compile.log 419 | Compiling packages... done 420 | Cleaning up... done 421 | 422 | All compiled within $TESTCASE_ROOT/bar-bundle. To use the compiled packages: 423 | 424 | - either re-run bar-bundle/compile.sh with a PREFIX argument to install command wrappers 425 | (it won't recompile everything) 426 | 427 | - or run the following to update the environment in the current shell, so that 428 | they are in your PATH: 429 | export PATH="$TESTCASE_ROOT/bar-bundle/bootstrap/bin:$PATH"; eval $(opam env --root "$TESTCASE_ROOT/bar-bundle/opam" --set-root) 430 | 431 | 432 | $ opam exec --root ./bar-bundle/opam -- bar 433 | I'm launching bar ! 434 | $ opam exec --root ./bar-bundle/opam -- foo 435 | I'm launching foo ! 436 | -------------------------------------------------------------------------------- /tests/stub/env.t: -------------------------------------------------------------------------------- 1 | This test verify different environment specifications that could be used with `opam-bundle`. 2 | Every package used is a stub package. 3 | 4 | Repo initial setup with three packages `foo`, `bar`, and `baz`, with specific availabilities 5 | $ export OPAMNOENVNOTICE=1 6 | $ export OPAMYES=1 7 | $ export OPAMROOT=$PWD/OPAMROOT 8 | $ export OPAMSTATUSLINE=never 9 | $ export OPAMVERBOSE=-1 10 | Stub executable 11 | $ cat > compile << EOF 12 | > #!/bin/sh 13 | > echo "I'm launching \$(basename \${0}) \$@!" 14 | > EOF 15 | $ chmod +x compile 16 | $ tar czf compile.tar.gz compile 17 | $ SHA=`openssl sha256 compile.tar.gz | cut -d ' ' -f 2` 18 | OCaml archive setup 19 | $ mkdir ocaml-4.14.0 20 | $ cat > ocaml-4.14.0/configure << EOF 21 | > set -uex 22 | > sed -i "s:PREFIX:\$2:g" Makefile 23 | > echo "configured" 24 | > EOF 25 | $ chmod +x ocaml-4.14.0/configure 26 | $ cat > ocaml-4.14.0/Makefile << EOF 27 | > world: 28 | > echo "make world" 29 | > world.opt: 30 | > echo "world opt" 31 | > install: 32 | > mkdir -p PREFIX/bin/ 33 | > cp ocaml PREFIX/bin/ 34 | > cp ocamlc PREFIX/bin/ 35 | > cp ocamlopt PREFIX/bin/ 36 | > cp $(which opam) PREFIX/bin/ 37 | > EOF 38 | $ cat > ocaml-4.14.0/ocaml << EOF 39 | > echo "I'm compiling \$1!" 40 | > EOF 41 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlc 42 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlopt 43 | $ tar czf ocaml.tar.gz ocaml-4.14.0 44 | $ OCAMLSHA=`openssl sha256 ocaml.tar.gz | cut -d ' ' -f 2` 45 | Repo setup 46 | $ mkdir -p REPO/packages/ 47 | $ cat > REPO/repo << EOF 48 | > opam-version: "2.0" 49 | > EOF 50 | === Foo package (not available on linux) === 51 | $ mkdir -p REPO/packages/foo/foo.1 52 | $ cat > REPO/packages/foo/foo.1/opam << EOF 53 | > opam-version: "2.0" 54 | > version: "1" 55 | > available: (os != "linux") 56 | > build: [ "sh" "compile" name ] 57 | > install: [ 58 | > [ "cp" "compile" "%{bin}%/%{name}%" ] 59 | > ] 60 | > depends : [ 61 | > "ocaml" {>= "4.12.0"} 62 | > ] 63 | > url { 64 | > src: "file://./compile.tar.gz" 65 | > checksum: "sha256=$SHA" 66 | > } 67 | > EOF 68 | === Bar package (not available on cygwin) === 69 | $ mkdir -p REPO/packages/bar/bar.1 70 | $ cat > REPO/packages/bar/bar.1/opam << EOF 71 | > opam-version: "2.0" 72 | > version: "1" 73 | > available: (os != "cygwin") 74 | > build: [ "sh" "compile" name ] 75 | > install: [ 76 | > [ "cp" "compile" "%{bin}%/%{name}%" ] 77 | > ] 78 | > depends : [ 79 | > "ocaml" {>= "4.14.0"} 80 | > ] 81 | > url { 82 | > src: "file://./compile.tar.gz" 83 | > checksum: "sha256=$SHA" 84 | > } 85 | > EOF 86 | === Baz packages (available on both) === 87 | $ mkdir -p REPO/packages/baz/baz.1 88 | $ cat > REPO/packages/baz/baz.1/opam << EOF 89 | > opam-version: "2.0" 90 | > version: "1" 91 | > build: [ "sh" "compile" name ] 92 | > install: [ 93 | > [ "cp" "compile" "%{bin}%/%{name}%" ] 94 | > ] 95 | > depends : [ 96 | > "ocaml" {>= "4.14.0"} 97 | > "foo" { os != "linux" } 98 | > "bar" { os != "cygwin" } 99 | > ] 100 | > url { 101 | > src: "file://./compile.tar.gz" 102 | > checksum: "sha256=$SHA" 103 | > } 104 | > EOF 105 | Ocaml-system.4.14.0 package. 106 | $ mkdir -p REPO/packages/ocaml-system/ocaml-system.4.14.0 107 | $ cat > REPO/packages/ocaml-system/ocaml-system.4.14.0/opam << EOF 108 | > opam-version: "2.0" 109 | > EOF 110 | Ocaml-config.2 package. 111 | $ mkdir -p REPO/packages/ocaml-config/ocaml-config.2 112 | $ cat > REPO/packages/ocaml-config/ocaml-config.2/opam << EOF 113 | > opam-version: "2.0" 114 | > EOF 115 | Ocaml.4.14.0 package. 116 | $ mkdir -p REPO/packages/ocaml/ocaml.4.14.0 117 | $ cat > REPO/packages/ocaml/ocaml.4.14.0/opam << EOF 118 | > opam-version: "2.0" 119 | > depends: [ 120 | > ("ocaml-system" | "ocaml-base-compiler") 121 | > "ocaml-config" 122 | > ] 123 | > url { 124 | > src: "file://./compile.tar.gz" 125 | > checksum: "sha256=$SHA" 126 | > } 127 | > EOF 128 | Ocaml-base-compiler.4.14.0 package. 129 | $ mkdir -p REPO/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0 130 | $ cat > REPO/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam << EOF 131 | > opam-version: "2.0" 132 | > build: [ "sh" "compile" name ] 133 | > install: [ 134 | > [ "chmod" "+x" "compile" ] 135 | > [ "cp" "compile" "%{bin}%/ocaml" ] 136 | > ] 137 | > url { 138 | > src: "file://./ocaml.tar.gz" 139 | > checksum: "sha256=$OCAMLSHA" 140 | > } 141 | > EOF 142 | Opam setup 143 | $ mkdir $OPAMROOT 144 | $ opam init --bare ./REPO --no-setup --bypass-checks 145 | No configuration file found, using built-in defaults. 146 | 147 | <><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> 148 | [default] Initialised 149 | $ opam switch create one --empty 150 | 151 | 152 | 153 | Running opam-bundle with sanitized output that contains replaced platform specific information. 154 | 155 | 156 | ============================== Test 1 ============================== 157 | 158 | 159 | Bundle package `baz`, without '--environment' option. That should lookup current platform (that should be linux), and filter packages in dependencies that 160 | are available on linux os (`foo` not included). 161 | 162 | $ opam-bundle baz --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 163 | OCaml version is set to 4.14.0. 164 | No opam version selected, will use 2.1.4. 165 | No environment specified, will use the following for package resolution (based on the host system): 166 | - arch = $ARCH 167 | - os = $OS 168 | - os-distribution = $OSDISTRIB 169 | - os-version = $OSVERSION 170 | - os-family = $OSFAMILLY 171 | 172 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 173 | [home] Initialised 174 | 175 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 176 | The following packages will be included: 177 | - bar.1 178 | - baz.1 179 | - ocaml.4.14.0 180 | - ocaml-base-compiler.4.14.0 181 | - ocaml-bootstrap.4.14.0 182 | - ocaml-config.2 183 | The bundle will be installable on systems matching the following: os != "cygwin" 184 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 185 | Continue ? [Y/n] y 186 | 187 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 188 | 189 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 190 | 191 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 192 | Done. Bundle generated as $TESTCASE_ROOT/baz-bundle.tar.gz 193 | $ tar --list -f baz-bundle.tar.gz | grep -v sha256 | sort 194 | baz-bundle/ 195 | baz-bundle/bootstrap.sh 196 | baz-bundle/common.sh 197 | baz-bundle/compile.sh 198 | baz-bundle/configure.sh 199 | baz-bundle/opam-full-2.1.4.tar.gz 200 | baz-bundle/repo/ 201 | baz-bundle/repo/archives/ 202 | baz-bundle/repo/archives/bar.1/ 203 | baz-bundle/repo/archives/bar.1/compile.tar.gz 204 | baz-bundle/repo/archives/baz.1/ 205 | baz-bundle/repo/archives/baz.1/compile.tar.gz 206 | baz-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 207 | baz-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 208 | baz-bundle/repo/archives/ocaml.4.14.0/ 209 | baz-bundle/repo/archives/ocaml.4.14.0/compile.tar.gz 210 | baz-bundle/repo/cache/ 211 | baz-bundle/repo/packages/ 212 | baz-bundle/repo/packages/bar/ 213 | baz-bundle/repo/packages/bar/bar.1/ 214 | baz-bundle/repo/packages/bar/bar.1/opam 215 | baz-bundle/repo/packages/baz/ 216 | baz-bundle/repo/packages/baz/baz.1/ 217 | baz-bundle/repo/packages/baz/baz.1/opam 218 | baz-bundle/repo/packages/ocaml-base-compiler/ 219 | baz-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 220 | baz-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 221 | baz-bundle/repo/packages/ocaml-bootstrap/ 222 | baz-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 223 | baz-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 224 | baz-bundle/repo/packages/ocaml-config/ 225 | baz-bundle/repo/packages/ocaml-config/ocaml-config.2/ 226 | baz-bundle/repo/packages/ocaml-config/ocaml-config.2/opam 227 | baz-bundle/repo/packages/ocaml/ 228 | baz-bundle/repo/packages/ocaml/ocaml.4.14.0/ 229 | baz-bundle/repo/packages/ocaml/ocaml.4.14.0/opam 230 | baz-bundle/repo/repo 231 | 232 | Cleaning up 233 | $ rm baz-bundle.tar.gz 234 | 235 | 236 | 237 | ============================== Test 2 ============================== 238 | 239 | 240 | Bundle package `baz`, with os="cygwin" constraint specified in '--environment' option. That should filter packages in dependencies that 241 | are available on cygwin os (`bar` not included). 242 | 243 | $ opam-bundle baz --environment os="cygwin" --repository ./REPO --ocaml=4.14.0 -y 2>&1 244 | OCaml version is set to 4.14.0. 245 | No opam version selected, will use 2.1.4. 246 | 247 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 248 | [home] Initialised 249 | 250 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 251 | The following packages will be included: 252 | - baz.1 253 | - foo.1 254 | - ocaml.4.14.0 255 | - ocaml-base-compiler.4.14.0 256 | - ocaml-bootstrap.4.14.0 257 | - ocaml-config.2 258 | The bundle will be installable on systems matching the following: os != "linux" 259 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 260 | Continue ? [Y/n] y 261 | 262 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 263 | 264 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 265 | 266 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 267 | Done. Bundle generated as $TESTCASE_ROOT/baz-bundle.tar.gz 268 | 269 | 270 | $ tar --list -f baz-bundle.tar.gz | grep -v sha256 | sort 271 | baz-bundle/ 272 | baz-bundle/bootstrap.sh 273 | baz-bundle/common.sh 274 | baz-bundle/compile.sh 275 | baz-bundle/configure.sh 276 | baz-bundle/opam-full-2.1.4.tar.gz 277 | baz-bundle/repo/ 278 | baz-bundle/repo/archives/ 279 | baz-bundle/repo/archives/baz.1/ 280 | baz-bundle/repo/archives/baz.1/compile.tar.gz 281 | baz-bundle/repo/archives/foo.1/ 282 | baz-bundle/repo/archives/foo.1/compile.tar.gz 283 | baz-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 284 | baz-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 285 | baz-bundle/repo/archives/ocaml.4.14.0/ 286 | baz-bundle/repo/archives/ocaml.4.14.0/compile.tar.gz 287 | baz-bundle/repo/cache/ 288 | baz-bundle/repo/packages/ 289 | baz-bundle/repo/packages/baz/ 290 | baz-bundle/repo/packages/baz/baz.1/ 291 | baz-bundle/repo/packages/baz/baz.1/opam 292 | baz-bundle/repo/packages/foo/ 293 | baz-bundle/repo/packages/foo/foo.1/ 294 | baz-bundle/repo/packages/foo/foo.1/opam 295 | baz-bundle/repo/packages/ocaml-base-compiler/ 296 | baz-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 297 | baz-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 298 | baz-bundle/repo/packages/ocaml-bootstrap/ 299 | baz-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 300 | baz-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 301 | baz-bundle/repo/packages/ocaml-config/ 302 | baz-bundle/repo/packages/ocaml-config/ocaml-config.2/ 303 | baz-bundle/repo/packages/ocaml-config/ocaml-config.2/opam 304 | baz-bundle/repo/packages/ocaml/ 305 | baz-bundle/repo/packages/ocaml/ocaml.4.14.0/ 306 | baz-bundle/repo/packages/ocaml/ocaml.4.14.0/opam 307 | baz-bundle/repo/repo 308 | 309 | Cleaning up 310 | $ rm baz-bundle.tar.gz 311 | 312 | 313 | 314 | ============================== Test 3 ============================== 315 | 316 | 317 | Bundle package `baz`, with empty constraint specified in '--environment' option. That shouldn't filter any packages (considering 'any' constraint) and install 318 | all dependencies. 319 | 320 | $ opam-bundle baz --environment --repository ./REPO --ocaml=4.14.0 -y 2>&1 321 | OCaml version is set to 4.14.0. 322 | No opam version selected, will use 2.1.4. 323 | [NOTE] Empty environment 324 | 325 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 326 | [home] Initialised 327 | 328 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 329 | The following packages will be included: 330 | - bar.1 331 | - baz.1 332 | - foo.1 333 | - ocaml.4.14.0 334 | - ocaml-base-compiler.4.14.0 335 | - ocaml-bootstrap.4.14.0 336 | - ocaml-config.2 337 | The bundle will be installable on systems matching the following: os != "cygwin" & os != "linux" 338 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 339 | Continue ? [Y/n] y 340 | 341 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 342 | 343 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 344 | 345 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 346 | Done. Bundle generated as $TESTCASE_ROOT/baz-bundle.tar.gz 347 | 348 | 349 | $ tar --list -f baz-bundle.tar.gz | grep -v sha256 | sort 350 | baz-bundle/ 351 | baz-bundle/bootstrap.sh 352 | baz-bundle/common.sh 353 | baz-bundle/compile.sh 354 | baz-bundle/configure.sh 355 | baz-bundle/opam-full-2.1.4.tar.gz 356 | baz-bundle/repo/ 357 | baz-bundle/repo/archives/ 358 | baz-bundle/repo/archives/bar.1/ 359 | baz-bundle/repo/archives/bar.1/compile.tar.gz 360 | baz-bundle/repo/archives/baz.1/ 361 | baz-bundle/repo/archives/baz.1/compile.tar.gz 362 | baz-bundle/repo/archives/foo.1/ 363 | baz-bundle/repo/archives/foo.1/compile.tar.gz 364 | baz-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 365 | baz-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 366 | baz-bundle/repo/archives/ocaml.4.14.0/ 367 | baz-bundle/repo/archives/ocaml.4.14.0/compile.tar.gz 368 | baz-bundle/repo/cache/ 369 | baz-bundle/repo/packages/ 370 | baz-bundle/repo/packages/bar/ 371 | baz-bundle/repo/packages/bar/bar.1/ 372 | baz-bundle/repo/packages/bar/bar.1/opam 373 | baz-bundle/repo/packages/baz/ 374 | baz-bundle/repo/packages/baz/baz.1/ 375 | baz-bundle/repo/packages/baz/baz.1/opam 376 | baz-bundle/repo/packages/foo/ 377 | baz-bundle/repo/packages/foo/foo.1/ 378 | baz-bundle/repo/packages/foo/foo.1/opam 379 | baz-bundle/repo/packages/ocaml-base-compiler/ 380 | baz-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 381 | baz-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 382 | baz-bundle/repo/packages/ocaml-bootstrap/ 383 | baz-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 384 | baz-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 385 | baz-bundle/repo/packages/ocaml-config/ 386 | baz-bundle/repo/packages/ocaml-config/ocaml-config.2/ 387 | baz-bundle/repo/packages/ocaml-config/ocaml-config.2/opam 388 | baz-bundle/repo/packages/ocaml/ 389 | baz-bundle/repo/packages/ocaml/ocaml.4.14.0/ 390 | baz-bundle/repo/packages/ocaml/ocaml.4.14.0/opam 391 | baz-bundle/repo/repo 392 | 393 | Cleaning up 394 | $ rm baz-bundle.tar.gz 395 | 396 | 397 | 398 | ============================== Test 4 (fail) ============================== 399 | 400 | Trying bundle package `bar` on cygwin. That will fail, since this package isn't available on cygwin. 401 | 402 | 403 | $ opam-bundle bar --environment os="cygwin" --repository ./REPO --ocaml=4.14.0 -y 2>&1 404 | OCaml version is set to 4.14.0. 405 | No opam version selected, will use 2.1.4. 406 | 407 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 408 | [home] Initialised 409 | 410 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 411 | [ERROR] The following packages do not exist in the specified repositories, or are not available with the given configuration: 412 | - bar: unmet availability conditions: 'os != "cygwin"' 413 | 414 | [5] 415 | -------------------------------------------------------------------------------- /tests/stub/packages.t: -------------------------------------------------------------------------------- 1 | This test verify different package specifications that could be used with `opam-bundle`. 2 | Every package used is a stub package. 3 | 4 | $ export OPAMNOENVNOTICE=1 5 | $ export OPAMYES=1 6 | $ export OPAMROOT=$PWD/OPAMROOT 7 | $ export OPAMSTATUSLINE=never 8 | $ export OPAMVERBOSE=-1 9 | Different version of one stub executable 10 | $ cat > compile << EOF 11 | > #!/bin/sh 12 | > echo "I'm launching \$(basename \${0}) \$@!" 13 | > EOF 14 | $ chmod +x compile 15 | $ tar czf compile.tar.gz compile 16 | $ SHA=`openssl sha256 compile.tar.gz | cut -d ' ' -f 2` 17 | $ cat > compile1 << EOF 18 | > #!/bin/sh 19 | > echo "I'm launching \$(basename \${0}) v.1 \$@!" 20 | > EOF 21 | $ chmod +x compile1 22 | $ tar czf compile1.tar.gz compile1 23 | $ SHA1=`openssl sha256 compile1.tar.gz | cut -d ' ' -f 2` 24 | $ cat > compile2 << EOF 25 | > #!/bin/sh 26 | > echo "I'm launching \$(basename \${0}) v.2 \$@!" 27 | > EOF 28 | $ chmod +x compile2 29 | $ tar czf compile2.tar.gz compile2 30 | $ SHA2=`openssl sha256 compile2.tar.gz | cut -d ' ' -f 2` 31 | $ cat > compile3 << EOF 32 | > #!/bin/sh 33 | > echo "I'm launching \$(basename \${0}) v.3 \$@!" 34 | > EOF 35 | $ chmod +x compile3 36 | $ tar czf compile3.tar.gz compile3 37 | $ SHA3=`openssl sha256 compile3.tar.gz | cut -d ' ' -f 2` 38 | $ cat > compile4 << EOF 39 | > #!/bin/sh 40 | > echo "I'm launching \$(basename \${0}) v.4 \$@!" 41 | > EOF 42 | $ chmod +x compile4 43 | OCaml archive setup 44 | $ mkdir ocaml-4.14.0 45 | $ cat > ocaml-4.14.0/configure << EOF 46 | > set -uex 47 | > sed -i "s:PREFIX:\$2:g" Makefile 48 | > echo "configured" 49 | > EOF 50 | $ chmod +x ocaml-4.14.0/configure 51 | $ cat > ocaml-4.14.0/Makefile << EOF 52 | > world: 53 | > echo "make world" 54 | > world.opt: 55 | > echo "world opt" 56 | > install: 57 | > mkdir -p PREFIX/bin/ 58 | > cp ocaml PREFIX/bin/ 59 | > cp ocamlc PREFIX/bin/ 60 | > cp ocamlopt PREFIX/bin/ 61 | > cp $(which opam) PREFIX/bin/ 62 | > EOF 63 | $ cat > ocaml-4.14.0/ocaml << EOF 64 | > echo "I'm compiling \$1!" 65 | > EOF 66 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlc 67 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlopt 68 | $ tar czf ocaml.tar.gz ocaml-4.14.0 69 | $ OCAMLSHA=`openssl sha256 ocaml.tar.gz | cut -d ' ' -f 2` 70 | Repo setup 71 | $ mkdir -p REPO/packages/ 72 | $ cat > REPO/repo << EOF 73 | > opam-version: "2.0" 74 | > EOF 75 | === Foo packages === 76 | Package which isn't included in repository. 77 | $ mkdir foo.4 78 | $ cat > foo.4/test.patch << EOF 79 | > --- foo.4/compile4 80 | > +++ foo.4/compile4 81 | > @@ -1 +1 @@ 82 | > -echo "I'm launching \$(basename \${0}) v.4 \$@!" 83 | > +echo "I'm launching with patch \$(basename \${0}) v.4 \$@!" 84 | > EOF 85 | $ cat > foo.4/opam << EOF 86 | > opam-version: "2.0" 87 | > version: "4" 88 | > build: [ "sh" "compile4" name ] 89 | > install: [ 90 | > [ "cp" "compile4" "%{bin}%/%{name}%" ] 91 | > ] 92 | > depends : [ 93 | > "ocaml" {>= "4.14.0"} 94 | > ] 95 | > extra-source "repo" { 96 | > src: "file://./REPO/repo" 97 | > } 98 | > patches : ["test.patch"] 99 | > EOF 100 | $ cp compile4 foo.4/ 101 | Repository packages 102 | $ mkdir -p REPO/packages/foo/foo.1 REPO/packages/foo/foo.2 REPO/packages/foo/foo.3 103 | $ cat > REPO/packages/foo/foo.1/opam << EOF 104 | > opam-version: "2.0" 105 | > version: "1" 106 | > build: [ "sh" "compile1" name ] 107 | > install: [ 108 | > [ "cp" "compile1" "%{bin}%/%{name}%" ] 109 | > ] 110 | > depends : [ 111 | > "ocaml" {>= "4.12.0"} 112 | > ] 113 | > url { 114 | > src: "file://./compile1.tar.gz" 115 | > checksum: "sha256=$SHA1" 116 | > } 117 | > EOF 118 | $ cat > REPO/packages/foo/foo.2/opam << EOF 119 | > opam-version: "2.0" 120 | > version: "2" 121 | > build: [ "sh" "compile2" name ] 122 | > install: [ 123 | > [ "cp" "compile2" "%{bin}%/%{name}%" ] 124 | > ] 125 | > depends : [ 126 | > "ocaml" {>= "4.13.0"} 127 | > ] 128 | > url { 129 | > src: "file://./compile2.tar.gz" 130 | > checksum: "sha256=$SHA2" 131 | > } 132 | > EOF 133 | $ cat > REPO/packages/foo/foo.3/opam << EOF 134 | > opam-version: "2.0" 135 | > version: "3" 136 | > build: [ "sh" "compile3" name ] 137 | > install: [ 138 | > [ "cp" "compile3" "%{bin}%/%{name}%" ] 139 | > ] 140 | > depends : [ 141 | > "ocaml" {>= "4.14.0"} 142 | > ] 143 | > url { 144 | > src: "file://./compile3.tar.gz" 145 | > checksum: "sha256=$SHA3" 146 | > } 147 | > EOF 148 | Bar packages. 149 | $ mkdir -p REPO/packages/bar/bar.1 REPO/packages/bar/bar.2 REPO/packages/bar/bar.3/files 150 | $ cat > REPO/packages/bar/bar.1/opam << EOF 151 | > opam-version: "2.0" 152 | > version: "1" 153 | > build: [ "sh" "compile1" name ] 154 | > install: [ 155 | > [ "cp" "compile1" "%{bin}%/%{name}%" ] 156 | > ] 157 | > depends : [ 158 | > "ocaml" {>= "4.14.0"} 159 | > "foo" {= "1"} 160 | > ] 161 | > url { 162 | > src: "file://./compile1.tar.gz" 163 | > checksum: "sha256=$SHA1" 164 | > } 165 | > EOF 166 | $ cat > REPO/packages/bar/bar.2/opam << EOF 167 | > opam-version: "2.0" 168 | > version: "2" 169 | > build: [ "sh" "compile2" name ] 170 | > install: [ 171 | > [ "cp" "compile2" "%{bin}%/%{name}%" ] 172 | > ] 173 | > depends : [ 174 | > "ocaml" {>= "4.14.0"} 175 | > "foo" {<= "2"} 176 | > ] 177 | > url { 178 | > src: "file://./compile2.tar.gz" 179 | > checksum: "sha256=$SHA2" 180 | > } 181 | > EOF 182 | $ cat > REPO/packages/bar/bar.3/files/test.patch << EOF 183 | > --- bar/compile3 184 | > +++ bar/compile3 185 | > @@ -1 +1 @@ 186 | > -echo "I'm launching \$(basename \${0}) v.3 \$@!" 187 | > +echo "I'm launching with patch \$(basename \${0}) v.3 \$@!" 188 | > EOF 189 | $ cat > REPO/packages/bar/bar.3/opam << EOF 190 | > opam-version: "2.0" 191 | > version: "3" 192 | > build: [ "sh" "compile3" name ] 193 | > install: [ 194 | > [ "cp" "compile3" "%{bin}%/%{name}%" ] 195 | > ] 196 | > depends : [ 197 | > "ocaml" {>= "4.14.0"} 198 | > "foo" {>= "3"} 199 | > ] 200 | > patches : ["test.patch"] 201 | > url { 202 | > src: "file://./compile3.tar.gz" 203 | > checksum: "sha256=$SHA3" 204 | > } 205 | > EOF 206 | Ocaml-system.4.14.0 package. 207 | $ mkdir -p REPO/packages/ocaml-system/ocaml-system.4.14.0 208 | $ cat > REPO/packages/ocaml-system/ocaml-system.4.14.0/opam << EOF 209 | > opam-version: "2.0" 210 | > EOF 211 | Ocaml-config.2 package. 212 | $ mkdir -p REPO/packages/ocaml-config/ocaml-config.2 213 | $ cat > REPO/packages/ocaml-config/ocaml-config.2/opam << EOF 214 | > opam-version: "2.0" 215 | > EOF 216 | Ocaml.4.14.0 package. 217 | $ mkdir -p REPO/packages/ocaml/ocaml.4.14.0 218 | $ cat > REPO/packages/ocaml/ocaml.4.14.0/opam << EOF 219 | > opam-version: "2.0" 220 | > depends: [ 221 | > ("ocaml-system" | "ocaml-base-compiler") 222 | > "ocaml-config" 223 | > ] 224 | > url { 225 | > src: "file://./compile.tar.gz" 226 | > checksum: "sha256=$SHA" 227 | > } 228 | > EOF 229 | Ocaml-base-compiler.4.14.0 package. 230 | $ mkdir -p REPO/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0 231 | $ cat > REPO/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam << EOF 232 | > opam-version: "2.0" 233 | > build: [ "sh" "compile" name ] 234 | > install: [ 235 | > [ "chmod" "+x" "compile" ] 236 | > [ "cp" "compile" "%{bin}%/ocaml" ] 237 | > ] 238 | > url { 239 | > src: "file://./ocaml.tar.gz" 240 | > checksum: "sha256=$OCAMLSHA" 241 | > } 242 | > EOF 243 | Opam setup 244 | $ mkdir $OPAMROOT 245 | $ opam init --bare ./REPO --no-setup --bypass-checks 246 | No configuration file found, using built-in defaults. 247 | 248 | <><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> 249 | [default] Initialised 250 | $ opam switch create one --empty 251 | 252 | 253 | 254 | Running opam-bundle with sanitized output that contains replaced platform specific information. 255 | 256 | 257 | ============================== Test 1 ============================== 258 | 259 | 260 | Bundle single package `bar` of version 2. That implies installation of its dependency `foo` with constraint "<=2". 261 | 262 | $ opam-bundle bar.2 --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 263 | OCaml version is set to 4.14.0. 264 | No opam version selected, will use 2.1.4. 265 | No environment specified, will use the following for package resolution (based on the host system): 266 | - arch = $ARCH 267 | - os = $OS 268 | - os-distribution = $OSDISTRIB 269 | - os-version = $OSVERSION 270 | - os-family = $OSFAMILLY 271 | 272 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 273 | [home] Initialised 274 | 275 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 276 | The following packages will be included: 277 | - bar.2 278 | - foo.2 279 | - ocaml.4.14.0 280 | - ocaml-base-compiler.4.14.0 281 | - ocaml-bootstrap.4.14.0 282 | - ocaml-config.2 283 | According to the packages' metadata, the bundle should be installable on any arch/OS. 284 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 285 | Continue ? [Y/n] y 286 | 287 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 288 | 289 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 290 | 291 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 292 | Done. Bundle generated as $TESTCASE_ROOT/bar-bundle.tar.gz 293 | $ tar xvf bar-bundle.tar.gz | grep -v sha256 | sort 294 | bar-bundle/ 295 | bar-bundle/bootstrap.sh 296 | bar-bundle/common.sh 297 | bar-bundle/compile.sh 298 | bar-bundle/configure.sh 299 | bar-bundle/opam-full-2.1.4.tar.gz 300 | bar-bundle/repo/ 301 | bar-bundle/repo/archives/ 302 | bar-bundle/repo/archives/bar.2/ 303 | bar-bundle/repo/archives/bar.2/compile2.tar.gz 304 | bar-bundle/repo/archives/foo.2/ 305 | bar-bundle/repo/archives/foo.2/compile2.tar.gz 306 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 307 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 308 | bar-bundle/repo/archives/ocaml.4.14.0/ 309 | bar-bundle/repo/archives/ocaml.4.14.0/compile.tar.gz 310 | bar-bundle/repo/cache/ 311 | bar-bundle/repo/packages/ 312 | bar-bundle/repo/packages/bar/ 313 | bar-bundle/repo/packages/bar/bar.2/ 314 | bar-bundle/repo/packages/bar/bar.2/opam 315 | bar-bundle/repo/packages/foo/ 316 | bar-bundle/repo/packages/foo/foo.2/ 317 | bar-bundle/repo/packages/foo/foo.2/opam 318 | bar-bundle/repo/packages/ocaml-base-compiler/ 319 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 320 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 321 | bar-bundle/repo/packages/ocaml-bootstrap/ 322 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 323 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 324 | bar-bundle/repo/packages/ocaml-config/ 325 | bar-bundle/repo/packages/ocaml-config/ocaml-config.2/ 326 | bar-bundle/repo/packages/ocaml-config/ocaml-config.2/opam 327 | bar-bundle/repo/packages/ocaml/ 328 | bar-bundle/repo/packages/ocaml/ocaml.4.14.0/ 329 | bar-bundle/repo/packages/ocaml/ocaml.4.14.0/opam 330 | bar-bundle/repo/repo 331 | 332 | $ sh ./bar-bundle/compile.sh ../BAR 333 | This bundle will compile the application to $TESTCASE_ROOT/bar-bundle, and put wrappers into 334 | ../BAR/bin. You will need to retain $TESTCASE_ROOT/bar-bundle for the wrappers to work. 335 | 336 | Press enter to continue... 337 | ================ Bootstrap: checking for prerequisites ================ 338 | 339 | Checking for cc... found 340 | Checking for make... found 341 | Checking for wget curl... found 342 | Checking for patch... found 343 | Checking for unzip... found 344 | Checking for bunzip2... found 345 | Checking for rsync... found 346 | 347 | ================ Bootstrap: compiling OCaml ================ 348 | 349 | This may take a while. Output is in $TESTCASE_ROOT/bar-bundle/bootstrap.log 350 | Uncompressing... done 351 | Configuring... done 352 | Compiling... done 353 | Installing to temp prefix... done 354 | Already compiled opam found 355 | 356 | ================ Configure: initialising opam ================ 357 | 358 | Output is in $TESTCASE_ROOT/bar-bundle/configure.log 359 | Initialising... done 360 | Creating sandbox... done 361 | 362 | ================ Compile: installing packages ================ 363 | 364 | Output is in $TESTCASE_ROOT/bar-bundle/compile.log 365 | Compiling packages... done 366 | Cleaning up... done 367 | Wrapper bar installed successfully. 368 | 369 | $ opam exec --root ./bar-bundle/opam -- foo 370 | I'm launching foo v.2 ! 371 | $ opam exec --root ./bar-bundle/opam -- bar 372 | I'm launching bar v.2 ! 373 | $ find BAR | sort 374 | BAR 375 | BAR/bin 376 | BAR/bin/bar 377 | $ BAR/bin/bar 378 | I'm launching bar v.2 ! 379 | 380 | Cleaning up 381 | $ rm -r BAR bar-bundle bar-bundle.tar.gz 382 | 383 | 384 | ============================== Test 2 ============================== 385 | 386 | 387 | Bundle two packages `bar` and `foo>2`. Forcing constraint on `foo` implies installation of `bar.3`. 388 | Since `foo` was specified as argument to `opam-bundle` it installs additionally `foo` wrapper. 389 | 390 | $ opam-bundle bar 'foo>2' --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 391 | OCaml version is set to 4.14.0. 392 | No opam version selected, will use 2.1.4. 393 | No environment specified, will use the following for package resolution (based on the host system): 394 | - arch = $ARCH 395 | - os = $OS 396 | - os-distribution = $OSDISTRIB 397 | - os-version = $OSVERSION 398 | - os-family = $OSFAMILLY 399 | 400 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 401 | [home] Initialised 402 | 403 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 404 | The following packages will be included: 405 | - bar.3 406 | - foo.3 407 | - ocaml.4.14.0 408 | - ocaml-base-compiler.4.14.0 409 | - ocaml-bootstrap.4.14.0 410 | - ocaml-config.2 411 | According to the packages' metadata, the bundle should be installable on any arch/OS. 412 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 413 | Continue ? [Y/n] y 414 | 415 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 416 | 417 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 418 | 419 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 420 | Done. Bundle generated as $TESTCASE_ROOT/bar-bundle.tar.gz 421 | $ tar xvf bar-bundle.tar.gz | grep -v sha256 | sort 422 | bar-bundle/ 423 | bar-bundle/bootstrap.sh 424 | bar-bundle/common.sh 425 | bar-bundle/compile.sh 426 | bar-bundle/configure.sh 427 | bar-bundle/opam-full-2.1.4.tar.gz 428 | bar-bundle/repo/ 429 | bar-bundle/repo/archives/ 430 | bar-bundle/repo/archives/bar.3/ 431 | bar-bundle/repo/archives/bar.3/compile3.tar.gz 432 | bar-bundle/repo/archives/foo.3/ 433 | bar-bundle/repo/archives/foo.3/compile3.tar.gz 434 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 435 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 436 | bar-bundle/repo/archives/ocaml.4.14.0/ 437 | bar-bundle/repo/archives/ocaml.4.14.0/compile.tar.gz 438 | bar-bundle/repo/cache/ 439 | bar-bundle/repo/packages/ 440 | bar-bundle/repo/packages/bar/ 441 | bar-bundle/repo/packages/bar/bar.3/ 442 | bar-bundle/repo/packages/bar/bar.3/files/ 443 | bar-bundle/repo/packages/bar/bar.3/files/test.patch 444 | bar-bundle/repo/packages/bar/bar.3/opam 445 | bar-bundle/repo/packages/foo/ 446 | bar-bundle/repo/packages/foo/foo.3/ 447 | bar-bundle/repo/packages/foo/foo.3/opam 448 | bar-bundle/repo/packages/ocaml-base-compiler/ 449 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 450 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 451 | bar-bundle/repo/packages/ocaml-bootstrap/ 452 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 453 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 454 | bar-bundle/repo/packages/ocaml-config/ 455 | bar-bundle/repo/packages/ocaml-config/ocaml-config.2/ 456 | bar-bundle/repo/packages/ocaml-config/ocaml-config.2/opam 457 | bar-bundle/repo/packages/ocaml/ 458 | bar-bundle/repo/packages/ocaml/ocaml.4.14.0/ 459 | bar-bundle/repo/packages/ocaml/ocaml.4.14.0/opam 460 | bar-bundle/repo/repo 461 | 462 | $ sh ./bar-bundle/compile.sh ../BAR 463 | This bundle will compile the application to $TESTCASE_ROOT/bar-bundle, and put wrappers into 464 | ../BAR/bin. You will need to retain $TESTCASE_ROOT/bar-bundle for the wrappers to work. 465 | 466 | Press enter to continue... 467 | ================ Bootstrap: checking for prerequisites ================ 468 | 469 | Checking for cc... found 470 | Checking for make... found 471 | Checking for wget curl... found 472 | Checking for patch... found 473 | Checking for unzip... found 474 | Checking for bunzip2... found 475 | Checking for rsync... found 476 | 477 | ================ Bootstrap: compiling OCaml ================ 478 | 479 | This may take a while. Output is in $TESTCASE_ROOT/bar-bundle/bootstrap.log 480 | Uncompressing... done 481 | Configuring... done 482 | Compiling... done 483 | Installing to temp prefix... done 484 | Already compiled opam found 485 | 486 | ================ Configure: initialising opam ================ 487 | 488 | Output is in $TESTCASE_ROOT/bar-bundle/configure.log 489 | Initialising... done 490 | Creating sandbox... done 491 | 492 | ================ Compile: installing packages ================ 493 | 494 | Output is in $TESTCASE_ROOT/bar-bundle/compile.log 495 | Compiling packages... done 496 | Cleaning up... done 497 | Wrapper bar installed successfully. 498 | Wrapper foo installed successfully. 499 | 500 | $ opam exec --root ./bar-bundle/opam -- foo 501 | I'm launching foo v.3 ! 502 | $ opam exec --root ./bar-bundle/opam -- bar 503 | I'm launching with patch bar v.3 ! 504 | $ find BAR | sort 505 | BAR 506 | BAR/bin 507 | BAR/bin/bar 508 | BAR/bin/foo 509 | $ BAR/bin/foo 510 | I'm launching foo v.3 ! 511 | $ BAR/bin/bar 512 | I'm launching with patch bar v.3 ! 513 | 514 | Cleaning up 515 | $ rm -r BAR bar-bundle bar-bundle.tar.gz 516 | 517 | 518 | ============================== Test 3 ============================== 519 | 520 | 521 | Bundle two packages `bar` and `foo@foo.4` where "foo.4" is a url to local version of package `foo`. This package 522 | has extra-source (opam-bundle archive 0.4) that should be also bundled. Forcing constraint on `foo` implies 523 | installation of `bar.3`. Since `foo` was specified as argument to `opam-bundle` it installs additionally `foo` 524 | wrapper. 525 | 526 | $ opam-bundle bar 'foo@foo.4' --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/;s/md5=.*/md5=$HASH/' | sed 's/.* No such file or directory/mv error/g' 527 | OCaml version is set to 4.14.0. 528 | No opam version selected, will use 2.1.4. 529 | No environment specified, will use the following for package resolution (based on the host system): 530 | - arch = $ARCH 531 | - os = $OS 532 | - os-distribution = $OSDISTRIB 533 | - os-version = $OSVERSION 534 | - os-family = $OSFAMILLY 535 | 536 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 537 | [home] Initialised 538 | 539 | <><> Getting external packages ><><><><><><><><><><><><><><><><><><><><><><><><> 540 | [NOTE] Will use package definition found in source for foo 541 | 542 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 543 | The following packages will be included: 544 | - bar.3 545 | - foo.4 546 | - ocaml.4.14.0 547 | - ocaml-base-compiler.4.14.0 548 | - ocaml-bootstrap.4.14.0 549 | - ocaml-config.2 550 | According to the packages' metadata, the bundle should be installable on any arch/OS. 551 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 552 | Continue ? [Y/n] y 553 | 554 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 555 | [WARNING] Extra source repo of foo.4 from file://./REPO/repo had no recorded checksum: adding md5=$HASH 556 | 557 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 558 | 559 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 560 | Done. Bundle generated as $TESTCASE_ROOT/bar-bundle.tar.gz 561 | 562 | $ tar xvf bar-bundle.tar.gz | grep -v sha256 | grep -v md5 | sort 563 | bar-bundle/ 564 | bar-bundle/bootstrap.sh 565 | bar-bundle/common.sh 566 | bar-bundle/compile.sh 567 | bar-bundle/configure.sh 568 | bar-bundle/opam-full-2.1.4.tar.gz 569 | bar-bundle/repo/ 570 | bar-bundle/repo/archives/ 571 | bar-bundle/repo/archives/bar.3/ 572 | bar-bundle/repo/archives/bar.3/compile3.tar.gz 573 | bar-bundle/repo/archives/foo.4/ 574 | bar-bundle/repo/archives/foo.4/foo.4.tar.gz 575 | bar-bundle/repo/archives/foo.4/repo 576 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ 577 | bar-bundle/repo/archives/ocaml-base-compiler.4.14.0/ocaml.tar.gz 578 | bar-bundle/repo/archives/ocaml.4.14.0/ 579 | bar-bundle/repo/archives/ocaml.4.14.0/compile.tar.gz 580 | bar-bundle/repo/cache/ 581 | bar-bundle/repo/packages/ 582 | bar-bundle/repo/packages/bar/ 583 | bar-bundle/repo/packages/bar/bar.3/ 584 | bar-bundle/repo/packages/bar/bar.3/files/ 585 | bar-bundle/repo/packages/bar/bar.3/files/test.patch 586 | bar-bundle/repo/packages/bar/bar.3/opam 587 | bar-bundle/repo/packages/foo/ 588 | bar-bundle/repo/packages/foo/foo.4/ 589 | bar-bundle/repo/packages/foo/foo.4/opam 590 | bar-bundle/repo/packages/ocaml-base-compiler/ 591 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/ 592 | bar-bundle/repo/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam 593 | bar-bundle/repo/packages/ocaml-bootstrap/ 594 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/ 595 | bar-bundle/repo/packages/ocaml-bootstrap/ocaml-bootstrap.4.14.0/opam 596 | bar-bundle/repo/packages/ocaml-config/ 597 | bar-bundle/repo/packages/ocaml-config/ocaml-config.2/ 598 | bar-bundle/repo/packages/ocaml-config/ocaml-config.2/opam 599 | bar-bundle/repo/packages/ocaml/ 600 | bar-bundle/repo/packages/ocaml/ocaml.4.14.0/ 601 | bar-bundle/repo/packages/ocaml/ocaml.4.14.0/opam 602 | bar-bundle/repo/repo 603 | 604 | $ sh ./bar-bundle/compile.sh ../BAR 605 | This bundle will compile the application to $TESTCASE_ROOT/bar-bundle, and put wrappers into 606 | ../BAR/bin. You will need to retain $TESTCASE_ROOT/bar-bundle for the wrappers to work. 607 | 608 | Press enter to continue... 609 | ================ Bootstrap: checking for prerequisites ================ 610 | 611 | Checking for cc... found 612 | Checking for make... found 613 | Checking for wget curl... found 614 | Checking for patch... found 615 | Checking for unzip... found 616 | Checking for bunzip2... found 617 | Checking for rsync... found 618 | 619 | ================ Bootstrap: compiling OCaml ================ 620 | 621 | This may take a while. Output is in $TESTCASE_ROOT/bar-bundle/bootstrap.log 622 | Uncompressing... done 623 | Configuring... done 624 | Compiling... done 625 | Installing to temp prefix... done 626 | Already compiled opam found 627 | 628 | ================ Configure: initialising opam ================ 629 | 630 | Output is in $TESTCASE_ROOT/bar-bundle/configure.log 631 | Initialising... done 632 | Creating sandbox... done 633 | 634 | ================ Compile: installing packages ================ 635 | 636 | Output is in $TESTCASE_ROOT/bar-bundle/compile.log 637 | Compiling packages... done 638 | Cleaning up... done 639 | Wrapper bar installed successfully. 640 | Wrapper foo installed successfully. 641 | 642 | $ opam exec --root ./bar-bundle/opam -- foo 643 | I'm launching with patch foo v.4 ! 644 | $ opam exec --root ./bar-bundle/opam -- bar 645 | I'm launching with patch bar v.3 ! 646 | $ find BAR | sort 647 | BAR 648 | BAR/bin 649 | BAR/bin/bar 650 | BAR/bin/foo 651 | $ BAR/bin/foo 652 | I'm launching with patch foo v.4 ! 653 | $ BAR/bin/bar 654 | I'm launching with patch bar v.3 ! 655 | 656 | 657 | 658 | ============================== Test 4 (fail) ============================== 659 | 660 | 661 | Trying to bundle two packages `bar.3` and `foo.1`. This should fail, because those versions are not compatible. 662 | 663 | $ opam-bundle bar.3 foo.1 --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 664 | OCaml version is set to 4.14.0. 665 | No opam version selected, will use 2.1.4. 666 | No environment specified, will use the following for package resolution (based on the host system): 667 | - arch = $ARCH 668 | - os = $OS 669 | - os-distribution = $OSDISTRIB 670 | - os-version = $OSVERSION 671 | - os-family = $OSFAMILLY 672 | 673 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 674 | [home] Initialised 675 | 676 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 677 | [ERROR] No solution for bar.3 & foo.1 & ocaml-bootstrap.4.14.0: * No agreement on the version of foo: 678 | - bar >= 3 -> foo >= 3 679 | - foo < 2 680 | 681 | 682 | 683 | 684 | 685 | ============================== Test 5 (fail) ============================== 686 | 687 | 688 | Trying to bundle two packages `bar` and `foo<3@foo.4`. This should fail, because package with url can be constrained only with '.' or '='. 689 | 690 | $ opam-bundle bar 'foo<2@foo.4' --repository ./REPO --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 691 | opam-bundle: PACKAGE… arguments: Only equality version constraints can be 692 | specified together with a target URL 693 | Usage: opam-bundle [OPTION]… PACKAGE… 694 | Try 'opam-bundle --help' for more information. 695 | -------------------------------------------------------------------------------- /tests/stub/repos.t: -------------------------------------------------------------------------------- 1 | This test verify different repository specifications that could be used with `opam-bundle`. 2 | Every package used is a stub package. 3 | 4 | $ export OPAMNOENVNOTICE=1 5 | $ export OPAMYES=1 6 | $ export OPAMROOT=$PWD/OPAMROOT 7 | $ export OPAMSTATUSLINE=never 8 | $ export OPAMVERBOSE=-1 9 | Stub executable 10 | $ cat > compile << EOF 11 | > #!/bin/sh 12 | > echo "I'm launching \$(basename \${0}) \$@!" 13 | > EOF 14 | $ chmod +x compile 15 | $ tar czf compile.tar.gz compile 16 | $ SHA=`openssl sha256 compile.tar.gz | cut -d ' ' -f 2` 17 | OCaml archives setup 18 | 4.14 19 | $ mkdir ocaml-4.14.0 20 | $ cat > ocaml-4.14.0/configure << EOF 21 | > set -uex 22 | > sed -i "s:PREFIX:\$2:g" Makefile 23 | > echo "configured" 24 | > EOF 25 | $ chmod +x ocaml-4.14.0/configure 26 | $ cat > ocaml-4.14.0/Makefile << EOF 27 | > world: 28 | > echo "make world" 29 | > world.opt: 30 | > echo "world opt" 31 | > install: 32 | > mkdir -p PREFIX/bin/ 33 | > cp ocaml PREFIX/bin/ 34 | > cp ocamlc PREFIX/bin/ 35 | > cp ocamlopt PREFIX/bin/ 36 | > cp $(which opam) PREFIX/bin/ 37 | > EOF 38 | $ cat > ocaml-4.14.0/ocaml << EOF 39 | > echo "I'm compiling v.4.14 \$1!" 40 | > EOF 41 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlc 42 | $ cp ocaml-4.14.0/ocaml ocaml-4.14.0/ocamlopt 43 | $ tar czf ocaml.4.14.tar.gz ocaml-4.14.0 44 | $ OCAMLSHA414=`openssl sha256 ocaml.4.14.tar.gz | cut -d ' ' -f 2` 45 | 4.13 46 | $ mkdir ocaml-4.13.0 47 | $ cat > ocaml-4.13.0/configure << EOF 48 | > set -uex 49 | > sed -i "s:PREFIX:\$2:g" Makefile 50 | > echo "configured" 51 | > EOF 52 | $ chmod +x ocaml-4.13.0/configure 53 | $ cat > ocaml-4.13.0/Makefile << EOF 54 | > world: 55 | > echo "make world" 56 | > world.opt: 57 | > echo "world opt" 58 | > install: 59 | > mkdir -p PREFIX/bin/ 60 | > cp ocaml PREFIX/bin/ 61 | > cp ocamlc PREFIX/bin/ 62 | > cp ocamlopt PREFIX/bin/ 63 | > cp $(which opam) PREFIX/bin/ 64 | > EOF 65 | $ cat > ocaml-4.13.0/ocaml << EOF 66 | > echo "I'm compiling v.4.13 \$1!" 67 | > EOF 68 | $ cp ocaml-4.13.0/ocaml ocaml-4.13.0/ocamlc 69 | $ cp ocaml-4.13.0/ocaml ocaml-4.13.0/ocamlopt 70 | $ tar czf ocaml.4.13.tar.gz ocaml-4.13.0 71 | $ OCAMLSHA413=`openssl sha256 ocaml.4.13.tar.gz | cut -d ' ' -f 2` 72 | 4.12 73 | $ mkdir ocaml-4.12.0 74 | $ cat > ocaml-4.12.0/configure << EOF 75 | > set -uex 76 | > sed -i "s:PREFIX:\$2:g" Makefile 77 | > echo "configured" 78 | > EOF 79 | $ chmod +x ocaml-4.12.0/configure 80 | $ cat > ocaml-4.12.0/Makefile << EOF 81 | > world: 82 | > echo "make world" 83 | > world.opt: 84 | > echo "world opt" 85 | > install: 86 | > mkdir -p PREFIX/bin/ 87 | > cp ocaml PREFIX/bin/ 88 | > cp ocamlc PREFIX/bin/ 89 | > cp ocamlopt PREFIX/bin/ 90 | > cp $(which opam) PREFIX/bin/ 91 | > EOF 92 | $ cat > ocaml-4.12.0/ocaml << EOF 93 | > echo "I'm compiling v.4.12 \$1!" 94 | > EOF 95 | $ cp ocaml-4.12.0/ocaml ocaml-4.12.0/ocamlc 96 | $ cp ocaml-4.12.0/ocaml ocaml-4.12.0/ocamlopt 97 | $ tar czf ocaml.4.12.tar.gz ocaml-4.12.0 98 | $ OCAMLSHA412=`openssl sha256 ocaml.4.12.tar.gz | cut -d ' ' -f 2` 99 | Repos setup 100 | $ mkdir -p REPO1/packages/ REPO2/packages/ REPO3/packages/ 101 | $ cat > REPO1/repo << EOF 102 | > opam-version: "2.0" 103 | > EOF 104 | $ cat > REPO2/repo << EOF 105 | > opam-version: "2.0" 106 | > EOF 107 | $ cat > REPO3/repo << EOF 108 | > opam-version: "2.0" 109 | > EOF 110 | Ocaml-system.4.14.0 package. 111 | $ mkdir -p REPO1/packages/ocaml-system/ocaml-system.4.14.0 112 | $ cat > REPO1/packages/ocaml-system/ocaml-system.4.14.0/opam << EOF 113 | > opam-version: "2.0" 114 | > EOF 115 | Ocaml.4.14.0 package. 116 | $ mkdir -p REPO1/packages/ocaml/ocaml.4.14.0 117 | $ cat > REPO1/packages/ocaml/ocaml.4.14.0/opam << EOF 118 | > opam-version: "2.0" 119 | > depends: [ 120 | > ("ocaml-system" | "ocaml-base-compiler") 121 | > "ocaml-config" 122 | > ] 123 | > url { 124 | > src: "file://./compile.tar.gz" 125 | > checksum: "sha256=$SHA" 126 | > } 127 | > EOF 128 | Ocaml-base-compiler.4.14.0 package. 129 | $ mkdir -p REPO1/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0 130 | $ cat > REPO1/packages/ocaml-base-compiler/ocaml-base-compiler.4.14.0/opam << EOF 131 | > opam-version: "2.0" 132 | > build: [ "sh" "compile" name ] 133 | > install: [ 134 | > [ "chmod" "+x" "compile" ] 135 | > [ "cp" "compile" "%{bin}%/ocaml" ] 136 | > ] 137 | > url { 138 | > src: "file://./ocaml.4.14.tar.gz" 139 | > checksum: "sha256=$OCAMLSHA414" 140 | > } 141 | > EOF 142 | Ocaml-system.4.13.0 package. 143 | $ mkdir -p REPO2/packages/ocaml-system/ocaml-system.4.13.0 144 | $ cat > REPO2/packages/ocaml-system/ocaml-system.4.13.0/opam << EOF 145 | > opam-version: "2.0" 146 | > EOF 147 | Ocaml.4.13.0 package. 148 | $ mkdir -p REPO2/packages/ocaml/ocaml.4.13.0 149 | $ cat > REPO2/packages/ocaml/ocaml.4.13.0/opam << EOF 150 | > opam-version: "2.0" 151 | > depends: [ 152 | > ("ocaml-system" | "ocaml-base-compiler") 153 | > "ocaml-config" 154 | > ] 155 | > url { 156 | > src: "file://./compile.tar.gz" 157 | > checksum: "sha256=$SHA" 158 | > } 159 | > EOF 160 | Ocaml-base-compiler.4.13.0 package. 161 | $ mkdir -p REPO2/packages/ocaml-base-compiler/ocaml-base-compiler.4.13.0 162 | $ cat > REPO2/packages/ocaml-base-compiler/ocaml-base-compiler.4.13.0/opam << EOF 163 | > opam-version: "2.0" 164 | > build: [ "sh" "compile" name ] 165 | > install: [ 166 | > [ "chmod" "+x" "compile" ] 167 | > [ "cp" "compile" "%{bin}%/ocaml" ] 168 | > ] 169 | > url { 170 | > src: "file://./ocaml.4.13.tar.gz" 171 | > checksum: "sha256=$OCAMLSHA413" 172 | > } 173 | > EOF 174 | Ocaml-system.4.12.0 package. 175 | $ mkdir -p REPO3/packages/ocaml-system/ocaml-system.4.12.0 176 | $ cat > REPO3/packages/ocaml-system/ocaml-system.4.12.0/opam << EOF 177 | > opam-version: "2.0" 178 | > EOF 179 | Ocaml.4.12.0 package. 180 | $ mkdir -p REPO3/packages/ocaml/ocaml.4.12.0 181 | $ cat > REPO3/packages/ocaml/ocaml.4.12.0/opam << EOF 182 | > opam-version: "2.0" 183 | > depends: [ 184 | > ("ocaml-system" | "ocaml-base-compiler") 185 | > "ocaml-config" 186 | > ] 187 | > url { 188 | > src: "file://./compile.tar.gz" 189 | > checksum: "sha256=$SHA" 190 | > } 191 | > EOF 192 | Ocaml-base-compiler.4.12.0 package. 193 | $ mkdir -p REPO3/packages/ocaml-base-compiler/ocaml-base-compiler.4.12.0 194 | $ cat > REPO3/packages/ocaml-base-compiler/ocaml-base-compiler.4.12.0/opam << EOF 195 | > opam-version: "2.0" 196 | > build: [ "sh" "compile" name ] 197 | > install: [ 198 | > [ "chmod" "+x" "compile" ] 199 | > [ "cp" "compile" "%{bin}%/ocaml" ] 200 | > ] 201 | > url { 202 | > src: "file://./ocaml.4.12.tar.gz" 203 | > checksum: "sha256=$OCAMLSHA412" 204 | > } 205 | > EOF 206 | Ocaml-config.2 package. 207 | $ mkdir -p REPO3/packages/ocaml-config/ocaml-config.2 208 | $ cat > REPO3/packages/ocaml-config/ocaml-config.2/opam << EOF 209 | > opam-version: "2.0" 210 | > EOF 211 | === Foo package === 212 | $ mkdir -p REPO1/packages/foo/foo.1 213 | $ cat > REPO1/packages/foo/foo.1/opam << EOF 214 | > opam-version: "2.0" 215 | > version: "1" 216 | > build: [ "sh" "compile" name ] 217 | > install: [ 218 | > [ "cp" "compile" "%{bin}%/%{name}%" ] 219 | > ] 220 | > depends : [ 221 | > "ocaml" {>= "4.12.0"} 222 | > ] 223 | > url { 224 | > src: "file://./compile.tar.gz" 225 | > checksum: "sha256=$SHA" 226 | > } 227 | > EOF 228 | === Bar package (not available on cygwin) === 229 | $ mkdir -p REPO2/packages/bar/bar.1 230 | $ cat > REPO2/packages/bar/bar.1/opam << EOF 231 | > opam-version: "2.0" 232 | > version: "1" 233 | > build: [ "sh" "compile" name ] 234 | > install: [ 235 | > [ "cp" "compile" "%{bin}%/%{name}%" ] 236 | > ] 237 | > depends : [ 238 | > "ocaml" {>= "4.13.0"} 239 | > "foo" 240 | > ] 241 | > url { 242 | > src: "file://./compile.tar.gz" 243 | > checksum: "sha256=$SHA" 244 | > } 245 | > EOF 246 | Opam setup 247 | $ mkdir $OPAMROOT 248 | $ opam init --bare repo1 ./REPO1 --no-setup --bypass-checks 249 | No configuration file found, using built-in defaults. 250 | 251 | <><> Fetching repository information ><><><><><><><><><><><><><><><><><><><><><> 252 | [repo1] Initialised 253 | 254 | $ opam switch create one --empty 255 | 256 | $ opam repo add repo2 ./REPO2 --all-switches 257 | [repo2] Initialised 258 | $ opam repo add repo3 ./REPO3 --all-switches 259 | [repo3] Initialised 260 | 261 | 262 | 263 | 264 | Running opam-bundle with sanitized output that contains replaced platform specific information. 265 | 266 | 267 | ============================== Test 1 ============================== 268 | 269 | 270 | Bundle package foo with and specifyng two repositories with `ocaml.4.12` and second repository containing 271 | only `ocaml.4.14` packages. We are forcing here to use 4.12 from second switch. 272 | 273 | $ opam-bundle foo --repository ./REPO1 --repository ./REPO3 --ocaml=4.12.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 274 | OCaml version is set to 4.12.0. 275 | No opam version selected, will use 2.1.4. 276 | No environment specified, will use the following for package resolution (based on the host system): 277 | - arch = $ARCH 278 | - os = $OS 279 | - os-distribution = $OSDISTRIB 280 | - os-version = $OSVERSION 281 | - os-family = $OSFAMILLY 282 | 283 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 284 | [home] Initialised 285 | [home1] Initialised 286 | 287 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 288 | The following packages will be included: 289 | - foo.1 290 | - ocaml.4.12.0 291 | - ocaml-base-compiler.4.12.0 292 | - ocaml-bootstrap.4.12.0 293 | - ocaml-config.2 294 | According to the packages' metadata, the bundle should be installable on any arch/OS. 295 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 296 | Continue ? [Y/n] y 297 | 298 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 299 | 300 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 301 | 302 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 303 | Done. Bundle generated as $TESTCASE_ROOT/foo-bundle.tar.gz 304 | 305 | 306 | 307 | ============================== Test 2 ============================== 308 | 309 | 310 | 311 | Bundle packages foo and bar with specifying three repositories with `foo` and second repository containing `bar` 312 | package and third containing required ocaml-config.2. We are forcing here to use 4.13 from switch. 313 | 314 | $ opam-bundle foo bar --repository ./REPO1 --repository ./REPO2 --repository ./REPO3 --ocaml=4.13.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 315 | OCaml version is set to 4.13.0. 316 | No opam version selected, will use 2.1.4. 317 | No environment specified, will use the following for package resolution (based on the host system): 318 | - arch = $ARCH 319 | - os = $OS 320 | - os-distribution = $OSDISTRIB 321 | - os-version = $OSVERSION 322 | - os-family = $OSFAMILLY 323 | 324 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 325 | [home] Initialised 326 | [home1] Initialised 327 | [home2] Initialised 328 | 329 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 330 | The following packages will be included: 331 | - bar.1 332 | - foo.1 333 | - ocaml.4.13.0 334 | - ocaml-base-compiler.4.13.0 335 | - ocaml-bootstrap.4.13.0 336 | - ocaml-config.2 337 | According to the packages' metadata, the bundle should be installable on any arch/OS. 338 | [NOTE] Opam system sandboxing (introduced in 2.0) will be disabled in the bundle. You need to trust that the build scripts of the included packages don't write outside of their build directory and dest dir. 339 | Continue ? [Y/n] y 340 | 341 | <><> Getting all archives <><><><><><><><><><><><><><><><><><><><><><><><><><><> 342 | 343 | <><> Getting bootstrap packages <><><><><><><><><><><><><><><><><><><><><><><><> 344 | 345 | <><> Building bundle ><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 346 | Done. Bundle generated as $TESTCASE_ROOT/foo-bundle.tar.gz 347 | 348 | 349 | 350 | ============================== Test 3 (fail) ============================== 351 | 352 | 353 | 354 | Trying bundle foo package with a repository that hasn't required package (ocaml-config). That should fail. 355 | 356 | $ opam-bundle foo --repository ./REPO1 --ocaml=4.14.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 357 | OCaml version is set to 4.14.0. 358 | No opam version selected, will use 2.1.4. 359 | No environment specified, will use the following for package resolution (based on the host system): 360 | - arch = $ARCH 361 | - os = $OS 362 | - os-distribution = $OSDISTRIB 363 | - os-version = $OSVERSION 364 | - os-family = $OSFAMILLY 365 | 366 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 367 | [home] Initialised 368 | 369 | <><> Resolving package set ><><><><><><><><><><><><><><><><><><><><><><><><><><> 370 | [ERROR] No solution for foo & ocaml-bootstrap.4.14.0: * Missing dependency: 371 | - ocaml-config 372 | unknown package 373 | 374 | 375 | 376 | 377 | 378 | ============================== Test 4 (fail) ============================== 379 | 380 | 381 | Trying bundle foo package with a repositories that hasn't required ocaml version. That should fail. 382 | 383 | $ opam-bundle foo --repository ./REPO1 --repository ./REPO3 --ocaml=4.13.0 -y 2>&1 | sed 's/arch =.*/arch = $ARCH/;s/os =.*/os = $OS/;s/os-distribution =.*/os-distribution = $OSDISTRIB/;s/os-version =.*/os-version = $OSVERSION/;s/os-family =.*/os-family = $OSFAMILLY/' 384 | OCaml version is set to 4.13.0. 385 | No opam version selected, will use 2.1.4. 386 | No environment specified, will use the following for package resolution (based on the host system): 387 | - arch = $ARCH 388 | - os = $OS 389 | - os-distribution = $OSDISTRIB 390 | - os-version = $OSVERSION 391 | - os-family = $OSFAMILLY 392 | 393 | <><> Initialising repositories ><><><><><><><><><><><><><><><><><><><><><><><><> 394 | [home] Initialised 395 | [home1] Initialised 396 | [ERROR] Package ocaml-system.4.13.0 not found in the repositories 397 | --------------------------------------------------------------------------------