M Makefile +7 -0
@@ 1,7 1,14 @@
+.PHONY: all test smoke-tests
all:
pds
$(MAKE) -f pds.mk all
+test: smoke-tests
+
%:
pds
$(MAKE) -f pds.mk $*
+
+
+smoke-tests: release
+ cd smoke-tests && ./test
M README.org +46 -18
@@ 6,24 6,25 @@ only option required is ~--opam-dir~.
** Variables
The following variables can be set in ~hll.conf~.
-| Name | Required | Type | Description |
-|-------------------+----------+-------------+-----------------------------------------------------------------|
-| desc | yes | string | Description of the package |
-| maintainer | yes | string | The maintainer of the package |
-| authors | yes | string list | List of authors of the repo |
-| homepage | yes | string | Homepage of the repo |
-| bug_reports | no | string | Where bugs should be reported |
-| dev_repo | no | string | URL to where the source of the repo lives |
-| url_template | yes | string | URL template to fetch the package |
-| url_pattern | yes | string | Pattern to replace in the url template with the tag |
-| url_protocol | yes | string | Valid options are "git" and "http" |
-| available | no | string | Adds an available section to the opam, surrounding [] are added |
-| build_deps | no | string list | List of deps needed to build the repo |
-| opam_extra_lines | no | string list | Add extra lines to the end of the opam |
-| deps_blacklist | no | string list | List of deps that should not be in the opam package |
-| deps_map | no | table | Table of package names and the pds deps that compose them |
-| pds.major_version | yes/no | int | The major version of pds the build depends on. |
-| pds.version | yes/no | string | The opam string filter describing the version |
+| Name | Required | Type | Description |
+|-------------------------+----------+-------------+-----------------------------------------------------------------|
+| desc | yes | string | Description of the package |
+| maintainer | yes | string | The maintainer of the package |
+| authors | yes | string list | List of authors of the repo |
+| homepage | yes | string | Homepage of the repo |
+| bug_reports | no | string | Where bugs should be reported |
+| dev_repo | no | string | URL to where the source of the repo lives |
+| url_template | yes | string | URL template to fetch the package |
+| url_pattern | yes | string | Pattern to replace in the url template with the tag |
+| url_protocol | yes | string | Valid options are "git" and "http" |
+| available | no | string | Adds an available section to the opam, surrounding [] are added |
+| build_deps | no | string list | List of deps needed to build the repo |
+| opam_extra_lines | no | string list | Add extra lines to the end of the opam |
+| deps_blacklist | no | string list | List of deps that should not be in the opam package |
+| deps_map | no | table | Table of package names and the pds deps that compose them |
+| pds.major_version | yes/no | int | The major version of pds the build depends on. |
+| pds.version | yes/no | string | The opam string filter describing the version |
+| selector_map.<selector> | no | string | Map a selector in pds to a pin |
Either the ~pds.major_version~ or ~pds.version~ are required but they are
mutually exclusive. This variable selects the ~pds~ version to use to build the
@@ 59,6 60,25 @@ url_protocol = "http"
foo = ["foo_baz", "foo_bar", "foo_zoom"]
"ocaml-bar" = ["bar_baz", "bar_zoom"]
#+END_EXAMPLE
+** Selectors
+hll supports selectors, which are a feature from pds for conditional
+compilation. hll translates selectors into filters on dependencies in opam.
+Selectors in pds can be entirely arbitrary and hll needs a way to map those
+arbitrary selectors to something that opam understands. By default, hll assumes
+that the selectors directly map to opam's OS variable. For example, the
+selector ~linux~ maps to the ~linux~ OS type, and ~freebsd~ to ~freebsd~. This
+mapping can be redefined in the ~selector_map~ section of ~hll.conf~. For
+example, if the pds configuration has a selector called ~bar~ that should map to
+the ~freebsd~ filter in opam, the ~selector_map~ would look like:
+
+#+BEGIN_SRC
+[selector_map]
+bar = "freebsd"
+#+END_SRC
+
+There is one case in which the ~selector_map~ is ignored, and that is when pins
+are specified for a dependency. hll assumes that the pin, which is explicitly
+set, is always right.
* Changelog
** 1.0.0
- Turn a ~pds.conf~ and a ~hll.conf~ into an OPAM package.
@@ 86,3 106,11 @@ foo = ["foo_baz", "foo_bar", "foo_zoom"]
tests.
- Dependencies that exist only in the ~tests~ table will receive a ~test~
constraint in the ~depends~ list.
+** 2.9
+- Support making test deps regular deps. This can be used to install those
+ dependencies in a testing environment. This is needed because telling opam to
+ run tests itself runs tests for the thing being installed and all of its
+ dependencies, which is almost never what one wants.
+** 2.10
+- Support selectors.
+
A => smoke-tests/bin/curl +3 -0
@@ 0,0 1,3 @@
+#! /usr/bin/env bash
+
+echo foo
A => smoke-tests/success/multiple_selectors/expected_opam/packages/multiple_selectors/multiple_selectors.1.0.0/descr +2 -0
A => smoke-tests/success/multiple_selectors/expected_opam/packages/multiple_selectors/multiple_selectors.1.0.0/opam +34 -0
@@ 0,0 1,34 @@
+opam-version: "1.2"
+maintainer: "test@test.com"
+build: [
+ [make "-j%{jobs}%"]
+]
+
+build-test: [
+ [make "-j%{jobs}%" "test"]
+]
+
+install: [
+ [make "PREFIX=%{prefix}%" "install"]
+]
+
+remove: [
+ [make "PREFIX=%{prefix}%" "remove"]
+]
+
+depends: [
+ "bye" { freebsd | linux }
+ "goodbye" { linux }
+ "hi" { !(freebsd | linux) }
+ "ocamlfind"
+ "pds" { build & (>= "5" & < "6") }
+]
+
+authors: [
+ "test@test.com"
+]
+
+homepage: "https://bitbucket.org/mimirops/hll"
+bug-reports: "https://bitbucket.org/mimirops/hll/issues"
+dev-repo: "git@bitbucket.org:mimirops/hll.git"
+
A => smoke-tests/success/multiple_selectors/expected_opam/packages/multiple_selectors/multiple_selectors.1.0.0/url +3 -0
@@ 0,0 1,3 @@
+archive: "https://bitbucket.org/mimirops/hll/get/1.0.0.tar.gz"
+checksum: "d3b07384d113edec49eaa6238ad5ff00"
+
A => smoke-tests/success/multiple_selectors/hll.conf +13 -0
@@ 0,0 1,13 @@
+pds = { major_version = 5 }
+
+desc = "Testing"
+maintainer = "test@test.com"
+authors = [ "test@test.com" ]
+homepage = "https://bitbucket.org/mimirops/hll"
+bug_reports = "https://bitbucket.org/mimirops/hll/issues"
+dev_repo = "git@bitbucket.org:mimirops/hll.git"
+
+url_template = "https://bitbucket.org/mimirops/hll/get/{tag}.tar.gz"
+url_pattern = "{tag}"
+url_protocol = "http"
+
A => smoke-tests/success/multiple_selectors/pds.conf +9 -0
@@ 0,0 1,9 @@
+[src.foo]
+install = false
+deps = [ "hi" ]
+
+[src.foo.selector.freebsd]
+deps = [ "bye" ]
+
+[src.foo.selector.linux]
+deps = [ "bye", "goodbye" ]
A => smoke-tests/success/multiple_selectors/test +4 -0
@@ 0,0 1,4 @@
+#! /usr/bin/env bash
+
+mkdir -p opam
+../../../build/release/hll/hll.native generate --opam-dir "$1" --tag 1.0.0
A => smoke-tests/success/pins/expected_opam/packages/pins/pins.1.0.0/descr +2 -0
A => smoke-tests/success/pins/expected_opam/packages/pins/pins.1.0.0/opam +32 -0
@@ 0,0 1,32 @@
+opam-version: "1.2"
+maintainer: "test@test.com"
+build: [
+ [make "-j%{jobs}%"]
+]
+
+build-test: [
+ [make "-j%{jobs}%" "test"]
+]
+
+install: [
+ [make "PREFIX=%{prefix}%" "install"]
+]
+
+remove: [
+ [make "PREFIX=%{prefix}%" "remove"]
+]
+
+depends: [
+ "hi" { >= "3" }
+ "ocamlfind"
+ "pds" { build & (>= "5" & < "6") }
+]
+
+authors: [
+ "test@test.com"
+]
+
+homepage: "https://bitbucket.org/mimirops/hll"
+bug-reports: "https://bitbucket.org/mimirops/hll/issues"
+dev-repo: "git@bitbucket.org:mimirops/hll.git"
+
A => smoke-tests/success/pins/expected_opam/packages/pins/pins.1.0.0/url +3 -0
@@ 0,0 1,3 @@
+archive: "https://bitbucket.org/mimirops/hll/get/1.0.0.tar.gz"
+checksum: "d3b07384d113edec49eaa6238ad5ff00"
+
A => smoke-tests/success/pins/hll.conf +13 -0
@@ 0,0 1,13 @@
+pds = { major_version = 5 }
+
+desc = "Testing"
+maintainer = "test@test.com"
+authors = [ "test@test.com" ]
+homepage = "https://bitbucket.org/mimirops/hll"
+bug_reports = "https://bitbucket.org/mimirops/hll/issues"
+dev_repo = "git@bitbucket.org:mimirops/hll.git"
+
+url_template = "https://bitbucket.org/mimirops/hll/get/{tag}.tar.gz"
+url_pattern = "{tag}"
+url_protocol = "http"
+
A => smoke-tests/success/pins/pds.conf +3 -0
@@ 0,0 1,3 @@
+[src.foo]
+install = false
+deps = [ "hi" ]
A => smoke-tests/success/pins/pins +1 -0
@@ 0,0 1,1 @@
+hi >= "3"
No newline at end of file
A => smoke-tests/success/pins/test +4 -0
@@ 0,0 1,4 @@
+#! /usr/bin/env bash
+
+mkdir -p opam
+../../../build/release/hll/hll.native generate --opam-dir "$1" --tag 1.0.0 --pins ./pins
A => smoke-tests/success/selector_map/expected_opam/packages/selector_map/selector_map.1.0.0/descr +2 -0
A => smoke-tests/success/selector_map/expected_opam/packages/selector_map/selector_map.1.0.0/opam +33 -0
@@ 0,0 1,33 @@
+opam-version: "1.2"
+maintainer: "test@test.com"
+build: [
+ [make "-j%{jobs}%"]
+]
+
+build-test: [
+ [make "-j%{jobs}%" "test"]
+]
+
+install: [
+ [make "PREFIX=%{prefix}%" "install"]
+]
+
+remove: [
+ [make "PREFIX=%{prefix}%" "remove"]
+]
+
+depends: [
+ "bye" { freebsd }
+ "hi" { !(freebsd) }
+ "ocamlfind"
+ "pds" { build & (>= "5" & < "6") }
+]
+
+authors: [
+ "test@test.com"
+]
+
+homepage: "https://bitbucket.org/mimirops/hll"
+bug-reports: "https://bitbucket.org/mimirops/hll/issues"
+dev-repo: "git@bitbucket.org:mimirops/hll.git"
+
A => smoke-tests/success/selector_map/expected_opam/packages/selector_map/selector_map.1.0.0/url +3 -0
@@ 0,0 1,3 @@
+archive: "https://bitbucket.org/mimirops/hll/get/1.0.0.tar.gz"
+checksum: "d3b07384d113edec49eaa6238ad5ff00"
+
A => smoke-tests/success/selector_map/hll.conf +15 -0
@@ 0,0 1,15 @@
+pds = { major_version = 5 }
+
+desc = "Testing"
+maintainer = "test@test.com"
+authors = [ "test@test.com" ]
+homepage = "https://bitbucket.org/mimirops/hll"
+bug_reports = "https://bitbucket.org/mimirops/hll/issues"
+dev_repo = "git@bitbucket.org:mimirops/hll.git"
+
+url_template = "https://bitbucket.org/mimirops/hll/get/{tag}.tar.gz"
+url_pattern = "{tag}"
+url_protocol = "http"
+
+[selector_map]
+bar = "freebsd"
A => smoke-tests/success/selector_map/pds.conf +6 -0
@@ 0,0 1,6 @@
+[src.foo]
+install = false
+deps = [ "hi" ]
+
+[src.foo.selector.bar]
+deps = [ "bye" ]
A => smoke-tests/success/selector_map/test +4 -0
@@ 0,0 1,4 @@
+#! /usr/bin/env bash
+
+mkdir -p opam
+../../../build/release/hll/hll.native generate --opam-dir "$1" --tag 1.0.0
A => smoke-tests/success/selectors/expected_opam/packages/selectors/selectors.1.0.0/descr +2 -0
A => smoke-tests/success/selectors/expected_opam/packages/selectors/selectors.1.0.0/opam +33 -0
@@ 0,0 1,33 @@
+opam-version: "1.2"
+maintainer: "test@test.com"
+build: [
+ [make "-j%{jobs}%"]
+]
+
+build-test: [
+ [make "-j%{jobs}%" "test"]
+]
+
+install: [
+ [make "PREFIX=%{prefix}%" "install"]
+]
+
+remove: [
+ [make "PREFIX=%{prefix}%" "remove"]
+]
+
+depends: [
+ "bye" { freebsd }
+ "hi" { !(freebsd) }
+ "ocamlfind"
+ "pds" { build & (>= "5" & < "6") }
+]
+
+authors: [
+ "test@test.com"
+]
+
+homepage: "https://bitbucket.org/mimirops/hll"
+bug-reports: "https://bitbucket.org/mimirops/hll/issues"
+dev-repo: "git@bitbucket.org:mimirops/hll.git"
+
A => smoke-tests/success/selectors/expected_opam/packages/selectors/selectors.1.0.0/url +3 -0
@@ 0,0 1,3 @@
+archive: "https://bitbucket.org/mimirops/hll/get/1.0.0.tar.gz"
+checksum: "d3b07384d113edec49eaa6238ad5ff00"
+
A => smoke-tests/success/selectors/hll.conf +12 -0
@@ 0,0 1,12 @@
+pds = { major_version = 5 }
+
+desc = "Testing"
+maintainer = "test@test.com"
+authors = [ "test@test.com" ]
+homepage = "https://bitbucket.org/mimirops/hll"
+bug_reports = "https://bitbucket.org/mimirops/hll/issues"
+dev_repo = "git@bitbucket.org:mimirops/hll.git"
+
+url_template = "https://bitbucket.org/mimirops/hll/get/{tag}.tar.gz"
+url_pattern = "{tag}"
+url_protocol = "http"
A => smoke-tests/success/selectors/pds.conf +6 -0
@@ 0,0 1,6 @@
+[src.foo]
+install = false
+deps = [ "hi" ]
+
+[src.foo.selector.freebsd]
+deps = [ "bye" ]
A => smoke-tests/success/selectors/test +4 -0
@@ 0,0 1,4 @@
+#! /usr/bin/env bash
+
+mkdir -p opam
+../../../build/release/hll/hll.native generate --opam-dir "$1" --tag 1.0.0
A => smoke-tests/success/selectors_test/expected_opam/packages/selectors_test/selectors_test.1.0.0/descr +2 -0
A => smoke-tests/success/selectors_test/expected_opam/packages/selectors_test/selectors_test.1.0.0/opam +34 -0
@@ 0,0 1,34 @@
+opam-version: "1.2"
+maintainer: "test@test.com"
+build: [
+ [make "-j%{jobs}%"]
+]
+
+build-test: [
+ [make "-j%{jobs}%" "test"]
+]
+
+install: [
+ [make "PREFIX=%{prefix}%" "install"]
+]
+
+remove: [
+ [make "PREFIX=%{prefix}%" "remove"]
+]
+
+depends: [
+ "bar" { test & (freebsd) }
+ "bye" { freebsd }
+ "hi" { !(freebsd) }
+ "ocamlfind"
+ "pds" { build & (>= "5" & < "6") }
+]
+
+authors: [
+ "test@test.com"
+]
+
+homepage: "https://bitbucket.org/mimirops/hll"
+bug-reports: "https://bitbucket.org/mimirops/hll/issues"
+dev-repo: "git@bitbucket.org:mimirops/hll.git"
+
A => smoke-tests/success/selectors_test/expected_opam/packages/selectors_test/selectors_test.1.0.0/url +3 -0
@@ 0,0 1,3 @@
+archive: "https://bitbucket.org/mimirops/hll/get/1.0.0.tar.gz"
+checksum: "d3b07384d113edec49eaa6238ad5ff00"
+
A => smoke-tests/success/selectors_test/hll.conf +12 -0
@@ 0,0 1,12 @@
+pds = { major_version = 5 }
+
+desc = "Testing"
+maintainer = "test@test.com"
+authors = [ "test@test.com" ]
+homepage = "https://bitbucket.org/mimirops/hll"
+bug_reports = "https://bitbucket.org/mimirops/hll/issues"
+dev_repo = "git@bitbucket.org:mimirops/hll.git"
+
+url_template = "https://bitbucket.org/mimirops/hll/get/{tag}.tar.gz"
+url_pattern = "{tag}"
+url_protocol = "http"
A => smoke-tests/success/selectors_test/pds.conf +9 -0
@@ 0,0 1,9 @@
+[src.foo]
+install = false
+deps = [ "hi" ]
+
+[src.foo.selector.freebsd]
+deps = [ "bye" ]
+
+[tests.foo.selector.freebsd]
+deps = [ "foo", "bye", "bar" ]
A => smoke-tests/success/selectors_test/test +4 -0
@@ 0,0 1,4 @@
+#! /usr/bin/env bash
+
+mkdir -p opam
+../../../build/release/hll/hll.native generate --opam-dir "$1" --tag 1.0.0
A => smoke-tests/success/simple/expected_opam/packages/simple/simple.1.0.0/descr +2 -0
A => smoke-tests/success/simple/expected_opam/packages/simple/simple.1.0.0/opam +32 -0
@@ 0,0 1,32 @@
+opam-version: "1.2"
+maintainer: "test@test.com"
+build: [
+ [make "-j%{jobs}%"]
+]
+
+build-test: [
+ [make "-j%{jobs}%" "test"]
+]
+
+install: [
+ [make "PREFIX=%{prefix}%" "install"]
+]
+
+remove: [
+ [make "PREFIX=%{prefix}%" "remove"]
+]
+
+depends: [
+ "hi"
+ "ocamlfind"
+ "pds" { build & (>= "5" & < "6") }
+]
+
+authors: [
+ "test@test.com"
+]
+
+homepage: "https://bitbucket.org/mimirops/hll"
+bug-reports: "https://bitbucket.org/mimirops/hll/issues"
+dev-repo: "git@bitbucket.org:mimirops/hll.git"
+
A => smoke-tests/success/simple/expected_opam/packages/simple/simple.1.0.0/url +3 -0
@@ 0,0 1,3 @@
+archive: "https://bitbucket.org/mimirops/hll/get/1.0.0.tar.gz"
+checksum: "d3b07384d113edec49eaa6238ad5ff00"
+
A => smoke-tests/success/simple/hll.conf +13 -0
@@ 0,0 1,13 @@
+pds = { major_version = 5 }
+
+desc = "Testing"
+maintainer = "test@test.com"
+authors = [ "test@test.com" ]
+homepage = "https://bitbucket.org/mimirops/hll"
+bug_reports = "https://bitbucket.org/mimirops/hll/issues"
+dev_repo = "git@bitbucket.org:mimirops/hll.git"
+
+url_template = "https://bitbucket.org/mimirops/hll/get/{tag}.tar.gz"
+url_pattern = "{tag}"
+url_protocol = "http"
+
A => smoke-tests/success/simple/pds.conf +3 -0
@@ 0,0 1,3 @@
+[src.foo]
+install = false
+deps = [ "hi" ]
A => smoke-tests/success/simple/test +4 -0
@@ 0,0 1,4 @@
+#! /usr/bin/env bash
+
+mkdir -p opam
+../../../build/release/hll/hll.native generate --opam-dir "$1" --tag 1.0.0
A => smoke-tests/success/ubiquitious_selector_in_simplest_form/expected_opam/packages/ubiquitious_selector_in_simplest_form/ubiquitious_selector_in_simplest_form.1.0.0/descr +2 -0
A => smoke-tests/success/ubiquitious_selector_in_simplest_form/expected_opam/packages/ubiquitious_selector_in_simplest_form/ubiquitious_selector_in_simplest_form.1.0.0/opam +33 -0
@@ 0,0 1,33 @@
+opam-version: "1.2"
+maintainer: "test@test.com"
+build: [
+ [make "-j%{jobs}%"]
+]
+
+build-test: [
+ [make "-j%{jobs}%" "test"]
+]
+
+install: [
+ [make "PREFIX=%{prefix}%" "install"]
+]
+
+remove: [
+ [make "PREFIX=%{prefix}%" "remove"]
+]
+
+depends: [
+ "bye" { freebsd }
+ "hi"
+ "ocamlfind"
+ "pds" { build & (>= "5" & < "6") }
+]
+
+authors: [
+ "test@test.com"
+]
+
+homepage: "https://bitbucket.org/mimirops/hll"
+bug-reports: "https://bitbucket.org/mimirops/hll/issues"
+dev-repo: "git@bitbucket.org:mimirops/hll.git"
+
A => smoke-tests/success/ubiquitious_selector_in_simplest_form/expected_opam/packages/ubiquitious_selector_in_simplest_form/ubiquitious_selector_in_simplest_form.1.0.0/url +3 -0
@@ 0,0 1,3 @@
+archive: "https://bitbucket.org/mimirops/hll/get/1.0.0.tar.gz"
+checksum: "d3b07384d113edec49eaa6238ad5ff00"
+
A => smoke-tests/success/ubiquitious_selector_in_simplest_form/hll.conf +12 -0
@@ 0,0 1,12 @@
+pds = { major_version = 5 }
+
+desc = "Testing"
+maintainer = "test@test.com"
+authors = [ "test@test.com" ]
+homepage = "https://bitbucket.org/mimirops/hll"
+bug_reports = "https://bitbucket.org/mimirops/hll/issues"
+dev_repo = "git@bitbucket.org:mimirops/hll.git"
+
+url_template = "https://bitbucket.org/mimirops/hll/get/{tag}.tar.gz"
+url_pattern = "{tag}"
+url_protocol = "http"
A => smoke-tests/success/ubiquitious_selector_in_simplest_form/pds.conf +6 -0
@@ 0,0 1,6 @@
+[src.foo]
+install = false
+deps = [ "hi" ]
+
+[src.foo.selector.freebsd]
+deps = [ "hi", "bye" ]
A => smoke-tests/success/ubiquitious_selector_in_simplest_form/test +4 -0
@@ 0,0 1,4 @@
+#! /usr/bin/env bash
+
+mkdir -p opam
+../../../build/release/hll/hll.native generate --opam-dir "$1" --tag 1.0.0
A => smoke-tests/test +39 -0
@@ 0,0 1,39 @@
+#! /usr/bin/env bash
+
+set -e
+set -u
+set -o pipefail
+
+tmp_dir="$(mktemp -d)"
+
+trap "rm -rf $tmp_dir" EXIT
+
+export PATH=$PWD/bin:$PATH
+
+num_tests="$(ls success | wc -l | awk '{print $1}')"
+
+echo "1..${num_tests}" > ../build/release/hll/smoke_tests.tap
+
+test_count=1
+failed_test=0
+
+for test in success/*; do
+ pushd "$test" > /dev/null
+ test_name="$(basename "$test")"
+ echo "Testing $test_name"
+ mkdir -p "$tmp_dir/$test_name"
+ set +e
+ ./test "$tmp_dir/$test_name" && diff -r "$tmp_dir/$test_name" expected_opam
+ if [[ "$?" -eq 0 ]]; then
+ echo "ok ${test_count} ${test_name}" >> ../../../build/release/hll/smoke_tests.tap
+ else
+ echo "not ok ${test_count} ${test_name}" >> ../../../build/release/hll/smoke_tests.tap
+ failed_test=1
+ fi
+ set -e
+ echo "Passed $(basename $test_name)"
+ popd > /dev/null
+ test_count=$((test_count + 1))
+done
+
+exit "$failed_test"
M src/hll/hll.ml +240 -18
@@ 49,6 49,20 @@ module Cmdline = struct
info "help" ~doc)
end
+let default_selector_map =
+ let make_pair x = (x, x) in
+ String_map.of_list
+ [ make_pair "darwin"
+ ; make_pair "linux"
+ ; make_pair "freebsd"
+ ; make_pair "openbsd"
+ ; make_pair "netbsd"
+ ; make_pair "dragonfly"
+ ; make_pair "cygwin"
+ ; make_pair "win32"
+ ; make_pair "unix"
+ ]
+
let value_opt ~default = function
| Some v -> v
| None -> default
@@ 105,7 119,7 @@ module Generate = struct
match t.url_protocol with
| Git ->
Printf.sprintf "git: \"%s\"\n" url
- | Http -> begin
+ | Http ->
let lines = P.read_stdout "curl" [| "-L"; url |] in
(*
* Process is, unfortunately, somewhat lame in that it breaks lines up
@@ 115,7 129,6 @@ module Generate = struct
let data = String.concat "\n" lines in
let hex = Digest.string data |> Digest.to_hex in
Printf.sprintf "archive: \"%s\"\nchecksum: \"%s\"\n" url hex
- end
let format_external_deps deps pins =
List.map
@@ 263,6 276,7 @@ module Generate_io = struct
; available : string
; opam_extra_lines : string list
; pds_version : Generate.Pds_version.t
+ ; selector_map : string String_map.t
}
let url_protocol_of_string = function
@@ 270,6 284,27 @@ module Generate_io = struct
| "http" -> Generate.Http
| s -> failwith (Printf.sprintf "Invalid url_protocol (%s) in hll configuration" s)
+ let selector_map table =
+ TomlTypes.Table.(
+ fold
+ (fun key v selectors ->
+ let filter =
+ value_exn
+ ~msg:"Selector map must be string to string"
+ TomlLenses.(get v string)
+ in
+ String_map.add (Key.to_string key) filter selectors)
+ table
+ String_map.empty)
+
+ let get_selector_map hll_conf =
+ let sm = TomlLenses.(get hll_conf (key "selector_map" |-- table)) in
+ match sm with
+ | Some table ->
+ selector_map table
+ | None ->
+ default_selector_map
+
let read fname =
let hll_conf = Toml.Parser.(from_filename fname |> unsafe) in
let maintainer =
@@ 359,6 394,7 @@ module Generate_io = struct
| (_, Some v) ->
Generate.Pds_version.Version v
in
+ let selector_map = get_selector_map hll_conf in
{ maintainer = maintainer
; url_template = url_template
; url_protocol = url_protocol_of_string url_protocol
@@ 374,15 410,20 @@ module Generate_io = struct
; build_deps = String_set.of_list build_deps
; opam_extra_lines = opam_extra_lines
; pds_version = pds_version
+ ; selector_map = selector_map
}
end
module Pds_conf = struct
- type t = { deps : String_set.t
- ; test_deps : String_set.t
+ type t = { deps : string list String_map.t (* Dep -> Selectors *)
+ ; tests_deps : string list String_map.t (* Dep -> Selectors *)
; targets : String_set.t
+ ; selectors : String_set.t
+ ; used_selectors : String_set.t
}
+ let default_selector = ""
+
let list_keys table =
TomlTypes.Table.(
fold
@@ 394,13 435,80 @@ module Generate_io = struct
TomlTypes.Table.(
fold
(fun key v deps ->
- deps @ value_opt
- ~default:[]
- TomlLenses.(get v (table |-- key "deps" |-- array |-- strings)))
+ deps @ value_opt
+ ~default:[]
+ TomlLenses.(get v (table |-- key "deps" |-- array |-- strings)))
table
[])
- let read test_deps_as_regular_deps fname =
+ (* Merge entries in a table and append lists. *)
+ let merge k v1 v2 =
+ match (v1, v2) with
+ | (Some v1, Some v2) -> Some (v1 @ v2)
+ | (Some v, None)
+ | (None, Some v) -> Some v
+ | (None, None) -> assert false
+
+ (* Return a tuple of to String_map's. The first is the map for builds and
+ the second is the deps for tests. *)
+ let selector_deps pds_conf =
+ (* Fold but specifically pick out the selectors of the entries in the
+ table. *)
+ let fold_selectors tbl f init =
+ TomlTypes.Table.fold
+ (fun build v acc ->
+ let selector =
+ value_opt
+ ~default:TomlTypes.Table.empty
+ TomlLenses.(get v (table |-- key "selector" |-- table))
+ in
+ f selector acc)
+ tbl
+ init
+ in
+ (* Look over all of the selectors in a table and merge their deps ->
+ selector map with the passed in map. *)
+ let merge_deps selector acc =
+ TomlTypes.Table.fold
+ (fun slct v acc ->
+ let slct = TomlTypes.Table.Key.to_string slct in
+ let deps =
+ value_opt
+ ~default:[]
+ TomlLenses.(get v (table |-- key "deps" |-- array |-- strings))
+ in
+ deps
+ |> ListLabels.map ~f:(fun d -> (d, [slct]))
+ |> String_map.of_list
+ |> String_map.merge merge acc)
+ selector
+ acc
+ in
+ let src =
+ value_opt
+ ~default:TomlTypes.Table.empty
+ TomlLenses.(get pds_conf (key "src" |-- table))
+ in
+ let tests =
+ value_opt
+ ~default:TomlTypes.Table.empty
+ TomlLenses.(get pds_conf (key "tests" |-- table))
+ in
+ let src_deps =
+ fold_selectors
+ src
+ merge_deps
+ String_map.empty
+ in
+ let tests_deps =
+ fold_selectors
+ tests
+ merge_deps
+ String_map.empty
+ in
+ (src_deps, tests_deps)
+
+ let read test_deps_as_regular_deps fname sm =
let pds_conf = Toml.Parser.(from_filename fname |> unsafe) in
let srcs =
value_opt
@@ 412,25 520,71 @@ module Generate_io = struct
~default:TomlTypes.Table.empty
TomlLenses.(get pds_conf (key "tests" |-- table))
in
+ let src_default_deps =
+ String_map.of_list
+ (ListLabels.map ~f:(fun d -> (d, [default_selector])) (list_deps srcs))
+ in
+ let tests_default_deps =
+ String_map.of_list
+ (ListLabels.map ~f:(fun d -> (d, [default_selector])) (list_deps tests))
+ in
let targets = String_set.of_list (list_keys srcs) in
- let deps = String_set.of_list (list_deps srcs) in
- let test_deps = String_set.of_list (list_deps tests) in
+ let (deps, tests_deps) = selector_deps pds_conf in
+ (* Convert the selectors via the map *)
+ (* TODO Make this get less exceptiony *)
+ let deps =
+ String_map.merge
+ merge
+ (String_map.map (ListLabels.map ~f:(CCFun.flip String_map.find sm)) deps)
+ src_default_deps
+ in
+ let tests_deps =
+ String_map.merge
+ merge
+ (String_map.map (ListLabels.map ~f:(CCFun.flip String_map.find sm)) tests_deps)
+ tests_default_deps
+ in
(* Those deps that are just in the test section *)
- let test_only_deps = String_set.diff test_deps deps in
+ let tests_only_deps = String_map.filter (fun k _ -> not (String_map.mem k deps)) tests_deps in
+ let selectors = String_set.of_list (ListLabels.map ~f:snd (String_map.bindings sm)) in
+ let used_selectors =
+ String_set.remove
+ default_selector
+ (String_set.of_list
+ (List.concat
+ (ListLabels.map ~f:snd (String_map.bindings deps) @
+ ListLabels.map ~f:snd (String_map.bindings tests_only_deps))))
+ in
if not test_deps_as_regular_deps then
{ deps = deps
- ; test_deps = test_only_deps
+ ; tests_deps = tests_only_deps
; targets = targets
+ ; selectors = selectors
+ ; used_selectors = used_selectors
}
else
- { deps = String_set.union deps test_only_deps
- ; test_deps = String_set.empty
+ { deps = String_map.merge merge deps tests_only_deps
+ ; tests_deps = String_map.empty
; targets = targets
+ ; selectors = selectors
+ ; used_selectors = used_selectors
}
- let external_deps t = String_set.diff t.deps t.targets
+ let external_deps t =
+ String_set.diff
+ (String_set.of_list (ListLabels.map ~f:fst (String_map.bindings t.deps)))
+ t.targets
- let test_external_deps t = String_set.diff t.test_deps t.targets
+ let test_external_deps t =
+ String_set.diff
+ (String_set.of_list (ListLabels.map ~f:fst (String_map.bindings t.tests_deps)))
+ t.targets
+
+ let only_in_default_selector v _ = v = [default_selector]
+
+ let has_default_selector v _ = ListLabels.mem default_selector ~set:v
+
+ let remove_default_selector v _ = ListLabels.filter ~f:((<>) default_selector) v
end
module Pins = struct
@@ 495,6 649,73 @@ let maybe_load_pins = function
| Some file -> Generate_io.Pins.read file
| None -> Generate_io.Pins.empty
+(* TODO Clean up all the duplication *)
+let merge_pins_with_selector_deps pins pds_conf =
+ let pins =
+ String_map.fold
+ (fun dep v acc ->
+ (* If there is already a pin, it overrides anything we want to do. *)
+ match String_map.get dep acc with
+ | Some _ ->
+ acc
+ | None when Generate_io.Pds_conf.only_in_default_selector v pds_conf ->
+ let used_selectors =
+ String_set.elements pds_conf.Generate_io.Pds_conf.used_selectors
+ in
+ if used_selectors <> [] then
+ let pin = "!(" ^ (String.concat " | " used_selectors) ^ ")" in
+ String_map.add dep pin acc
+ else
+ acc
+ | None when Generate_io.Pds_conf.has_default_selector v pds_conf ->
+ let used_selectors = pds_conf.Generate_io.Pds_conf.used_selectors in
+ let v = String_set.of_list (Generate_io.Pds_conf.remove_default_selector v pds_conf) in
+ let negative_selectors = String_set.diff used_selectors v in
+ if not (String_set.is_empty negative_selectors) then
+ let pin =
+ "!(" ^ (String.concat " | " (String_set.elements negative_selectors)) ^ ")"
+ in
+ String_map.add dep pin acc
+ else
+ acc
+ | None ->
+ let pin = String.concat " | " v in
+ String_map.add dep pin acc)
+ pds_conf.Generate_io.Pds_conf.deps
+ pins
+ in
+ String_map.fold
+ (fun dep v acc ->
+ (* If there is already a pin, it overrides anything we want to do. *)
+ match String_map.get dep acc with
+ | Some _ ->
+ acc
+ | None when Generate_io.Pds_conf.only_in_default_selector v pds_conf ->
+ let used_selectors =
+ String_set.elements pds_conf.Generate_io.Pds_conf.used_selectors
+ in
+ if used_selectors <> [] then
+ let pin = "test & !(" ^ (String.concat " | " used_selectors) ^ ")" in
+ String_map.add dep pin acc
+ else
+ acc
+ | None when Generate_io.Pds_conf.has_default_selector v pds_conf ->
+ let selectors = pds_conf.Generate_io.Pds_conf.selectors in
+ let v = String_set.of_list (Generate_io.Pds_conf.remove_default_selector v pds_conf) in
+ let negative_selectors = String_set.diff selectors v in
+ let pin =
+ if not (String_set.is_empty negative_selectors) then
+ "test & !(" ^ (String.concat " | " (String_set.elements negative_selectors)) ^ ")"
+ else
+ "test"
+ in
+ String_map.add dep pin acc
+ | None ->
+ let pin = "test & (" ^ (String.concat " | " v) ^ ")" in
+ String_map.add dep pin acc)
+ pds_conf.Generate_io.Pds_conf.tests_deps
+ pins
+
let generate_pkg
opam_dir
(tag_opt : string option)
@@ 503,9 724,10 @@ let generate_pkg
pds_conf
test_deps_as_regular_deps =
let tag = maybe_load_tag tag_opt in
- let pins = maybe_load_pins pins_file_opt in
let hll_conf = Generate_io.Hll_conf.read hll_conf in
- let pds_conf = Generate_io.Pds_conf.read test_deps_as_regular_deps pds_conf in
+ let selector_map = hll_conf.Generate_io.Hll_conf.selector_map in
+ let pds_conf = Generate_io.Pds_conf.read test_deps_as_regular_deps pds_conf selector_map in
+ let pins = merge_pins_with_selector_deps (maybe_load_pins pins_file_opt) pds_conf in
let gen_t =
Generate.({ tag = tag
; url_protocol = hll_conf.Generate_io.Hll_conf.url_protocol