diff --git a/.gitignore b/.gitignore index c1a8898..8326f35 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ /.nrepl-history /test-data/ /test/resources/data/grill/ +/test/resources/data/meta/ /test/resources/data/test-search-strat/ /test/resources/data/test-version-comparison/ /test/resources/test-data/ diff --git a/TODO b/TODO index 2a6bf03..dffdc9e 100644 --- a/TODO +++ b/TODO @@ -1,13 +1,5 @@ -- [ ] When making more package systems, pass `options` to the thing - so that e.g. the helm chart package system can make smart decisions - about what repo to present based on conflict strategy. -- [ ] Docs: package-system implies a *default* version comparison - algorithm consistent with what package system is used -- [ ] Docs: generate-repo-index version comparison -- [ ] Docs: resolve-locations version comparison -- [ ] Docs: query-repo version comparison -- [ ] Merge rpm/debian branch into develop, make it work -- [ ] Create bintray repos for degasolv rpm and deb -- [ ] Update docs to match for release -- [ ] Release -- [ ] With RPM/DEB, set up release +- [ ] Docs: + - [ ] Set Up Guide + - [ ] Star me on GitHub + - [ ] Add new logo +- [ ] BOOT fix so that most of build is in it diff --git a/build b/build deleted file mode 100755 index ab6225d..0000000 --- a/build +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh -POSIXLY_CORRECT=1 -set -e -set -x - -# It is assumed that the PWD is the root of the source code -if [ ! -s "project.clj" ] || \ - ! grep -q -E 'defproject *dependable' ./project.clj -then - echo "This script must be run from the root of the source code for" >&2 - echo "dependable." >&2 - exit 1 -fi - -if [ "${TRAVIS}" = "true" ] -then - leinw="lein2" -else - leinw="buildutils/lein" -fi - -set -x - -${leinw} compile -${leinw} test -# Need to fix this so that it checks the other loaded files. -#${leinw} cloverage - -# Test the coverage -#buildutils/coverage.awk target/coverage/coverage.txt - -# Tests passed, jar it. -${leinw} jar - -# Also uberjar it. - -# Also package it. -fpm -s - diff --git a/docs/changelog.rst b/docs/changelog.rst index dc970fe..913acb1 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -9,27 +9,28 @@ and this project adheres to `Semantic Versioning`_. .. _Semantic Versioning: http://semver.org/spec/v2.0.0.html .. _Keep a Changelog: http://keepachangelog.com/en/1.0.0/ - -`Unreleased`_ -------------- +`1.11.0`_ +--------- Added +++++ - -Changed -+++++++ - -Fixed -+++++ - +- Added the ``--meta`` :ref:`option ` to + :ref:`generate-card ` +- Added metadata a la ``--meta`` to the ``apt`` :ref:`package system + ` (experimental) +- Added the ``edn`` :ref:`output format option ` for + the ``resolve-locations`` :ref:`subcommand ` +- Added the ``--output-format`` :ref:`option + ` to the :ref:`query-repo ` + command `1.10.0`_ ------------- Added +++++ -- Added the ``--output-format`` option to :ref:`resolve-locations - ` +- Added the ``--output-format`` :ref:`option ` to + :ref:`resolve-locations ` `1.9.0`_ -------- @@ -38,9 +39,6 @@ Added +++++ - Added the :ref:`pessimistic greater-than ` comparison operator ``><``. -Changed -+++++++ - Fixed +++++ - Removed validation from the config file option, allowing it to be a URL or @@ -54,12 +52,16 @@ Fixed Added +++++ -- Distribution is now done via RPM and Debian package as well as JAR file -- Added the ``--version-comparison`` option :ref:`resolve-locations - ` and :ref:`query-repo `, - allowing the user to specify which version comparison algorithm is used. +- Distribution is now done via RPM and Debian package as well as JAR fil +- Added the ``--version-comparison`` option to + :ref:`generate-repo-index ` (option :ref:`here + `), :ref:`resolve-locations + ` (option :ref:`here `) + and :ref:`query-repo ` (option :ref:`here + `), allowing the user to specify which + version comparison algorithm is used. - Added the ``--search-strat`` option to :ref:`resolve-locations - `, allowing users to select breadth first + `, allowing users to select breadth first search or depth first search during resolution - Added the :ref:`matches ` operator (``<>REGEX``) which matches a version against a regex @@ -94,7 +96,8 @@ Fixed Added +++++ -- Added ``--option-pack``, the ability to specify multiple options +- Added ``--option-pack``, the ability to :ref:`specify multiple + options at once ` Fixed +++++ @@ -108,7 +111,8 @@ Fixed Added +++++ - Formatted docs better on the front page for PDF purposes -- Add ability to use any (long) option on the command line in display-config +- Add ability to use any (long) option on the command line in + :ref:`display-config ` Improved ++++++++ @@ -117,9 +121,89 @@ Improved - Changed apt reop function from filtering a list to lookup in a map, increasing its speed -.. _Unreleased: https://github.com/djhaskin987/degasolv/compare/1.10.0...HEAD +`1.5.1`_ +-------- + +Added ++++++ + +- In just ~15 seconds, it slurps in a rather large apt repository +Packages.gz file. In another ~45 seconds, it resolves the +ubuntu-desktop package, spitting out a grand total of 797 packages +with their locations. + +Fixed ++++++ + +- While using the apt data and package system to profile degasolv, I + found some rather nasty bugs. This release fixes them. This tool is + now ready for prime time. + +`1.5.0`_ +-------- + +Added ++++++ +- Added the ``--disable-alternatives`` :ref:`option + ` and the ``--enable-alternatives`` + :ref:`option ` for debugging purposes. + +`1.4.0`_ +-------- + +Added ++++++ + +- Added the ``--present-package`` :ref:`option ` and + the ``--package-system`` :ref:`option ` to the + :ref:`resolve-locations ` subcommand. This was so + that degasolv could be profiled using apt package repos + (real-world data) and thereby have its performance optimized. + +`1.3.0`_ +-------- + +Added ++++++ + +- Add standard input as a file type. All options which take a file name may now + have ``-`` given as the filename, to specify that standard in should be used. + +`1.2.0`_ +-------- + +Added ++++++ + +- Added the ability to specify multiple configuration files, + thus allowing for site-wide configuration. + +`1.1.0`_ +-------- + +Added ++++++ + +- Added the ``--conflict-strat`` :ref:`option ` to the + :ref:`resolve-locations ` subcommand. + +- Added docs and tests. + +1.0.2 +----- + +- This isn't the first release, but for the purposes of these docs, it is :D + +.. _Unreleased: https://github.com/djhaskin987/degasolv/compare/1.11.0...HEAD +.. _1.10.0: https://github.com/djhaskin987/degasolv/compare/1.10.0...1.11.0 .. _1.10.0: https://github.com/djhaskin987/degasolv/compare/1.9.0...1.10.0 .. _1.9.0: https://github.com/djhaskin987/degasolv/compare/1.8.0...1.9.0 .. _1.8.0: https://github.com/djhaskin987/degasolv/compare/1.7.0...1.8.0 .. _1.7.0: https://github.com/djhaskin987/degasolv/compare/1.6.0...1.7.0 .. _1.6.0: https://github.com/djhaskin987/degasolv/compare/1.5.1...1.6.0 +.. _1.5.1: https://github.com/djhaskin987/degasolv/compare/1.5.0...1.5.1 +.. _1.5.0: https://github.com/djhaskin987/degasolv/compare/1.4.0...1.5.0 +.. _1.4.0: https://github.com/djhaskin987/degasolv/compare/1.3.0...1.4.0 +.. _1.3.0: https://github.com/djhaskin987/degasolv/compare/1.2.0...1.3.0 +.. _1.2.0: https://github.com/djhaskin987/degasolv/compare/1.1.0...1.2.0 +.. _1.1.0: https://github.com/djhaskin987/degasolv/compare/1.0.2...1.1.0 diff --git a/docs/command-reference.rst b/docs/command-reference.rst index 40f9808..9678eb6 100644 --- a/docs/command-reference.rst +++ b/docs/command-reference.rst @@ -4,9 +4,34 @@ Degasolv Command Reference This article describes the Degasolv CLI, what subcommands and options there are, and what they are for. +Some Notes on Versions +---------------------- + +- On a best-effort basis, features have had the version that they first + appeared associated with them in this guide. + +- Anything tagged with version 1.0.2 *really* means "1.0.2 or + earlier". The history gets shaky before that :) + +- The first version of degasolv (for the purposes of this guide) + released was 1.0.2 . + +- As of version 1.3.0, All options which take a file name may now have + ``-`` given as the filename, to specify that standard in should be + used. + +- The earliest usable released version of degasolv that can be + recommended for use is 1.5.1 . Anything before that wasn't profiled, + and had some pretty bad bugs in it. + +.. _top-level-cli: + Top-Level CLI ------------- +Top-Level Usage Page +++++++++++++++++++++ + Running ``java -jar degasolv--standalone.jar -h`` will yield a page that looks something like this:: @@ -30,162 +55,207 @@ a page that looks something like this:: Simply run `degasolv -h` for help information. -Explanation of options: - -- ``-c FILE``, ``--config-file FILE``: A config file may be specified - at the command line. The config file is in the `EDN format`_. As a - rule, any option for any sub-command may be given a value from this - config file, using the keyword form of the argument. For example, - instead of running this command:: - - java -jar degasolv--standalone.jar \ - generate-repo-index --search-directory /some/directory \ - [...] - - A configuration file that looks like this could be used instead:: - - ;; filename: config.edn - { - :search-directory "/some/directory" - } - - With this command:: - - java -jar degasolv--standalone.jar \ - --config-file "$PWD/config.edn" \ - generate-repo-index [...] - - Notable exceptions to this rule include options which may be - specified multiple times. These options are named using singular - nouns (e.g. ``--repository REPO``), but their corresponding - configuration file keys are specified using plural nouns (e.g., - ``:repositories ["REPO1",...]``). - - So, instead of using this - command:: - - java -jar degasolv--standalone.jar \ - resolve-locations \ - --disable-alternatives \ - --present-package "x==0.1" \ - --present-package "y==0.2" \ - --repository "https://example.com/repo1/" \ - --repository "https://example.com/repo2/" \ - --requirement "a" \ - --requirement "b" - [...] - - This configuration file might be used:: - - ; filename: config.edn - { - :alternatives false - :respositories ["https://example.com/repo1/" - "https://example.com/repo2/"] - :requirements ["a" - "b"] - :present-packages ["x==0.1" - "y==0.2"] - } - - With this command:: - - java -jar degasolv--standalone.jar \ - --config-file "$PWD/config.edn" \ - resolve-locations \ - [...] - - The config file may be a URL or a filepath. Both HTTP and HTTPS URLs are - supported. If the config file is ``-`` (the hyphen character), degasolv - will read standard input instead of any specific file or - URL. - - As of version 1.2.0, the ``--config-file`` option may be specified multiple - times. Each configuration file specified will get its configuration - merged into the previously specified configuration files. If both - configuration files contain the same option, the option specified in - the latter specified configuration file will be used. - - .. _config files section: - - As an example, consider the following `display-config command`_:: - - java -jar degasolv--standalone.jar \ - --config-file "$PWD/a.edn" \ - --config-file "$PWD/b.edn" \ - display-config - - If this is the contents of the file ``a.edn``:: - - { - :index-strat "priority" - :repositories ["https://example.com/repo1/"] - :id "a" - :version "1.0.0" - } - - And this were the contents of ``b.edn``:: - - { - :conflict-strat "exclusive" - :repositories ["https://example.com/repo2/"] - :id "b" - :version "2.0.0" - } - - Then the output of the above command would look like this:: - - { - :index-strat "priority", - :repositories ["https://example.com/repo2/"], - :id "b", - :version "2.0.0", - :conflict-strat "exclusive", - :arguments ["display-config"] - } - - .. _site-wide: - - The merging of config files, together with the interesting - fact that config files may be specified via HTTP/HTTPS URLs, - allows the user to specify a *site config file*. - - Many options, such as ``--index-strat``, ``--conflict-strat``, - and ``--resolve-strat`` fundamentally change how degasolv - works, and so it is recommended that they are specified site-wide. - Specifying these in a site config file, then serving that config - file internally via HTTP(S) would allow all instances of degasolv - to point to a site-wide file, together with a build-specific config - file, as in this example:: - - java -jar degasolv--standalone.jar \n - --config-file "https://nas.example.com/degasolv/site.edn" \ - --config-file "./degasolv.edn" \ - generate-card - +Explanation of Options +++++++++++++++++++++++ + +Using Configuration Files +************************* + +Basic Configuration Usage +######################### + ++-----------------------------+---------------------------------------+ +| Short option | ``-c FILE`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--config-file FILE`` | ++-----------------------------+---------------------------------------+ +| Config file key | N/A | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +A config file may be specified at the command line. The config file is +in the `EDN format`_. As a rule, any option for any sub-command may be +given a value from this config file, using the keyword form of the +argument. For example, instead of running this command:: + + java -jar degasolv--standalone.jar \ + generate-repo-index --search-directory /some/directory \ + [...] + +A configuration file that looks like this could be used instead:: + + ;; filename: config.edn + { + :search-directory "/some/directory" + } + +With this command:: + + java -jar degasolv--standalone.jar \ + --config-file "$PWD/config.edn" \ + generate-repo-index [...] + +Notable exceptions to this rule include options which may be +specified multiple times. These options are named using singular +nouns (e.g. ``--repository REPO``), but their corresponding +configuration file keys are specified using plural nouns (e.g., +``:repositories ["REPO1", ... ]``). + +So, instead of using this +command:: + + java -jar degasolv--standalone.jar \ + resolve-locations \ + --disable-alternatives \ + --present-package "x==0.1" \ + --present-package "y==0.2" \ + --repository "https://example.com/repo1/" \ + --repository "https://example.com/repo2/" \ + --requirement "a" \ + --requirement "b" + [...] + +This configuration file might be used:: + + ; filename: config.edn + { + :alternatives false + :respositories ["https://example.com/repo1/" + "https://example.com/repo2/"] + :requirements ["a" + "b"] + :present-packages ["x==0.1" + "y==0.2"] + } + +With this command:: + + java -jar degasolv--standalone.jar \ + --config-file "$PWD/config.edn" \ + resolve-locations \ + [...] + +As of version 1.3.0, The config file may be a URL or a filepath. Both +HTTP and HTTPS URLs are supported. If the config file is ``-`` (the +hyphen character), degasolv will read standard input instead of any +specific file or URL. + +Using Multiple Configuration Files +################################## + +As of version 1.2.0, the ``--config-file`` option may be specified multiple +times. Each configuration file specified will get its configuration +merged into the previously specified configuration files. If both +configuration files contain the same option, the option specified in +the latter specified configuration file will be used. + +.. _config files section: + +As an example, consider the following `display-config command`_:: + + java -jar degasolv--standalone.jar \ + --config-file "$PWD/a.edn" \ + --config-file "$PWD/b.edn" \ + display-config + +If this is the contents of the file ``a.edn``:: + + { + :index-strat "priority" + :repositories ["https://example.com/repo1/"] + :id "a" + :version "1.0.0" + } + +And this were the contents of ``b.edn``:: + + { + :conflict-strat "exclusive" + :repositories ["https://example.com/repo2/"] + :id "b" + :version "2.0.0" + } + +Then the output of the above command would look like this:: + + { + :index-strat "priority", + :repositories ["https://example.com/repo2/"], + :id "b", + :version "2.0.0", + :conflict-strat "exclusive", + :arguments ["display-config"] + } + +.. _site-wide: + +Using Site-Wide Configuration Files +################################### + +The merging of config files, together with the interesting +fact that config files may be specified via HTTP/HTTPS URLs, +allows the user to specify a *site config file*. + +Multiple sub-commands have options ending in ``-strat`` which +fundamentally change how degasolv works. These are +``--conflict-strat``, ``--index-strat``, ``--resolve-strat`` and +``--search-strat``. It is therefore recommended that they are +specified site-wide. Specifying these in a site config file, then +serving that config file internally via HTTP(S) would allow all +instances of degasolv to point to a site-wide file, together with a +build-specific config file, as in this example:: + + java -jar degasolv--standalone.jar \ + --config-file "https://nas.example.com/degasolv/site.edn" \ + --config-file "./degasolv.edn" \ + generate-card + +.. _option-pack: .. _option pack: -- ``-k PACK``, ``--option-pack PACK``, ``:option-packs ["PACK1",...]``: Specify - one or more option packs. - - Degasolv ships with several "option packs", each of which imply several degasolv - options at once. When an - option pack is specified, degasolv looks up which option pack is used and what - options are implied by using it. More than one option pack may be specified. - If option packs are specified both on the command line and in the config file, - the option packs on the command line are used and the ones in the config file - are ignored. - - The following option packs are supported in the current version: - - ``multi-version-mode``: Added as of version 1.7.0 . Implies - ``--conflict-strat inclusive``, - ``--resolve-strat fast``, and ``--disable-alternatives``. - - ``firstfound-version-mode``: Added as of version 1.7.0 . Implies - ``--conflic-strat prioritized``, - ``--resolve-strat fast``, and ``--disable-alternatives``. - -- ``-h``, ``--help``: Prints the help page. This can be used on every - sub-command as well. +Option Packs +************ + ++-----------------------------+---------------------------------------+ +| Short option | ``-k PACK`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--option-pack PACK`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:option-packs ["PACK1",...]`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.7.0 | ++-----------------------------+---------------------------------------+ + +Specify one or more option packs. + +Degasolv ships with several "option packs", each of which imply +several degasolv options at once. When an option pack is specified, +degasolv looks up which option pack is used and what options are +implied by using it. More than one option pack may be specified. If +option packs are specified both on the command line and in the config +file, the option packs on the command line are used and the ones in +the config file are ignored. + +The following option packs are supported in the current version: + - ``multi-version-mode``: Added as of version 1.7.0 . Implies + ``--conflict-strat inclusive``, + ``--resolve-strat fast``, and ``--disable-alternatives``. + - ``firstfound-version-mode``: Added as of version 1.7.0 . Implies + ``--conflic-strat prioritized``, + ``--resolve-strat fast``, and ``--disable-alternatives``. + +Print the Help Page +******************* + ++------------------+------------------------+---------------------------------+ +| Short option | Long option | Config File Key | ++------------------+------------------------+---------------------------------+ +| ``-h`` | ``--help`` | N/A | ++------------------+------------------------+---------------------------------+ + +``-h``, ``--help``: Prints the help page. This can be used on every +sub-command as well. .. _EDN format: https://github.com/edn-format/edn @@ -195,6 +265,9 @@ Explanation of options: CLI for ``display-config`` -------------------------- +Usage Page for ``display-config`` ++++++++++++++++++++++++++++++++++ + Running ``java -jar degasolv--standalone.jar display-config -h`` returns a page that looks something like this:: @@ -225,12 +298,16 @@ returns a page that looks something like this:: --version true Version of the package -h, --help Print this help page -The ``display-config`` command is used to print all the options -in the *effective configuration*. It allows the user to debug -configuration by printing the actual configuration used by degasolv -after all the command-line arguments and config files have -been merged together. An example of this is found in the -`config files section`_. +Overview of ``display-config`` +++++++++++++++++++++++++++++++ + +*This subcommand introduced as of version 1.6.0*. + +The ``display-config`` command is used to print all the options in the +*effective configuration*. It allows the user to debug configuration +by printing the actual configuration used by degasolv after all the +command-line arguments and config files have been merged together. An +example of this is found in the `config files section`_. As of version 1.6.0, ``display-config`` accepts any valid option in long form (``--long-form``) which is accepted by any other @@ -238,9 +315,14 @@ subcommand. This enables the user to print out the effective configuration resulting from multiple config files as well as any options that might be given on the CLI. +.. _generate-card-options: + CLI for ``generate-card`` ------------------------- +Usage Page for ``generate-card`` +++++++++++++++++++++++++++++++++ + Running ``java -jar degasolv--standalone.jar generate-card -h`` returns a page that looks something like this:: @@ -253,6 +335,7 @@ returns a page that looks something like this:: -C, --card-file FILE ./out.dscard The name of the card file -i, --id true ID (name) of the package -l, --location true URL or filepath of the package + -m, --meta K=V Add additional metadata -r, --requirement REQ List requirement ** -v, --version true Version of the package -h, --help Print this help page @@ -263,49 +346,187 @@ returns a page that looks something like this:: - `-v`, `--version`, or the config file key `:version`. - `-l`, `--location`, or the config file key `:location`. +Overview of ``generate-card`` ++++++++++++++++++++++++++++++ + +*This subcommand introduced as of version 1.0.2*. + This subcommand is used to generate a card file. This card file is used to represent a package within a degasolv repository. It is placed in a directory with other card files, and then the ``generate-repo-index`` command is used to search that directory for card files to produce a repository index. -Explanation of options: - -- ``-i ID``, ``--id ID``, ``:id "ID"``: **Required**. Specify the name of the - package described in the card file. May be composed of any characters - other than the following characters: ``<>=!,;|``. - -- ``-v VERSION``, ``--version VERSION``, ``:version "VERSION"``: - **Required**. Specify the name of the package described in the card - file. - -- ``-l LOCATION``, ``--location LOCATION``, ``:location "LOCATION"``: - **Required**. Specify the location of the file associated with the - package to be described in the generated card file. Degasolv does - not place any restrictions on this string; it can be anything, - including a file location or a URL. - -- ``-r REQUIREMENT``, ``--requirement REQUIREMENT``, - ``:requirements ["REQ1", ...]``: List a requirement (dependency) of the - package in the card file. May be specified one or more times as a command - line option, or once as a list of strings in a configuration file. See - :ref:`Specifying a requirement` for more information. - -- ``-C FILE``, ``--card-file FILE``, ``:card-file "FILE"``: - Specify the name of the card file to generate. It is best practice - to name this file after the name of the file referred to by the package's - location with a ``.dscard`` extension. For example, if I created a card - using the option ``--location http://example.com/repo/a-1.0.zip``, - I would name the card file ``a-1.0.zip.dscard``, as in - ``--card-file a-1.0.zip.dscard``. By default, the card file is named - ``out.dscard``. - -- ``-h``, ``--help``: Print a help page for the subcommand ``generate-dscard``. - +Explanation of Options for ``generate-card`` +++++++++++++++++++++++++++++++++++++++++++++ + +Specify Location of the Card File +********************************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-C FILE`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--card-file FILE`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:card-file "FILE"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +Specify the name of the card file to generate. It is best practice +to name this file after the name of the file referred to by the package's +location with a ``.dscard`` extension. For example, if I created a card +using the option ``--location http://example.com/repo/a-1.0.zip``, +I would name the card file ``a-1.0.zip.dscard``, as in +``--card-file a-1.0.zip.dscard``. By default, the card file is named +``out.dscard``. + +Specify the ID (Name) of the Package +************************************ + ++-----------------------------+---------------------------------------+ +| Short option | ``-i ID`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--id ID`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:id "ID"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +**Required**. Specify the ID of the package described in the card +file. The ID serves both as a unique identifier for the package and +its name. It may be composed of any characters other than the +following characters: ``<>=!,;|``. + +Specify the Location of the Package +*********************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-l LOCATION`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--location LOCATION`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:location "LOCATION"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +**Required**. Specify the location of the file associated with the +package to be described in the generated card file. Degasolv does +not place any restrictions on this string; it can be anything, +including a file location or a URL. + +.. _meta-data: + +Specify Additional Metadata for a Package +***************************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-m K=V`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--meta K=V`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:meta {:key1 "value1" ...}`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.11.0 | ++-----------------------------+---------------------------------------+ + +Specify additional metadata about the package within the card +file. This metadata will stay with the package information in its card +file. It will also be printed with other package information about the +package when the package is printed after dependency resolution when +`resolve-locations`_ subcommand is called, provided that the +`output-format`_ option is also used in a mode other than ``plain``. + +This is a powerful feature allowing the operator to build tooling on +top of degasolv. For example, now the operator may store the sha256 +sum of the artifact, the location of its PGP signature, a list of +scripts useful in the build contained within the artifact, etc. + +For key/value pairs specified on the command line, keys are turned +into EDN keywords (e.g., ``:K``) internally and values are simply +taken as strings. Additional metadata can also be specified from a +configuration file as well. When they are specified via config file, +they may be any data type allowed by EDN. + +Key/value pairs specified via configuration file must be children of +the top-level ``:meta`` key, like this:: + + { + ... + :meta { + :sha256sum "sumsumsum" + :otherkey "suchvalue" + :key3 ["values", "can", "be", "lists"] + :key4 {:key1 "or", + :key2 "maps"} + } + } + +If used from the config file, the map's keys and values will be +placed directly in to the card file. If keys ``:id``, ``:version`` +``:location``, or ``:requirements`` are specified in the config +file, or keys ``id=``, ``version=``, ``location=``, or +``requirements=`` on the CLI, they will be ignored. + +Specify a Requirement for a Package +*********************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-r REQ`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--requirement REQ`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:requirements ["REQ1", ...]`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +List a requirement (dependency) of the package in the card file. May +be specified one or more times as a command line option, or once as a +list of strings in a configuration file. See :ref:`Specifying a +requirement` for more information. + +Specify a Version for a Package +******************************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-v VERSION`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--version VERSION`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:version "VERSION"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +**Required**. Specify the name of the package described in the card +file. + +Print the ``generate-card`` Help Page +************************************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-h`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--help`` | ++-----------------------------+---------------------------------------+ +| Config file key | N/A | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +Print a help page for the subcommand ``generate-card``. + +.. _generate-repo-index: CLI for ``generate-repo-index`` ------------------------------- +Usage Page for ``generate-repo-index`` +++++++++++++++++++++++++++++++++++++++ + Running ``java -jar degasolv--standalone.jar generate-repo-index -h`` returns a page that looks something like this:: @@ -321,6 +542,11 @@ returns a page that looks something like this:: -V, --version-comparison CMP maven May be 'debian', 'maven', 'naive', 'python', 'rpm', 'rubygem', or 'semver'. -h, --help Print this help page +Overview of ``generate-repo-index`` ++++++++++++++++++++++++++++++++++++ + +*This subcommand introduced as of version 1.0.2*. + This subcommand is used to generate a repository index file. A repository index file lists all versions of all packages in a particular degasolv repository, together with their locations. This @@ -328,82 +554,136 @@ file's location, whether by file path or URL, would then be given to ``resolve-locations`` and ``query-repo`` commands as degasolv repositories. -Explanation of options: - -- ``-d DIR``, ``--search-directory DIR``, ``:search-directory "DIR"``: - Look for degasolv card files in this directory. The directory will - be recursively searched for files with the ``.dscard`` extension and - their information will be added to the index. Default value is the - present working directory (``.``). - -- ``-I FILE``, ``--index-file FILE``, ``:index-file "FILE"``: Write the - index file at the location ``FILE``. Default value is ``index.dsrepo``. It is - good practice to use the default value. - -- ``-V CMP``, ``--version-comparison CMP``, ``:version-comparison - "CMP"``: Use the specified version comparison algorithm when - generating the repository index. When repository indexes are - generated, lists of packages representing different versions of each - named package are created within the index. These lists are sorted - in descending order by version number, so that the latest version of - a given package is tried first when resolving dependencies. - - This option allows the operator to change what version comparison - algorithm is used. By default, the algorithm is "maven". May be - "maven", "debian", "maven", "naive", "python", "rpm", "rubygem", or - "semver". - - .. caution:: This is one of those options that should not be used - unless the operator has a good reason, but it is - available and usable if needed. - - .. note:: This option should be used with care, since whatever setting - is used will greatly alter behavior. Similar options are availabe - for the ``resolve-locations`` subcommand and the ``query-repo`` - subcommand. They should all agree when used within the same - site. It is therefore recommended that whichever setting is - chosen should be used `site-wide`_ within an organization. - -- ``-a INDEX``, ``--add-to INDEX``, ``:add-to "INDEX"``: Add to - the repository index file found at ``INDEX``. In general, it is best - to simply regenerate a new repository index fresh based on the card files - found in a search directory; however, it may be useful to use this option - to generate a repository file incrementally. - - For example, a card file might be generated during a build, then - added to a repository index file in the same build script:: - - #!/bin/sh - - java -jar degasolv--standalone.jar generate-card \ - -i "a" -v "1.0.0" -l "http://example.com/repo/a-1.0.0.zip" \ - -C "a-1.0.0.zip.dscard" - - java -jar degasolv--standalone.jar generate-repo-index \ - -I "new-index.dsrepo" -a "http://example.com/repo/index.dsrepo" \ - -d "." - - rsync -av a-1.0.0.zip.dscard user@example.com:/var/www/repo/ - rsync -av new-index.dsrepo user@example.com:/var/www/repo/index.dsrepo - - In this example, a card file is generated. Then, a new repository is - generated based on an existing index and a newly generated card - file. Then it is copied up to the repo server, replacing the old - index. The card file is copied up as well to preserve the record in - the search directory on the actual repository server so that a - repository index could be generated on the server in the usual way - later. - - ``INDEX`` may be a URL or a filepath. Both HTTP and HTTPS URLs are - supported. If ``INDEX`` is ``-`` (the hyphen character), degasolv - will read standard input instead of any specific file or - URL. - -.. _resolve-locations-options: +Explanation of Options for ``generate-repo-index`` +++++++++++++++++++++++++++++++++++++++++++++++++++ + +Specify the Repo Search Directory +********************************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-d DIR`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--search-directory DIR`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:search-directory "DIR"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +Look for degasolv card files in this directory. The directory will be +recursively searched for files with the ``.dscard`` extension and +their information will be added to the index. Default value is the +present working directory (``.``). + +Specify the Repo Index File +*************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-I FILE`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--index-file FILE`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:index-file "FILE"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +Write the index file at the location ``FILE``. Default value is +``index.dsrepo``. It is good practice to use the default value. + +.. _version-comparison-generate: + +Specify the Version Comparison Algorithm +**************************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-V CMP`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--version-comparison CMP`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:version-comparison "CMP"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.8.0 | ++-----------------------------+---------------------------------------+ + +Use the specified version comparison algorithm when generating the +repository index. When repository indexes are generated, lists of +packages representing different versions of each named package are +created within the index. These lists are sorted in descending order +by version number, so that the latest version of a given package is +tried first when resolving dependencies. + +This option allows the operator to change what version comparison +algorithm is used. By default, the algorithm is ``maven``. May be +``maven``, ``debian``, ``maven``, ``naive``, ``python``, ``npm``, +``rubygem``, or ``semver``. + +.. caution:: This is one of those options that should not be used + unless the operator has a good reason, but it is available + and usable if needed. + +.. note:: This option should be used with care, since whatever setting + is used will greatly alter behavior. Similar options are availabe + for the ``resolve-locations`` subcommand and the ``query-repo`` + subcommand. They should all agree when used within the same + site. It is therefore recommended that whichever setting is chosen + should be used `site-wide`_ within an organization. + +Add to an Existing Repository Index +*********************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-a INDEX`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--add-to INDEX`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:add-to "INDEX"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +Add to the repository index file found at ``INDEX``. In general, it is +best to simply regenerate a new repository index fresh based on the +card files found in a search directory; however, it may be useful to +use this option to generate a repository file incrementally. + +For example, a card file might be generated during a build, then added +to a repository index file in the same build script:: + + #!/bin/sh + + java -jar degasolv--standalone.jar generate-card \ + -i "a" -v "1.0.0" -l "http://example.com/repo/a-1.0.0.zip" \ + -C "a-1.0.0.zip.dscard" + + java -jar degasolv--standalone.jar generate-repo-index \ + -I "new-index.dsrepo" -a "http://example.com/repo/index.dsrepo" \ + -d "." + + rsync -av a-1.0.0.zip.dscard user@example.com:/var/www/repo/ + rsync -av new-index.dsrepo user@example.com:/var/www/repo/index.dsrepo + +In this example, a card file is generated. Then, a new repository is +generated based on an existing index and a newly generated card +file. Then it is copied up to the repo server, replacing the old +index. The card file is copied up as well to preserve the record in +the search directory on the actual repository server so that a +repository index could be generated on the server in the usual way +later. + +``INDEX`` may be a URL or a filepath. Both HTTP and HTTPS URLs are +supported. As of version 1.3.0, an ``INDEX`` may be specified as +``-``, the hyphen character. If ``INDEX`` is ``-``, degasolv will read +standard input instead of any specific file or URL. + +.. _resolve-locations: CLI for ``resolve-locations`` ----------------------------- +Usage Page for ``resolve-locations`` +++++++++++++++++++++++++++++++++++++ + Running ``java -jar degasolv--standalone.jar resolve-locations -h`` returns a page that looks something like this:: @@ -432,11 +712,16 @@ returns a page that looks something like this:: 1. `-R`, `--repository`, or the config file key `:repositories`. 2. `-r`, `--requirement`, or the config file key `:requirements`. -The ``resolve-locations`` command searches one or more repository index files, -and uses the package information in them to attempt to resolve the requirements -given at the command line. If successful, it exits with a return code of 0 and -outputs the name of each package in the solution it has found, together with -that package's location. +Overview of ``resolve-locations`` ++++++++++++++++++++++++++++++++++ + +*This subcommand introduced as of version 1.0.2*. + +The ``resolve-locations`` command searches one or more repository +index files, and uses the package information in them to attempt to +resolve the requirements given at the command line. If successful, it +exits with a return code of 0 and outputs the name of each package in +the solution it has found, together with that package's location. If the command fails, a non-zero exit code is returned. The output from such a run might look like this:: @@ -471,338 +756,631 @@ fulfill or resolve. Each field is explained as follows: 5. ``Package ID in question``: This field displays the package searched for when the problem was encountered. -Explanation of options: - -- ``-a``, ``--enable-alternatives``, ``:alternatives true``: - Consider all `alternatives`_ encountered while resolving dependencies. - This is the default behavior. It allows the developers and packagers - to decide whether or not to use alternatives. As alternatives are generally - expensive to resolve, packagers should of course use them with caution. - If this option occurs together with the ``--disable-alternatives`` option - on a command line, the last argument of the two specified wins. - - -- ``-A``, ``--disable-alternatives``, ``:alternatives false``: - Consider only the first of any given set of `alternatives`_ for any - particular requirement while resolving dependencies. It allows the package - consumer to debug dependency resolution issues. This is especially useful - when alternatives are used frequently in specifying requirements by - packagers, thus causing performance issues on the part of the package - consumers; or, when trying to figure out why dependencies won't resolve - properly. If this option occurs together with the ``--enable-alternatives`` - option on a command line, the last argument of the two specified wins. - - .. note:: - - Use of this option defeats the purpose of degasolv supporting alternatives - in the first place. This option is intended generally for use - when debugging a build. If it *is* used routinely, it should be used - `site-wide`_. - -- ``-e STRAT``, ``--search-strat STRAT``, ``:search-strat "STRAT"``: - This option determines whether breadth first search or depth first - search is used during package resolution. Valid values are - ``depth-first`` to specify depth-first search or ``breadth-first`` - to specify breadth-first search. This option is set to - ``breadth-first`` by default. +Explanation of Options for ``resolve-locations`` +++++++++++++++++++++++++++++++++++++++++++++++++ + +.. _enable-alternatives: + +Enable the Use of Alternatives +****************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-a`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--enable-alternatives`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:alternatives true`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.5.0 | ++-----------------------------+---------------------------------------+ + +Consider all `alternatives`_ encountered while resolving dependencies. +This is the default behavior. It allows the developers and packagers +to decide whether or not to use alternatives. As alternatives are +generally expensive to resolve, packagers should of course use them +with caution. If this option occurs together with the +``--disable-alternatives`` option on a command line, the last argument +of the two specified wins. + +.. _disable-alternatives: + +Disable the Use of Alternatives +******************************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-A`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--disable-alternatives`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:alternatives false`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.5.0 | ++-----------------------------+---------------------------------------+ + +Consider only the first of any given set of `alternatives`_ for any +particular requirement while resolving dependencies. It allows the package +consumer to debug dependency resolution issues. This is especially useful +when alternatives are used frequently in specifying requirements by +packagers, thus causing performance issues on the part of the package +consumers; or, when trying to figure out why dependencies won't resolve +properly. If this option occurs together with the ``--enable-alternatives`` +option on a command line, the last argument of the two specified wins. + +.. note:: + + Use of this option defeats the purpose of degasolv supporting alternatives + in the first place. This option is intended generally for use + when debugging a build. If it *is* used routinely, it should be used + `site-wide`_. + +Specify Solution Search Strategy +******************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-e STRAT`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--search-strat STRAT`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:search-strat "STRAT"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.8.0 | ++-----------------------------+---------------------------------------+ + +This option determines whether breadth first search or depth first +search is used during package resolution. Valid values are +``depth-first`` to specify depth-first search or ``breadth-first`` +to specify breadth-first search. This option is set to +``breadth-first`` by default. .. _conflict strategies: -- ``-f STRAT``, ``--conflict-strat STRAT``, ``:conflict-strat "STRAT"``: - This option determines how encountered version conflicts will be - handled. Valid values are ``exclusive``, ``inclusive``, and - ``prioritized``. The default setting is ``exclusive`` and this setting - should work for most environments. - - .. note:: This option should be used with care, since whatever setting is - used will greatly alter behavior. It is therefore recommended that - whichever setting is chosen should be used `site-wide`_ within an - organization. - - - If set to ``exclusive``, all dependencies and their version - specifications must be satisfied in order for the command to - succeed, and only one version of each package is allowed. This is - the default option, and is the safest, though it may carry with it - significant performance ramifications. It turns dependency - resolution into an NP hard problem. This is normally not a problem - since the number of dependencies at most organizations (on the - order of hundreds) is relatively small, but it is something of which the - reader should be aware. - - - If set to ``inclusive``, all dependencies and their version specifications - must be satisfied in order for the command to succeed, but multiple versions - of each package are allowed to be part of the solution. To call for - similar behavior to ruby's gem or node's npm, for example, set - ``--conflict-strat`` to ``inclusive`` and set ``--resolve-strat`` - to ``fast``. This can be easily and cleanly specified done by using the - ``multi-version-mode`` `option pack`_. - - - If set to ``prioritized``, then the first time a package is required and - is found at a particular version, it will be considered to fulfill the - all other encountered requirements asking for that package. This is - intended to mimic the behavior of java's maven package manager. - - It means that, for example, if package ``a`` at version ``1`` - requires package ``b`` at version ``1`` and also package ``c`` at - version ``1``; and package ``c`` at version ``1`` requires package - ``b`` at version ``2``; then the packages ``a`` at version ``1``, - the package ``b`` at version ``1``, and the package ``c`` at - version ``1`` will be found. Despite the fact that ``c`` needed - ``b`` to be at version ``2``, it had already been found at version - ``1`` and that version was assumed to fulfill all requirements asking - for package ``b``. - - To mimic the behavior of maven, set ``--conflict-strat`` to - ``prioritized`` and ``--resolve-strat`` to ``fast``. This can be - easily and cleanly specified done by using the - ``firstfound-version-mode`` `option pack`_. - - -- ``-o FORMAT``, ``--output-format FORMAT``, ``:output-format "FORMAT"``: - Specify an output format. May be ``plain`` or ``json``. This output format - only takes effect when the package resolution was successful. - - The default output format is ``plain``. It is a simple text format - that was designed for ease of use within bash scripts while also - being somewhat pleasant to look at. - - Example output on a successful run when the format is set to ``plain``:: - - c==3.5.0 @ https://example.com/repo/c-3.5.0.zip - d==0.8.0 @ https://example.com/repo/d-0.8.0.zip - e==1.8.0 @ https://example.com/repo/e-1.8.0.zip - b==2.3.0 @ https://example.com/repo/b-2.3.0.zip - - In the above example out, each line takes the form:: - - == @ - - When the output format is JSON, the output would spit out a JSON - document containing lots of different keys and values representing - some of the internal state degasolv had when it resolved - the packages. Among those keys will be a key called "packages", and it will - look something like this:: - - { - ..., - "packages": [ - { - "name": "c", - "version": "3.5.0", - "location": "https://example.com/repo/c-3.5.0.zip" - }, +Specify Conflict Strategy +************************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-f STRAT`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--conflict-strat STRAT`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:conflict-strat "STRAT"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.1.0 | ++-----------------------------+---------------------------------------+ + +This option determines how encountered version conflicts will be +handled. Valid values are ``exclusive``, ``inclusive``, and +``prioritized``. The default setting is ``exclusive`` and this setting +should work for most environments. + +.. note:: This option should be used with care, since whatever setting is + used will greatly alter behavior. It is therefore recommended that + whichever setting is chosen should be used `site-wide`_ within an + organization. + +- If set to ``exclusive``, all dependencies and their version + specifications must be satisfied in order for the command to + succeed, and only one version of each package is allowed. This is + the default option, and is the safest, though it may carry with it + significant performance ramifications. It turns dependency + resolution into an NP hard problem. This is normally not a problem + since the number of dependencies at most organizations (on the + order of hundreds) is relatively small, but it is something of which the + reader should be aware. + +- If set to ``inclusive``, all dependencies and their version specifications + must be satisfied in order for the command to succeed, but multiple versions + of each package are allowed to be part of the solution. To call for + similar behavior to ruby's gem or node's npm, for example, set + ``--conflict-strat`` to ``inclusive`` and set ``--resolve-strat`` + to ``fast``. This can be easily and cleanly specified done by using the + ``multi-version-mode`` `option pack`_. + +- If set to ``prioritized``, then the first time a package is required and + is found at a particular version, it will be considered to fulfill the + all other encountered requirements asking for that package. This is + intended to mimic the behavior of java's maven package manager. + + It means that, for example, if package ``a`` at version ``1`` + requires package ``b`` at version ``1`` and also package ``c`` at + version ``1``; and package ``c`` at version ``1`` requires package + ``b`` at version ``2``; then the packages ``a`` at version ``1``, + the package ``b`` at version ``1``, and the package ``c`` at + version ``1`` will be found. Despite the fact that ``c`` needed + ``b`` to be at version ``2``, it had already been found at version + ``1`` and that version was assumed to fulfill all requirements asking + for package ``b``. + + To mimic the behavior of maven, set ``--conflict-strat`` to + ``prioritized`` and ``--resolve-strat`` to ``fast``. This can be + easily and cleanly specified done by using the + ``firstfound-version-mode`` `option pack`_. + +.. _output-format: + +Specify Output Format +********************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-o FORMAT`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--output-format FORMAT`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:output-format "FORMAT"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.10.0; EDN introduced 1.11.0 | ++-----------------------------+---------------------------------------+ + +Specify an output format. May be ``plain``, ``edn`` or ``json``. This +output format only takes effect when the package resolution was +successful. + +The default output format is ``plain``. It is a simple text format +that was designed for ease of use within bash scripts while also +being somewhat pleasant to look at. + +Example output on a successful run when the format is set to ``plain``:: + + c==3.5.0 @ https://example.com/repo/c-3.5.0.zip + d==0.8.0 @ https://example.com/repo/d-0.8.0.zip + e==1.8.0 @ https://example.com/repo/e-1.8.0.zip + b==2.3.0 @ https://example.com/repo/b-2.3.0.zip + +In the above example out, each line takes the form:: + + == @ + +When the output format is JSON, the output would spit out a JSON +document containing lots of different keys and values representing +some of the internal state degasolv had when it resolved +the packages. Among those keys will be a key called "packages", and it will +look something like this:: + + { + "command": "degasolv", + "subcommand": "resolve-locations", + "options": { + "requirements": [ + "b" + ], + "resolve-strat": "thorough", + "index-strat": "priority", + "conflict-strat": "exclusive", + "search-directory": ".", + "package-system": "degasolv", + "output-format": "json", + "version-comparison": "maven", + "index-file": "index.dsrepo", + "repositories": [ + "./index.dsrepo" + ], + "search-strat": "breadth-first", + "alternatives": true, + "present-packages": [ + "x==0.9.0", + "e==1.8.0" + ], + "card-file": "./out.dscard" + }, + "result": "successful", + "packages": [ + { + "id": "d", + "version": "0.8.0", + "location": "https://example.com/repo/d-0.8.0.zip", + "requirements": [ + [ { - "name": "d", - "version": "0.8.0", - "location": "https://example.com/repo/d-0.8.0.zip" - }, + "status": "present", + "id": "e", + "spec": [ + [ + { + "relation": "greater-equal", + "version": "1.1.0" + }, + { + "relation": "less-than", + "version": "2.0.0" + } + ] + ] + } + ] + ] + }, + { + "id": "c", + "version": "3.5.0", + "location": "https://example.com/repo/c-3.5.0.zip", + "requirements": [] + }, + { + "id": "b", + "version": "2.3.0", + "location": "https://example.com/repo/b-2.3.0.zip", + "requirements": [ + [ { - "name": "e", - "version": "1.8.0", - "location:" "https://example.com/repo/e-1.8.0.zip" - }, + "status": "present", + "id": "c", + "spec": [ + [ + { + "relation": "greater-equal", + "version": "3.5.0" + } + ] + ] + } + ], + [ { - "name": "b", - "version": "2.3.0", - "location:" "https://example.com/repo/b-2.3.0.zip" - }, ... - ], ... + "status": "present", + "id": "d", + "spec": null + } + ] + ] + } + ] + } + +If the output format is EDN, the output will be similar, except it will use +the EDN format:: + + { + :command "degasolv", + :subcommand "resolve-locations", + :options { + :requirements ("a<=1.0.0"), + :resolve-strat "thorough", + :index-strat "priority", + :conflict-strat "exclusive", + :search-directory ".", + :package-system "degasolv", + :output-format "edn", + :version-comparison "maven", + :index-file "index.dsrepo", + :repositories ( + "./index.dsrepo" + ), + :search-strat "breadth-first", + :alternatives true, + :card-file "./out.dscard" + }, + :result :successful, + :packages #{ + #degasolv.resolver/PackageInfo { + :id "b", + :version "2.3.0", + :location "https://example.com/repo/b-2.3.0.zip", + :requirements [] + }, + #degasolv.resolver/PackageInfo { + :id "a", + :version "1.0.0", + :location "https://example.com/repo/a-1.0.0.zip", + :requirements [ + [ + #degasolv.resolver/Requirement { + :status :present, + :id "b", + :spec nil + } + ] + ] + } } + } + +The output, if the format is not ``plain``, will have the following +top-level keys in it: + + - ``command``: This is will be ``degasolv``. + - ``subcommand``: This will reflect what subcommand was specified. + In the current version, this will always be ``resolve-locations``. + - ``options``: This shows what options were given when degasolv was + run. Its contents should roughly reflect the output of ``display-config`` + when run with similar options. + - ``result``: This displays whether the run was successful or + not. Since unsuccessful runs result in a printed error and not + outputted JSON, this will be ``successful``. At present, to + determine whether a run was successful, use the return code of + degasolv rather than this key. + - ``packages``: This displays the list of packages and, if present, + any additional `meta-data`_ associated with the package. .. _present package: - -- ``-p PKG``, ``--present-package PKG``, ``:present-packages ["PKG1", ...]``: - Specify a "hard present package". Specify ``PKG`` as - ``==``, as in this example: ``garfield==1.0``. - - Doing this tells degasolv that a package "already exists" at a particular - version in the system or build, whatever that means. This means that when - degasolv encounters a requirement for this package, it will assume the - package is already found and it will mark the dependency as resolved. On the - other hand, degasolv will not try to change or update the found package. If - the version of the present package conflicts with requirements encountered, - resolution of those requirements may fail. - - This is another one of those options that is provided and, if needed, is - meant to benefit the user; however, judicious use is recommended. If you - don't know what you're doing, you probably don't want to use this option. - - For example, if this option is used to tell degasolv that, as part of a - build, some packages have already been downloaded, degasolv will not - recommend that those packages be upgraded. This is the "hard" in "hard - present package": If the user specifies via ``--present-package`` that - a package is already found and usable, degasolv won't try to find a new - version for it; it assumes "you know what you're doing" and that the - package(s) in question are not to be touched. - -- ``-r REQ``, ``--requirement REQ``, ``:requirements ["REQ1", ...]``: - **Required**. Resolve this requirement together with all other requirements - given. May be specified one ore more times as a command line option, or once - as a list of strings in a configuration file. See - :ref:`Specifying a requirement` for more information. - - The last requirement specified will be the first to be resolved. If the - requirements are retrieved from the config file, they are resolved in order - from first to last in the list. If requirements are specified both on the - command line and in the configuration file, the requirements in the - configuration file are ignored. +.. _present-package: + +Specify that a Package is Already Present +***************************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-p PKG`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--present-package PKG`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:present-packages ["PKG1", ...]`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.4.0 | ++-----------------------------+---------------------------------------+ + +Specify a "hard present package". Specify ``PKG`` as ``==``, +as in this example: ``garfield==1.0``. + +Doing this tells degasolv that a package "already exists" at a +particular version in the system or build, whatever that means. This +means that when degasolv encounters a requirement for this package, it +will assume the package is already found and it will mark the +dependency as resolved. On the other hand, degasolv will not try to +change or update the found package. If the version of the present +package conflicts with requirements encountered, resolution of those +requirements may fail. + +This is another one of those options that is provided and, if needed, +is meant to benefit the user; however, judicious use is +recommended. If you don't know what you're doing, you probably don't +want to use this option. + +For example, if this option is used to tell degasolv that, as part of +a build, some packages have already been downloaded, degasolv will not +recommend that those packages be upgraded. This is the "hard" in "hard +present package": If the user specifies via ``--present-package`` that +a package is already found and usable, degasolv won't try to find a +new version for it; it assumes "you know what you're doing" and that +the package(s) in question are not to be touched. + +Specify a Requirement +********************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-r REQ`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--requirement REQ`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:requirements ["REQ1", ...]`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +**Required**. Resolve this requirement together with all other +requirements given. May be specified one ore more times as a command +line option, or once as a list of strings in a configuration file. See +:ref:`Specifying a requirement` for more information. + +The last requirement specified will be the first to be resolved. If +the requirements are retrieved from the config file, they are resolved +in order from first to last in the list. If requirements are +specified both on the command line and in the configuration file, the +requirements in the configuration file are ignored. .. _repository option: .. _specify repositories: -- ``-R INDEX``, ``--repository INDEX``, ``:repositories ["INDEX1", ...]``: - **Required**. Search the repository index given by INDEX for packages when - resolving the given requirements. - - When the index strategy is ``priority`` The last repository index specified - will be the first to be consulted. If the repository indices are retrieved - from the config file, they are consulted in order from first to last in the - list. If indices are specified both on the command line and in the - configuration file, the indices in the configuration file are ignored. See - `index strategy`_ for more information. - - ``INDEX`` may be a URL or a filepath pointing to a `*.dsrepo` file. For - example, index might be `http://example.com/repo/index.dsrepo`. Both HTTP and - HTTPS URLs are supported. If ``INDEX`` is ``-`` (the hyphen character), - degasolv will read standard input instead of any specific file or URL. Possible - use cases for this include downloading the index repository first via some - other tool (such as `cURL`_). One reason users might do this is if - authentication is required to download the index, as in this example:: - - curl --user username:password https://example.com/degasolv/index.dsrepo | \ - degasolv resolve-locations -R - "req" +Specify a Repository to Search +****************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-R INDEX`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--repository INDEX`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:repositories ["INDEX1", ...]`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +**Required**. Search the repository index given by INDEX for packages +when resolving the given requirements. + +When the index strategy is ``priority`` The last repository index +specified will be the first to be consulted. If the repository indices +are retrieved from the config file, they are consulted in order from +first to last in the list. If indices are specified both on the +command line and in the configuration file, the indices in the +configuration file are ignored. See `index strategy`_ for more +information. + +``INDEX`` may be a URL or a filepath pointing to a `*.dsrepo` +file. For example, index might be +`http://example.com/repo/index.dsrepo`. Both HTTP and HTTPS URLs are +supported. As of version 1.1.0, If ``INDEX`` is ``-`` (the hyphen character), degasolv will +read standard input instead of any specific file or URL. Possible use +cases for this include downloading the index repository first via some +other tool (such as `cURL`_). One reason users might do this is if +authentication is required to download the index, as in this example:: + + curl --user username:password https://example.com/degasolv/index.dsrepo | \ + degasolv resolve-locations -R - "req" .. _cURL: https://curl.haxx.se/ -- ``-s STRAT``, ``--resolve-strat STRAT``, ``:resolve-strat "STRAT"``: This - option determines which versions of a given package id are considered when - resolving the given requirements. If set to ``fast``, only the first - available version matching the first set of requirements on a particular - package id is consulted, and it is hoped that this version will match all - subsequent requirements constraining the versions of that id. If set to - ``thorough``, all available versions matching the requirements will be - considered. The default setting is ``thorough`` and this setting - should work for most environments. - - .. note:: This option should be used with care, since whatever setting is - used will greatly alter behavior. It is therefore recommended that - whichever setting is chosen should be used `site-wide`_ within an - organization. +Specify a Resolution Strategy +***************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-s STRAT`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--resolve-strat STRAT`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:resolve-strat "STRAT"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +This option determines which versions of a given package id are +considered when resolving the given requirements. If set to ``fast``, +only the first available version matching the first set of +requirements on a particular package id is consulted, and it is hoped +that this version will match all subsequent requirements constraining +the versions of that id. If set to ``thorough``, all available +versions matching the requirements will be considered. The default +setting is ``thorough`` and this setting should work for most +environments. + +.. note:: This option should be used with care, since whatever setting + is used will greatly alter behavior. It is therefore recommended + that whichever setting is chosen should be used `site-wide`_ within + an organization. .. _index strategy: -- ``-S STRAT``, ``--index-strat STRAT``, ``:index-strat "STRAT"``: Repositories - are queried by package id in order to discover what packages are available to - fulfill the given requirements. This option determines how multiple - repository indexes are queried if there are more than one. If set to - ``priority``, the first repository that answers with a non-empty result is - used, if any. Note that this is true even if the versions don't match what is - required. - - For example, if ```` contains a package ``a`` at version ``1.8``, - and ```` contains a package ``a`` at version ``1.9``, then the - following command wil fail:: - - java -jar ./degasolv--standalone.jar -R -R \ - -r "a==1.9" - - While, on the other hand, this command will succeed:: +Specify an Index Strategy +************************* - java -jar ./degasolv--standalone.jar -R -R \ - -r "a==1.9" ++-----------------------------+---------------------------------------+ +| Short option | ``-S STRAT`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--index-strat STRAT`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:index-strat "STRAT"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ - By contrast, if ``--index-strat`` is given the STRAT of ``global``, - all versions from all repositories answering to a particular package - id will be considered. So, both of the following commands would - succeed, under the scenario presented above:: - - java -jar ./degasolv--standalone.jar -S global \ - -R -R -r "a==1.9" - - java -jar ./degasolv--standalone.jar -S global \ - -R -R -r "a==1.9" - - The default setting is ``priority`` and this setting should work for most - environments. - - .. note:: This option should be used with care, since whatever setting is - used will greatly alter behavior. It is therefore recommended that - whichever setting is chosen should be used `site-wide`_ within an - organization. - -.. _package system: +Repositories are queried by package id in order to discover what +packages are available to fulfill the given requirements. This option +determines how multiple repository indexes are queried if there are +more than one. If set to ``priority``, the first repository that +answers with a non-empty result is used, if any. Note that this is +true even if the versions don't match what is required. -- ``-t SYS``, ``--package-system SYS``, ``:package-system "SYS"``: - **Experimental**. Specify package system to use. By default, this value - is ``degasolv``. Using this option allows the user to run degasolv's - resolver engine on respositories from other package manager systems. Though - option was mainly implemented for profiling and debugging purposes, it is - envisioned that this option will expand to include many package manager - repositories. This will allow users to use degasolv to resolve packages - from well-known sources, in a reliable and useful manner. +For example, if ```` contains a package ``a`` at version +``1.8``, and ```` contains a package ``a`` at version ``1.9``, +then the following command wil fail:: - Other available values are: + java -jar ./degasolv--standalone.jar -R -R \ + -r "a==1.9" - - ``apt``: resolve using the APT debian package manager. When using this - method, `specify repositories`_ using the format:: +While, on the other hand, this command will succeed:: - {binary-amd64|binary-i386} + java -jar ./degasolv--standalone.jar -R -R \ + -r "a==1.9" - Or, in the case of naive apt repositories:: +By contrast, if ``--index-strat`` is given the STRAT of ``global``, +all versions from all repositories answering to a particular package +id will be considered. So, both of the following commands would +succeed, under the scenario presented above:: - {binary-amd64|binary-i386} + java -jar ./degasolv--standalone.jar -S global \ + -R -R -r "a==1.9" - For example, I might use the repository option like this:: + java -jar ./degasolv--standalone.jar -S global \ + -R -R -r "a==1.9" - java -jar degasolv--standalone.jar resolve-locations \ - -R "binary-amd64 https://example.com/ubuntu/ /" - -t "apt" \ - --requirement "ubuntu-desktop" +The default setting is ``priority`` and this setting should work for +most environments. - Or this:: +.. note:: This option should be used with care, since whatever setting + is used will greatly alter behavior. It is therefore recommended + that whichever setting is chosen should be used `site-wide`_ within + an organization. - java -jar degasolv--standalone.jar resolve-locations \ - -R "binary-amd64 https://example.com/ubuntu/ yakkety main" \ - -R "binary-i386 https://example.com/ubuntu/ yakkety main" \ - -t "apt" \ - --requirement "ubuntu-desktop" - - .. note:: Degasolv does not currently support APT dependencies between - machine architectures, as in ``python:i386``. Also, every degasolv - repo is currently architecture-specific; each repo has an associated - architecture, even if that architecture is ``any``. - - -- ``-V CMP``, ``--version-comparison CMP``, ``:version-comparison "CMP"``: - Use the specified version comparison algorithm when resolving - dependencies. - - This option allows the operator to change what version - comparison algorithm is used. By default, the algorithm is - "maven". May be "debian", "maven", "naive", "python" (PEP 440), - "rpm", "rubygem", or "semver" (2.0.0). Version comparison algorithms - are taken from the Serovers library. Descriptions for these - algorithms can be found in the `Serovers docs`_. - - .. _Serovers docs: http://djhaskin987.gitlab.io/serovers/serovers.core.html - - .. caution:: This is one of those options that should not be used - unless the operator has a good reason, but it is - available and usable if needed. - - .. note:: This option should be used with care, since whatever setting - is used will greatly alter behavior. Similar options are availabe - for the ``generate-repo-index`` subcommand and the ``query-repo`` - subcommand. They should all agree when used within the same - site. It is therefore recommended that whichever setting is - chosen should be used `site-wide`_ within an organization. - -.. _query-repo-options: +.. _package system: +.. _package-system: + +Specify a Package System (Experimental) +*************************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-t SYS`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--package-system SYS`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:package-system "SYS"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.4.0 | ++-----------------------------+---------------------------------------+ + +**Experimental**. Specify package system to use. By default, this +value is ``degasolv``. Using this option allows the user to run +degasolv's resolver engine on respositories from other package manager +systems. Though option was mainly implemented for profiling and +debugging purposes, it is envisioned that this option will expand to +include many package manager repositories. This will allow users to +use degasolv to resolve packages from well-known sources, in a +reliable and useful manner. + +Other available values are: + + - ``apt``: resolve using the APT debian package manager. When using + this method, `specify repositories`_ using the format:: + + {binary-amd64|binary-i386} + + Or, in the case of naive apt repositories:: + + {binary-amd64|binary-i386} + + For example, I might use the repository option like this:: + + java -jar degasolv--standalone.jar resolve-locations \ + -R "binary-amd64 https://example.com/ubuntu/ /" + -t "apt" \ + --requirement "ubuntu-desktop" + + Or this:: + + java -jar degasolv--standalone.jar resolve-locations \ + -R "binary-amd64 https://example.com/ubuntu/ yakkety main" \ + -R "binary-i386 https://example.com/ubuntu/ yakkety main" \ + -t "apt" \ + --requirement "ubuntu-desktop" + + .. note:: Degasolv does not currently support APT dependencies + between machine architectures, as in ``python:i386``. Also, + every degasolv repo is currently architecture-specific; each + repo has an associated architecture, even if that architecture + is ``any``. + +.. _version-comparison-resolve: + +Specify the Version Comparison Algorithm +**************************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-V CMP`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--version-comparison CMP`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:version-comparison "CMP"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.8.0 | ++-----------------------------+---------------------------------------+ + +Use the specified version comparison algorithm when resolving +dependencies. + +This option allows the operator to change what version comparison +algorithm is used. By default, the algorithm is "maven". May be +"debian", "maven", "naive", "python" (PEP 440), "rpm", "rubygem", or +"semver" (2.0.0). Version comparison algorithms are taken from the +Serovers library. Descriptions for these algorithms can be found in +the `Serovers docs`_. + +.. _Serovers docs: http://djhaskin987.gitlab.io/serovers/serovers.core.html + +.. caution:: This is one of those options that should not be used + unless the operator has a good reason, but it is + available and usable if needed. + +.. note:: This option should be used with care, since whatever setting + is used will greatly alter behavior. Similar options are availabe + for the ``generate-repo-index`` subcommand and the ``query-repo`` + subcommand. They should all agree when used within the same + site. It is therefore recommended that whichever setting is + chosen should be used `site-wide`_ within an organization. + +.. _query-repo: CLI for ``query-repo`` ---------------------- +Usage Page for ``query-repo`` ++++++++++++++++++++++++++++++ + Running ``java -jar degasolv--standalone.jar query-repo -h`` returns a page that looks something like this:: @@ -824,66 +1402,157 @@ page that looks something like this:: - `-R`, `--repository`, or the config file key `:repositories`. - `-q`, `--query`, or the config file key `:query`. -This subcommand queries a repository index or indices for packages. This comand -is intended to be useful or debugging dependency problems. - -Explanation of options: - -- ``-q QUERY``, ``--query QUERY``: **Required**. Query repository index or indices for a - package. Syntax is exactly the same as requirements except that only one - alternative may be specified (that is, using the ``|`` character or - specifying multiple package ids), and the requirement must specify - a present package (no ``!`` character may be used either). - See `Specifying a requirement`_ for more information. - - Examples of valid queries: - - - ``"pkg"`` - - ``"pkg!=3.0.0"`` - - Examples if invalid queries: - - - ``"a|b"`` - - ``"!a"`` - -- ``-R INDEX``, ``--repository INDEX``, ``:repositories ["INDEX1", ...]``: **Required**. - This option works exactly the same as the `repository option`_ for the - ``resolve-locations`` command, except that instead of using the repositories - for resolving requirements, it uses them for simple index queries. See that - option's explanation for more information. - -- ``-S STRAT``, ``--index-strat STRAT``, ``:index-strat "STRAT"``: - This option works exactly the same as the `index strategy`_ option for the - ``resolve-locations`` command, except that it is used for simple index - queries. See that option's explanation for more information. - -- ``-t SYS``, ``--package-system SYS``, ``:package-system "SYS"``: - This option works exactly the same as the `package system`_ option for the - ``resolve-locations`` command, except that it is used for simple index - queries. See that option's explanation for more information. - -- ``-V CMP``, ``--version-comparison CMP``, ``:version-comparison "CMP"``: - Use the specified version comparison algorithm when querying the repository. - - This option allows the operator to change what version - comparison algorithm is used. By default, the algorithm is - "maven". May be "debian", "maven", "naive", "python" (PEP 440), - "rpm", "rubygem", or "semver" (2.0.0). Version comparison algorithms - are taken from the Serovers library. Descriptions for these - algorithms can be found in the `Serovers docs`_. - - .. _Serovers docs: http://djhaskin987.gitlab.io/serovers/serovers.core.html - - .. caution:: This is one of those options that should not be used - unless the operator has a good reason, but it is - available and usable if needed. - - .. note:: This option should be used with care, since whatever setting - is used will greatly alter behavior. Similar options are availabe - for the ``generate-repo-index`` subcommand and the ``resolve-locations`` - subcommand. They should all agree when used within the same - site. It is therefore recommended that whichever setting is - chosen should be used `site-wide`_ within an organization. +Overview of ``query-repo`` +++++++++++++++++++++++++++ + +*This subcommand introduced as of version 1.0.2*. + +This subcommand queries a repository index or indices for +packages. This comand is intended to be useful or debugging dependency +problems. + +Explanation of Options for ``query-repo`` ++++++++++++++++++++++++++++++++++++++++++ + +.. _output-format-query-repo: + +Specify Output Format +********************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-o FORMAT`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--output-format FORMAT`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:output-format "FORMAT"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.11.0 | ++-----------------------------+---------------------------------------+ + +Specify an output format. May be ``plain``, ``edn`` or ``json``. By +default the output format is ``plain``. This output format only takes +effect when the query returns a non-empty set of results. This is +exactly like the `output-format`_ option for `resolve-locations`_, +except that the ``subcommand`` field is new returned as +``query-repo``. + +Specify Query +************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-q QUERY`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--query QUERY`` | ++-----------------------------+---------------------------------------+ +| Config file key | N/A | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +**Required**. Query repository index or indices for a package. Syntax +is exactly the same as requirements except that only one alternative +may be specified (that is, using the ``|`` character or specifying +multiple package ids), and the requirement must specify a present +package (no ``!`` character may be used either). See `Specifying a +requirement`_ for more information. + +Examples of valid queries: + + - ``"pkg"`` + - ``"pkg!=3.0.0"`` + +Examples if invalid queries: + + - ``"a|b"`` + - ``"!a"`` + +Specify a Repository to Search +****************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-R INDEX`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--repository INDEX`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:repositories ["INDEX1", ...]`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +**Required** This option works exactly the same as the `repository +option`_ for the ``resolve-locations`` command, except that instead of +using the repositories for resolving requirements, it uses them for +simple index queries. See that option's explanation for more +information. + +Specify an Index Strategy +************************* + ++-----------------------------+---------------------------------------+ +| Short option | ``-S STRAT`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--index-strat STRAT`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:index-strat "STRAT"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.0.2 | ++-----------------------------+---------------------------------------+ + +This option works exactly the same as the `index strategy`_ option for the +``resolve-locations`` command, except that it is used for simple index +queries. See that option's explanation for more information. + +Specify a Package System (Experimental) +*************************************** + ++--------------+---------------------------+-----------------------------------+ +| Short option | Long option | Config File Key | ++--------------+---------------------------+-----------------------------------+ +| ``-t SYS`` | ``--package-system SYS`` | ``:package-system "SYS"`` | ++--------------+---------------------------+-----------------------------------+ + +This option works exactly the same as the `package system`_ option for +the ``resolve-locations`` command, except that it is used for simple +index queries. See that option's explanation for more information. + +.. _version-comparison-query: + +Specify the Version Comparison Algorithm +**************************************** + ++-----------------------------+---------------------------------------+ +| Short option | ``-V CMP`` | ++-----------------------------+---------------------------------------+ +| Long option | ``--version-comparison CMP`` | ++-----------------------------+---------------------------------------+ +| Config file key | ``:version-comparison "CMP"`` | ++-----------------------------+---------------------------------------+ +| Version introduced | 1.8.0 | ++-----------------------------+---------------------------------------+ + +Use the specified version comparison algorithm when querying the +repository. + +This option allows the operator to change what version comparison +algorithm is used. By default, the algorithm is "maven". May be +"debian", "maven", "naive", "python" (PEP 440), "rpm", "rubygem", or +"semver" (2.0.0). Version comparison algorithms are taken from the +Serovers library. Descriptions for these algorithms can be found in +the `Serovers docs`_. + +.. _Serovers docs: http://djhaskin987.gitlab.io/serovers/serovers.core.html + +.. caution:: This is one of those options that should not be used + unless the operator has a good reason, but it is available + and usable if needed. + +.. note:: This option should be used with care, since whatever setting + is used will greatly alter behavior. Similar options are availabe + for the ``generate-repo-index`` subcommand and the + ``resolve-locations`` subcommand. They should all agree when used + within the same site. It is therefore recommended that whichever + setting is chosen should be used `site-wide`_ within an + organization. .. _Specifying a requirement: @@ -893,10 +1562,13 @@ Specifying a requirement .. _alternative: .. _alternatives: -A requirement is given as a string of text. A -requirement consists of one or more *alternatives*. Any of the alternatives -will satisfy the requirement. Alternatives are specified by a bar character -(``|``), like this:: +*Unless otherwise noted, features in this section were introduced as +of version 1.0.2 or earlier*. + +A requirement is given as a string of text. A requirement consists of +one or more *alternatives*. Any of the alternatives will satisfy the +requirement. Alternatives are specified by a bar character (``|``), +like this:: "||" @@ -946,12 +1618,14 @@ equal to", and "newer than", respectively, using whatever version comparison algorithm was specified using the CLI, or using the maven version comparison algorithm by default. -In addition to the above operators, two other version spec operators are +In addition to the above operators, three other version spec operators are provided: - * The "matches" operator: ``<>``. This operator is given in a version spec - as ``<>REGEX``. The version of any package found during the resolution - process must match the given `java regular expression`_. Examples: + * The "matches" operator: ``<>``. *Introduced of version + 1.8.0*. This operator is given in a version spec as + ``<>REGEX``. The version of any package found during the + resolution process must match the given `java regular + expression`_. Examples: * The expression ``<>\d+\.\d+\.\d+`` matches any version containing a three-part version in it. @@ -962,7 +1636,8 @@ provided: .. _java regular expression: http://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html - * The "in-range" operator: ``=>``. This operator is given in a version spec + * The "in-range" operator: ``=>``. *Introduced as of version + 1.8.0*. This operator is given in a version spec as ``=>RANGE``. The version of any package found during the resolution process must be in the given version range. Examples: @@ -988,9 +1663,10 @@ provided: version string as computed in the previous step, are considered for dependency resolution. - * The "pessimistic greater-than" operator: ``><``. This operator is given in - a version spec as ``><``. *Introduced as of + version 1.9.0*. This operator is given in a version spec as + ``><3.2.1`` matches the versions ``3.2.1``, ``3.4.3`` diff --git a/docs/conf.py b/docs/conf.py index ff451dc..6fa8162 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -58,9 +58,9 @@ # built documents. # # The short X.Y version. -version = '1.10' +version = '1.11' # The full version, including alpha/beta/rc tags. -release = '1.10.0' +release = '1.11.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/index.rst b/docs/index.rst index ae888d0..0e37176 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,6 +8,7 @@ Degasolv Why Degasolv? Get Degasolv Quickstart + Site Set-Up Guide A Longer Example Command Reference Changelog diff --git a/docs/set-up-guide.rst b/docs/set-up-guide.rst new file mode 100644 index 0000000..cec59e8 --- /dev/null +++ b/docs/set-up-guide.rst @@ -0,0 +1,12 @@ +# Site Set-Up Guide + +This article details how to set up a site to use degasolv. + +Degasolv is a customizable dependency management solution, and is +optimized for use at a *site*, such as within a company or other large +organization. Additionally, there will soon be made "public" sites available, +or in other words, degasolv repositories available to the public. + +## Site Configuration file + +## Booban diff --git a/project.clj b/project.clj index dea6b01..0d85be2 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject degasolv/degasolv "1.10.0" +(defproject degasolv/degasolv "1.11.0" :description "Dependency tracker with an eye toward building and shipping software." :url "http://github.com/djhaskin987/degasolv" :license {:name "Eclipse Public License" diff --git a/sample.json b/sample.json new file mode 100644 index 0000000..9852d4a --- /dev/null +++ b/sample.json @@ -0,0 +1,89 @@ +{ + "command": "degasolv", + "subcommand": "resolve-locations", + "options": { + "requirements": [ + "b" + ], + "resolve-strat": "thorough", + "index-strat": "priority", + "conflict-strat": "exclusive", + "search-directory": ".", + "package-system": "degasolv", + "output-format": "json", + "version-comparison": "maven", + "index-file": "index.dsrepo", + "repositories": [ + "./index.dsrepo" + ], + "search-strat": "breadth-first", + "alternatives": true, + "present-packages": [ + "x==0.9.0", + "e==1.8.0" + ], + "card-file": "./out.dscard" + }, + "result": "successful", + "packages": [ + { + "id": "d", + "version": "0.8.0", + "location": "https://example.com/repo/d-0.8.0.zip", + "requirements": [ + [ + { + "status": "present", + "id": "e", + "spec": [ + [ + { + "relation": "greater-equal", + "version": "1.1.0" + }, + { + "relation": "less-than", + "version": "2.0.0" + } + ] + ] + } + ] + ] + }, + { + "id": "c", + "version": "3.5.0", + "location": "https://example.com/repo/c-3.5.0.zip", + "requirements": [] + }, + { + "id": "b", + "version": "2.3.0", + "location": "https://example.com/repo/b-2.3.0.zip", + "requirements": [ + [ + { + "status": "present", + "id": "c", + "spec": [ + [ + { + "relation": "greater-equal", + "version": "3.5.0" + } + ] + ] + } + ], + [ + { + "status": "present", + "id": "d", + "spec": null + } + ] + ] + } + ] +} diff --git a/src/degasolv/cli.clj b/src/degasolv/cli.clj index 458e417..92d90c6 100644 --- a/src/degasolv/cli.clj +++ b/src/degasolv/cli.clj @@ -179,7 +179,9 @@ (println (case output-format "json" - (json/write-str result-info) + (json/write-str result-info :escape-slash false) + "edn" + (pr-str result-info) "plain" (string/join \newline @@ -200,25 +202,28 @@ (map r/explain-problem (:problems result-info)))))))) (defn- generate-card! - [{:keys [id version location requirements card-file]} + [{:keys [id version location requirements card-file meta]} arguments] (default-spit card-file - (->PackageInfo + (into + (->PackageInfo id version location (into [] (map #(string-to-requirement %) - requirements))))) + requirements))) + (dissoc meta :id :version :location :requirements)))) (defn query-repo! [options arguments] - (let [{:keys [repositories - query - index-strat + (let [{:keys [index-strat + output-format package-system + repositories + query version-comparison]} options version-comparator @@ -235,15 +240,31 @@ version-comparator) results (filter #(spec-call spec %) - (aggregate-repo id))] + (aggregate-repo id)) + result-info + { + :command "degasolv" + :subcommand "resolve-locations" + :options options + :packages results + }] (if (empty? results) (exit 2 "No results returned from query") (println - (string/join - \newline - (map - explain-package - results)))))) + (case output-format + "json" + (json/write-str result-info :escape-slash false) + "edn" + (pr-str result-info) + "plain" + (string/join + \newline + (map + explain-package + results)) + (throw (ex-info "This shouldn't happen" + {:subcommand "query-repo" + :output-format output-format}))))))) (def subcommand-option-defaults { @@ -289,6 +310,15 @@ :validate [#(not (empty? %)) "Location must be a non-empty string."] :required true] + ["-m" "--meta K=V" + "Add additional metadata" + :validate [#(re-matches #"^[^=]+=[^=].*$" %) + "Metadata must be presented as = pair."] + :id :meta + :assoc-fn + (fn [m k v] + (let [[_ rk rv] (re-find #"^([^=]+)=([^=].*)$" v)] + (update-in m [k] #(assoc % (keyword rk) rv))))] ["-r" "--requirement REQ" "List requirement **" :validate [#(re-matches r/str-requirement-regex %) @@ -350,12 +380,13 @@ (= "inclusive" %) (= "prioritized" %)) "Conflict strategy must either be 'exclusive', 'inclusive', or 'prioritized'."]] - ["-o" "--output-format FORMAT" "May be 'plain' or 'json'" + ["-o" "--output-format FORMAT" "May be 'plain', 'edn' or 'json'" :default nil :default-desc (str (:output-format subcommand-option-defaults)) :validate [#(or (= "plain" %) - (= "json" %)) - "Output format may be either 'plain' or 'json'"]] + (= "json" %) + (= "edn" %)) + "Output format may be either be 'plain', 'edn' or 'json'"]] ["-p" "--present-package PKG" "Hard present package. **" :id :present-packages @@ -409,6 +440,13 @@ :required-arguments {:repositories ["-R" "--repository"] :query ["-q" "--query"]} :cli [ + ["-o" "--output-format FORMAT" "May be 'plain', 'edn' or 'json'" + :default nil + :default-desc (str (:output-format subcommand-option-defaults)) + :validate [#(or (= "plain" %) + (= "json" %) + (= "edn" %)) + "Output format may be either be 'plain', 'edn' or 'json'"]] ["-q" "--query QUERY" "Display packages matching query string." :validate [#(and (re-matches r/str-requirement-regex %) @@ -586,7 +624,6 @@ configs))))) (hash-map)))) - (defn -main [& args] (let [{:keys [options arguments errors summary]} (parse-opts args (concat diff --git a/src/degasolv/pkgsys/apt.clj b/src/degasolv/pkgsys/apt.clj index 894393d..ae743a4 100644 --- a/src/degasolv/pkgsys/apt.clj +++ b/src/degasolv/pkgsys/apt.clj @@ -31,13 +31,6 @@ #(string-to-requirement %) it)))) -(defn start-pkg-segment? - [lines] - (t/truthy? - (re-matches - #"^Package:.*$" - (first lines)))) - (defn lines-to-map [lines] (t/it-> lines @@ -85,24 +78,33 @@ (defn expand-provides [pkg] - (let [new-package - (->PackageInfo + (let [restof-package + (dissoc + pkg + :version + :location + :depends) + new-package + (into + (->PackageInfo (string/replace - (:package pkg) - #"[:]any$" - "") + (:package pkg) + #"[:]any$" + "") (:version pkg) (:location pkg) - (:depends pkg))] + (:depends pkg)) + restof-package)] (if (:provides pkg) (t/it-> (deb-to-degasolv-provides (:provides pkg)) (map - #(->PackageInfo - % - "0" - (:location pkg) - (:depends pkg)) + #(into (->PackageInfo + % + "0" + (:location pkg) + (:depends pkg)) + restof-package) it) (conj it @@ -121,15 +123,14 @@ pkg each (string/split-lines each) (filter - #(re-matches #"^(Provides|Version|Package|Depends|Filename):.*" %) + #(re-matches #"^(\p{Alnum}+):.*" %) each) (lines-to-map each) (convert-pkg-requirements each) (add-pkg-location each url) - (expand-provides each))) + (expand-provides (persistent! each)))) it) (apply concat it) - ;; (fn query [id] ;; (sort-by ;; :version @@ -138,7 +139,6 @@ ;; #(= id (:id %)) ;; it))) ;; (memoize it))) - (reduce (fn conjv [c v] diff --git a/test/degasolv/pkgsys/apt_test.clj b/test/degasolv/pkgsys/apt_test.clj index 555ac3d..4615799 100644 --- a/test/degasolv/pkgsys/apt_test.clj +++ b/test/degasolv/pkgsys/apt_test.clj @@ -116,31 +116,55 @@ Description-md5: 1c71821ee46c31ca86e8242f7517c26e Bugs: https://bugs.launchpad.net/ubuntu/+filebug Origin: Ubuntu Supported: 9m")] - (is (= (repo "foo") - [(->PackageInfo - "foo" - "0.1.11-0ubuntu3" - "http://us.archive.ubuntu.com/ubuntu/pool/main/f/foo/foo_0.1.11-0ubuntu3_amd64.deb" - [[(->Requirement - :present - "liba11y-profile-manager-0.1-0" - [[(->VersionPredicate - :greater-equal - "0.1.11")]])] - [(->Requirement - :present - "libc6" - [[(->VersionPredicate - :greater-equal - "2.4")]])] - [(->Requirement - :present - "libglib2.0-0" - [[(->VersionPredicate - :greater-equal - "2.26.0")]])]])])) - (is (= (repo "a11y-profile-manager") - [(->PackageInfo + (is (= + (repo "foo") + [(into + (->PackageInfo + "foo" + "0.1.11-0ubuntu3" + "http://us.archive.ubuntu.com/ubuntu/pool/main/f/foo/foo_0.1.11-0ubuntu3_amd64.deb" + [[(->Requirement + :present + "liba11y-profile-manager-0.1-0" + [[(->VersionPredicate + :greater-equal + "0.1.11")]])] + [(->Requirement + :present + "libc6" + [[(->VersionPredicate + :greater-equal + "2.4")]])] + [(->Requirement + :present + "libglib2.0-0" + [[(->VersionPredicate + :greater-equal + "2.26.0")]])]]) + {:maintainer "Luke Yelavich ", + :description + "Accessibility Profile Manager - Command-line utility", + :package "foo:any", + :architecture "amd64", + :task + "ubuntu-live, ubuntu-gnome-desktop, ubuntu-mate-live", + :supported "9m", + :homepage "https://launchpad.net/a11y-profile-manager", + :section "misc", + :bugs "https://bugs.launchpad.net/ubuntu/+filebug", + :size "6310", + :sha1 "3520ea78e489da35a7e71048dd5ff3fe6d99e13e", + :filename + "pool/main/f/foo/foo_0.1.11-0ubuntu3_amd64.deb", + :priority "optional", + :sha256 + "a14a3bf010d5e5f8a2b46ff94836808cca02ebb1610b9e36558d3a4d8a7296d9", + :origin "Ubuntu", + :md5sum "88048849b5897f17b987c0bfd8f1c899"})])) + (is (= + (repo "a11y-profile-manager") + [(into + (->PackageInfo "a11y-profile-manager" "0.1.11-0ubuntu3" "http://us.archive.ubuntu.com/ubuntu/pool/main/a/a11y-profile-manager/a11y-profile-manager_0.1.11-0ubuntu3_amd64.deb" @@ -161,10 +185,54 @@ Supported: 9m")] "libglib2.0-0" [[(->VersionPredicate :greater-equal - "2.26.0")]])]])])) + "2.26.0")]])]]) + {:maintainer "Luke Yelavich ", + :description + "Accessibility Profile Manager - Command-line utility", + :package "a11y-profile-manager", + :architecture "amd64", + :task + "ubuntu-live, ubuntu-gnome-desktop, ubuntu-mate-live", + :supported "9m", + :homepage "https://launchpad.net/a11y-profile-manager", + :section "misc", + :bugs "https://bugs.launchpad.net/ubuntu/+filebug", + :size "6310", + :sha1 "3520ea78e489da35a7e71048dd5ff3fe6d99e13e", + :filename + "pool/main/a/a11y-profile-manager/a11y-profile-manager_0.1.11-0ubuntu3_amd64.deb", + :priority "optional", + :sha256 + "a14a3bf010d5e5f8a2b46ff94836808cca02ebb1610b9e36558d3a4d8a7296d9", + :origin "Ubuntu", + :md5sum "88048849b5897f17b987c0bfd8f1c899"})])) (is (= (repo "a11y-profile-manager-doc") - [(->PackageInfo - "a11y-profile-manager-doc" - "0.1.11-0ubuntu3" - "http://us.archive.ubuntu.com/ubuntu/pool/main/a/a11y-profile-manager/a11y-profile-manager-doc_0.1.11-0ubuntu3_all.deb" - nil)]))))) + [(into + (->PackageInfo + "a11y-profile-manager-doc" + "0.1.11-0ubuntu3" + "http://us.archive.ubuntu.com/ubuntu/pool/main/a/a11y-profile-manager/a11y-profile-manager-doc_0.1.11-0ubuntu3_all.deb" + nil + ) + {:maintainer "Luke Yelavich ", + :description + "Accessibility Profile Manager - Documentation", + :package "a11y-profile-manager-doc", + :architecture "all", + :supported "9m", + :homepage "https://launchpad.net/a11y-profile-manager", + :section "doc", + :bugs "https://bugs.launchpad.net/ubuntu/+filebug", + :source "a11y-profile-manager", + :size "13362", + :sha1 "f14bf9a6cf95b7f0e22e03c9628ab8c394e32a1e", + :filename + "pool/main/a/a11y-profile-manager/a11y-profile-manager-doc_0.1.11-0ubuntu3_all.deb", + :priority "optional", + :sha256 + "9827eea0cdb6f142057dc5768a8980f91f21dbb1544c9860a77e75ff3dfc183c", + :origin "Ubuntu", + :recommends "devhelp", + :md5sum "d47968ecee4e0ef7b647b87022c9f6c7"} + ) + ]))))) diff --git a/test/resources/scripts/test-apt b/test/resources/scripts/test-apt index 712e28c..266a4aa 100755 --- a/test/resources/scripts/test-apt +++ b/test/resources/scripts/test-apt @@ -101,4 +101,5 @@ try_time java \ --package-system apt \ --present-package "libasound2==1.1.1" \ --present-package "libpng12-0==1.2.13-4" \ - --requirement "ubuntu-desktop" + --requirement "ubuntu-desktop" \ + --output-format "json" diff --git a/test/resources/scripts/test-meta b/test/resources/scripts/test-meta new file mode 100755 index 0000000..d92703d --- /dev/null +++ b/test/resources/scripts/test-meta @@ -0,0 +1,67 @@ +#!/bin/sh +export POSIXLY_CORRECT=1 +set -x +if [ ! -f './project.clj' -a ! -f './build.boot' ] +then + echo "This script must be run from the root of the project." +fi + +test_home=test/resources/data/meta +rm -rf ${test_home} +mkdir -p ${test_home} + +name=$(lein print :name | sed 's|"||g') +version=$(lein print :version | sed 's|"||g') + +java \ + -jar target/uberjar/${name}-${version}-standalone.jar \ + generate-card \ + --card-file ${test_home}/out.dscard \ + --id yer \ + --location yerloc \ + --requirement foo \ + --meta sha256sum=goodcodegottaloadagooddealofdata \ + --meta foo=bar \ + --version 1.2.3 + +cat ${test_home}/out.dscard | grep -q goodcode + +cat > ${test_home}/degasolv.edn <2.0" +then + exit 1 +fi + +java -jar ${root_path}/target/uberjar/${name}-${version}-standalone.jar \ + query-repo \ + -R ${PWD}/index.dsrepo \ + --output-format edn \ + --query "a" + +if java -jar ${root_path}/target/uberjar/${name}-${version}-standalone.jar \ + query-repo \ + -R ${PWD}/index.dsrepo \ + --output-format edn \ + --query "a>2.0" +then + exit 1 +fi + +java -jar ${root_path}/target/uberjar/${name}-${version}-standalone.jar \ + query-repo \ + -R ${PWD}/index.dsrepo \ + --query "a" + +if java -jar ${root_path}/target/uberjar/${name}-${version}-standalone.jar \ + query-repo \ + -R ${PWD}/index.dsrepo \ + --query "a>2.0" +then + exit 1 +fi