diff --git a/README.md b/README.md index 2f803fa..53a63fd 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ Installation 1. Check out pgenv into `~/.pgenv`. ``` sh - $ git clone https://github.com/theory/pgenv.git ~/.pgenv + git clone https://github.com/theory/pgenv.git ~/.pgenv ``` 2. Add `~/.pgenv/bin` and `~/.pgenv/pgsql/bin` to your `$PATH` for access to @@ -60,7 +60,7 @@ Installation PostgreSQL: ``` sh - $ echo 'export PATH="$HOME/.pgenv/bin:$HOME/.pgenv/pgsql/bin:$PATH"' >> ~/.bash_profile + echo 'export PATH="$HOME/.pgenv/bin:$HOME/.pgenv/pgsql/bin:$PATH"' >> ~/.bash_profile ``` **Ubuntu note**: Modify your `~/.profile` instead of `~/.bash_profile`. @@ -70,15 +70,15 @@ Installation 3. Restart your shell as a login shell so the path changes take effect. You can now begin using pgenv. - ~~~ sh - $ exec $SHELL -l - ~~~ + ``` sh + exec $SHELL -l + ``` 4. Build a version of PostgreSQL: - ~~~ sh - $ pgenv build 10.4 - ~~~ + ``` sh + pgenv build 10.4 + ``` ### Configuration @@ -107,57 +107,58 @@ Custom scripts are driven by a set of configuration variables as follows: finishes. The return value of the script does not affect the `pgenv` workflow. The script gets the version of PostgreSQL being installed as first argument. -- `PGENV_SCRIPT_POSTINITDB` is an executable script run as soon as the `use` -command ends the `initdb` phase, that happens only the `PGDATA` has not been -initialized (i.e., on *very first `use`*). -The return value of the script does not affect the `pgenv` workflow. -The script gets the current `PGDATA` path as first argument. - -- `PGENV_SCRIPT_POSTSTART` is an executable script executed each time -an instances is started, that is `start` is executed. -The return value of the script does not affect the `pgenv` workflow. -The script gets the current `PGDATA` path as first argument. - -- `PGENV_SCRIPT_PRESTOP` is an executable script executed before -an instance is stopped, that is brefore the `stop` command is executed. -The return value of the script does not affect the `pgenv` workflow, -and if the script generates errors they are ignored, so that the -cluster is going to be stopped anyway. -The script gets the current `PGDATA` path as first argument. +- `PGENV_SCRIPT_POSTINITDB` is an executable script run as soon as the `use` + command ends the `initdb` phase, that happens only the `PGDATA` has not been + initialized (i.e., on *very first `use`*). The return value of the script + does not affect the `pgenv` workflow. The script gets the current `PGDATA` + path as first argument. -- `PGENV_SCRIPT_POSTSTOP` is an executable script executed each time -an instance is stopped, that is the `stop` command is executed. -The return value of the script does not affect the `pgenv` workflow. -The script gets the current `PGDATA` path as first argument. +- `PGENV_SCRIPT_POSTSTART` is an executable script executed each time an + instances is started, that is `start` is executed. The return value of the + script does not affect the `pgenv` workflow. The script gets the current + `PGDATA` path as first argument. -- `PGENV_SCRIPT_POSTRESTART` is an executable script executed each time -an instance is restarted, that is the `restart` command is executed. -The return value of the script does not affect the `pgenv` workflow. -The script gets the current `PGDATA` path as first argument. +- `PGENV_SCRIPT_PRESTOP` is an executable script executed before an instance + is stopped, that is before the `stop` command is executed. The return value + of the script does not affect the `pgenv` workflow, and if the script + generates errors they are ignored, so that the cluster is going to be + stopped anyway. The script gets the current `PGDATA` path as first argument. +- `PGENV_SCRIPT_POSTSTOP` is an executable script executed each time an + instance is stopped, that is the `stop` command is executed. The return + value of the script does not affect the `pgenv` workflow. The script gets + the current `PGDATA` path as first argument. +- `PGENV_SCRIPT_POSTRESTART` is an executable script executed each time an + instance is restarted, that is the `restart` command is executed. The return + value of the script does not affect the `pgenv` workflow. The script gets + the current `PGDATA` path as first argument. -The above configuration variables can be set in the configuration file -or on the fly, for instance: - - $ export PGENV_SCRIPT_POSTSTART=/usr/local/bin/load_data.sh - $ pgenv start 12.0 +The above configuration variables can be set in the configuration file or on the +fly, for instance: +``` sh +export PGENV_SCRIPT_POSTSTART=/usr/local/bin/load_data.sh +pgenv start 12.0 +``` -It is worth noting that the start, restart and post script are not shared between similar events: for instance the `PGENV_SCRIPT_POSTSTOP` is not executed if the user issues a `restart` command (even if that implies somehow a cluster stop). +It is worth noting that the start, restart and post script are not shared +between similar events: for instance the `PGENV_SCRIPT_POSTSTOP` is not executed +if the user issues a `restart` command (even if that implies somehow a cluster +stop). -**Please note that running external scripts can result in damages and crashes in the `pgenv` workflow.** -In the future, more hooks to run scripts could be added. +**Please note that running external scripts can result in damages and crashes in +the `pgenv` workflow.** In the future, more hooks to run scripts could be added. ### Upgrading You can upgrade your installation to the cutting-edge version at any time with a simple `git pull`. -~~~ sh -$ cd ~/.pgenv -$ git pull -~~~ +``` sh +cd ~/.pgenv +git pull +``` ### Dependencies ------------ @@ -185,26 +186,22 @@ You can specify the version the command applies to by either entering the PostgreSQL version number or by specifying any of the special keywords: - `current` or `version` to indicate the currently selected PostgreSQL version; -- `earliest` to indicate the oldest installed version (exluding beta versions); -- `newest` to indicate the newest installed version (exluding beta versions). - -It is important to note that `earliest` and `latest` have nothing to do -with the time you installed PostgreSQL by means of `pgenv`: they refer only -to PostgreSQL *stable* versions. -To better clearify this, the following -snippet shows you which aliases point -to which versions in an example installation. - - - 9.6.19 <-- earliest (also earliest 9.6) - 9.6.20 <-- latest 9.6 - 12.2 <-- earliest 12 - 12.4 <-- latest 12 - 13beta2 - 13.0 <-- latest (also latest 13) - +- `earliest` to indicate the oldest installed version (excluding beta versions); +- `newest` to indicate the newest installed version (excluding beta versions). +It is important to note that `earliest` and `latest` have nothing to do with the +time you installed PostgreSQL by means of `pgenv`: they refer only to PostgreSQL +*stable* versions. To better clarify this, the following snippet shows you which +aliases point to which versions in an example installation. +``` +9.6.19 <-- earliest (also earliest 9.6) +9.6.20 <-- latest 9.6 +12.2 <-- earliest 12 +12.4 <-- latest 12 +13beta2 +13.0 <-- latest (also latest 13) +``` The subcommands are: @@ -213,25 +210,28 @@ The subcommands are: Sets the version of PostgreSQL to be used in all shells by symlinking its directory to `~/$PGENV_ROOT/pgsql` and starting it. Initializes the data directory if none exists. If another version is currently active, it will be -stopped before switching. If the specified version is already in use, the -`use` command won't stop it, but will initialize its data directory and starts -it if it's not already running. +stopped before switching. If the specified version is already in use, the `use` +command won't stop it, but will initialize its data directory and starts it if +it's not already running. - $ pgenv use 10.4 - waiting for server to shut down.... done - server stopped - waiting for server to start.... done - server started - PostgreSQL 10.4 started +``` +$ pgenv use 10.4 +waiting for server to shut down.... done +server stopped +waiting for server to start.... done +server started +PostgreSQL 10.4 started +``` +The `use` command supports the special keywords `earliest` and `latest` to +respectively indicate the oldest PostgreSQL version installed and the newest +one. It is also possible to indicate a major version to narrow the scope of the +special keywords. As an example: -The `use` command supports the special keywords `earliest` and `latest` -to respectively indicate the oldest PostgreSQL version installed and -the newest one. It is also possible to indicate a major version -to narrow the scope of the special keywords. As an example: +``` sh +pgenv use latest 10 +``` - $ pgenv use latest 10 - will select the most recent PostgreSQL version of the 10 series installed. ### pgenv versions @@ -241,57 +241,65 @@ the currently active version (if any). The first column reports versions available for use by `pgenv` and the second lists the subdirectory of `$PGENV_ROOT` in which the each version is installed: - $ pgenv versions - 10.4 pgsql-10.4 - 11beta3 pgsql-11beta3 - 9.5.13 pgsql-9.5.13 - * 9.6.9 pgsql-9.6.9 +``` +$ pgenv versions + 10.4 pgsql-10.4 + 11beta3 pgsql-11beta3 + 9.5.13 pgsql-9.5.13 + * 9.6.9 pgsql-9.6.9 +``` -In this example, versions `9.5.13`, `9.6.9`, `10.4`, and `11beta3` are -available for use, and the `*` indicates that `9.6.10` is the currently active -version. Each version is installed in a `pgsql-` subdirectory of -`$PGENV_ROOT`. +In this example, versions `9.5.13`, `9.6.9`, `10.4`, and `11beta3` are available +for use, and the `*` indicates that `9.6.10` is the currently active version. +Each version is installed in a `pgsql-` subdirectory of `$PGENV_ROOT`. ### pgenv current Displays the currently active PostgreSQL version. - $ pgenv current - 10.4 +``` +$ pgenv current +10.4 +``` Please note that `version` is a command synonym for version: - $ pgenv version - 10.4 +``` +$ pgenv version +10.4 +``` ### pgenv clear Clears the currently active version of PostgreSQL. If the current version is running, `clear` will stop it before clearing it. - $ pgenv clear - waiting for server to shut down.... done - server stopped - PostgreSQL stopped - PostgreSQL cleared +``` +$ pgenv clear +waiting for server to shut down.... done +server stopped +PostgreSQL stopped +PostgreSQL cleared +``` ### pgenv build Downloads and builds the specified version of PostgreSQL and its contrib -modules, as far back as version `8.0`. -It is possible to instrument the build process to patch the source tree, see -the section on patching later on. -If the version is already built, it will not be rebuilt; use -`clear` to remove an existing version before building it again. +modules, as far back as version `8.0`. It is possible to instrument the build +process to patch the source tree, see the section on patching later on. If the +version is already built, it will not be rebuilt; use `clear` to remove an +existing version before building it again. - $ pgenv build 10.3 - # [Curl, configure, and make output elided] - PostgreSQL 10.3 built +``` +$ pgenv build 10.3 +# [Curl, configure, and make output elided] +PostgreSQL 10.3 built +``` -The build phase can be customized via a configuration file, in the case -the system does not find a configuration file when the `build` is executed, -a warning is shown to the user to remind she can edit a configuration file -and start over the build process: +The build phase can be customized via a configuration file, in the case the +system does not find a configuration file when the `build` is executed, a +warning is shown to the user to remind she can edit a configuration file and +start over the build process: ```sh $ pgenv build 10.3 @@ -306,179 +314,205 @@ adjust 'configure' and 'make' options and flags and run again Within the configuration file it is possible to instrument the build phase from the configuration to the actual build. For instance, in order to build with -PL/Perl, it is possible to configure the variable `PGENV_CONFIGURE_OPTS` adding -`--with-perl`. Or say you need SSL support and to tell teh compiler to use -Homebrew-installed OpenSSL. Edit it something like: +PL/Perl, it is possible to configure the variable `PGENV_CONFIGURE_OPTIONS` +adding `--with-perl`. Or say you need SSL support and to tell teh compiler to +use Homebrew-installed OpenSSL. Edit it something like: - PGENV_CONFIGURE_OPTS="--with-perl --with-openssl CFLAGS=-I/usr/local/opt/openssl/include LDFLAGS=-L/usr/local/opt/openssl/lib" +``` sh +PGENV_CONFIGURE_OPTIONS=( + --with-perl + --with-openssl + 'CFLAGS=-I/opt/local/opt/openssl/include -I/opt/local/opt/libxml2/include' + 'LDFLAGS=-L/opt/local/opt/openssl/lib -L/opt/local/opt/libxml2/lib' +) +``` Please note that it is possible to pass argument variables within the command line to instrument the build phase. As an example, the following is a possible -work-flow to configure and build a customized 10.5 instance: - - $ pgenv config write 10.5 - $ pgenv config edit 10.5 - # adjust PGENV_CONFIGURE_OPTS - $ pgenv build 10.5 - -In the case you need to specify a particular variable, such as the Perl interpreter, -pass it on the command line at the time of build: +workflow to configure and build a customized 10.5 instance: - $ PERL=/usr/local/my-fancy-perl pgenv build 10.5 - -#### Patching +``` sh +pgenv config write 10.5 +pgenv config edit 10.5 +# adjust PGENV_CONFIGURE_OPTIONS +pgenv build 10.5 +``` -`pgenv` can patch the source tree before the build process starts. -In particular, the `patch/` folder can contain a set of index files -and patch to apply. The process searches for an index file corresponding -to the PostgreSQL version to build, and if found applies all the patches -contained into the index. +In the case you need to specify a particular variable, such as the Perl +interpreter, pass it on the command line at the time of build: -Index files are named after the PostgreSQL version and the Operating System; -in particular the name of an index file is composed as `patch..` -where `version` is the PostgreSQL version number (or a part of it) and -`os` is the Operating System. As an example, `patch.8.1.4.Linux` represents -the index used when building PostgreSQL 8.1.4 on a Linux machine. -To provide more flexibility, the system searches for an index that is named -after the exact PostgreSQL version and Operating System or a mix of -possible combinations of those. -As an example, in the case of the PostgreSQL version -8.1.4 the index files is searched among one of the following: +``` sh +PERL=/usr/local/my-fancy-perl pgenv build 10.5 +``` - $PGENV_ROOT/patch/index/patch.8.1.4.Linux - $PGENV_ROOT/patch/index/patch.8.1.4 - $PGENV_ROOT/patch/index/patch.8.1.Linux - $PGENV_ROOT/patch/index/patch.8.1 - $PGENV_ROOT/patch/index/patch.8.Linux - $PGENV_ROOT/patch/index/patch.8 +#### Patching +`pgenv` can patch the source tree before the build process starts. In +particular, the `patch/` folder can contain a set of index files and patch to +apply. The process searches for an index file corresponding to the PostgreSQL +version to build, and if found applies all the patches contained into the index. + +Index files are named after the PostgreSQL version and the Operating System; in +particular the name of an index file is composed as `patch..` where +`version` is the PostgreSQL version number (or a part of it) and `os` is the +Operating System. As an example, `patch.8.1.4.Linux` represents the index used +when building PostgreSQL 8.1.4 on a Linux machine. To provide more flexibility, +the system searches for an index that is named after the exact PostgreSQL +version and Operating System or a mix of possible combinations of those. As an +example, in the case of the PostgreSQL version 8.1.4 the index files is searched +among one of the following: -This allows you to specify an index for pretty much any combination or grouping desired. -The first index file that matches wins and it is the only one used for the build process. -If no index file is found at all, no patching is applied on the source tree. +``` sh +$PGENV_ROOT/patch/index/patch.8.1.4.Linux +$PGENV_ROOT/patch/index/patch.8.1.4 +$PGENV_ROOT/patch/index/patch.8.1.Linux +$PGENV_ROOT/patch/index/patch.8.1 +$PGENV_ROOT/patch/index/patch.8.Linux +$PGENV_ROOT/patch/index/patch.8 +``` -The index file must contain a list of patches to apply, that is file names (either absolute -or relative to the `patch/` subfolder). Each individual file is applied thru `patch(1)`. +This allows you to specify an index for pretty much any combination or grouping +desired. The first index file that matches wins and it is the only one used for +the build process. If no index file is found at all, no patching is applied on +the source tree. -It is possible to specify a particular index file, that means avoid the automatic index selection, -by either setting the `PGENV_PATCH_INDEX` variable on the command line or in the configuration -file. As an example +The index file must contain a list of patches to apply, that is file names +(either absolute or relative to the `patch/` subfolder). Each individual file is +applied thru `patch(1)`. - $ PGENV_PATCH_INDEX=/src/my-patch-list.txt pgenv build 10.5 +It is possible to specify a particular index file, that means avoid the +automatic index selection, by either setting the `PGENV_PATCH_INDEX` variable on +the command line or in the configuration file. As an example +``` sh +PGENV_PATCH_INDEX=/src/my-patch-list.txt pgenv build 10.5 +``` #### Build special keywords The `build` command accepts the special keywords `earliest` and `latest` as -indicators of the version to build. -The logic is as follows: -- `latest` triggers the build of the very last available PostgreSQL version -available for download; -- `earliest` triggers the build of the very first available PostgreSQL version, -that is `1.08` (and probably is not what you are looking for); -- `latest xx` where `xx` is a PostgreSQL major version number (e.g., `13`) triggers -the build of the latest available version in such major version branch (e.g., `13.1`); -- `earliest xx` where `xx` is a PostgreSQL major version number (e.g., `13`) triggers -the build of the earliest available version in such major version branch (e.g., `13.0`). - -The `latest` and `earliest` keywords work only with the `build` command and not with the -`rebuild` command. - +indicators of the version to build. The logic is as follows: + +- `latest` triggers the build of the very last available PostgreSQL version + available for download; +- `earliest` triggers the build of the very first available PostgreSQL + version, that is `1.08` (and probably is not what you are looking for); +- `latest xx` where `xx` is a PostgreSQL major version number (e.g., `13`) + triggers the build of the latest available version in such major version + branch (e.g., `13.1`); +- `earliest xx` where `xx` is a PostgreSQL major version number (e.g., `13`) + triggers the build of the earliest available version in such major version + branch (e.g., `13.0`). + +The `latest` and `earliest` keywords work only with the `build` command and not +with the `rebuild` command. ### pgenv rebuild -The `rebuild` command allows the rebuilding from sources of a specific +The `rebuild` command allows the rebuilding from sources of a specific PostgreSQL version. *The `PGDATA` directory will not be deleted if already -initialized via `initdb`*. However, in the case the PostgreSQL instance -to rebuild is currently in use, the `rebuild` command will not proceed. -This is meant to prevent the user to change the binaries of a in-use -PostgreSQL cluster. +initialized via `initdb`*. However, in the case the PostgreSQL instance to +rebuild is currently in use, the `rebuild` command will not proceed. This is +meant to prevent the user to change the binaries of a in-use PostgreSQL cluster. -The configuration will follow the same rules adopted in `build`, that means -if a configuration file will be present it will be readed and loaded, otherwise -the system will claim about such file proposing to create one. +The configuration will follow the same rules adopted in `build`, which means if +a configuration file is present it will be loaded, otherwise the system will +claim about such file proposing to create one. -In the case a specific version has never been built, `rebuild` acts exactly -as `build`. +In the case a specific version has never been built, `rebuild` acts exactly as +`build`. ### pgenv remove Removes the specified version of PostgreSQL unless it is the currently-active version. Use the `clear` command to clear the active version before removing it. - $ pgenv remove 10.3 - PostgreSQL 10.3 removed +``` +$ pgenv remove 10.3 +PostgreSQL 10.3 removed +``` The command removes the version, data directory, source code and configuration. -The `remove` command supports the special keywords `earliest` and `latest` -to respectively indicate the oldest PostgreSQL version installed and -the newest one. It is also possible to indicate a major version -to narrow the scope of the special keywords. As an example: +The `remove` command supports the special keywords `earliest` and `latest` to +respectively indicate the oldest PostgreSQL version installed and the newest +one. It is also possible to indicate a major version to narrow the scope of the +special keywords. As an example: - $ pgenv remove latest 10 +``` +$ pgenv remove latest 10 +``` will remove the most recent PostgreSQL version of the 10 series installed. - ### pgenv start Starts the currently active version of PostgreSQL if it's not already running. Initializes the data directory if none exists. - $ pgenv start - PostgreSQL started +``` +$ pgenv start +PostgreSQL started +``` It is possible to specify flags to pass to `pg_ctl(1)` when performing the -`START` action, setting the `PGENV_START_OPTS` in the [configuration](#pgenv-config). -Such options must not include the data directory, nor the log file. +`START` action, setting the `PGENV_START_OPTIONS` array in the +[configuration](#pgenv-config). Such options must not include the data +directory, nor the log file. ### pgenv stop Stops the currently active version of PostgreSQL. - $ pgenv stop - PostgreSQL 10.5 stopped +``` +$ pgenv stop +PostgreSQL 10.5 stopped +``` It is possible to specify flags to pass to `pg_ctl(1)` when performing the -`stop` action, setting the `PGENV_STOP_OPTS` in the [configuration](#pgenv-config). +`stop` action, setting the `PGENV_STOP_OPTIONS` array in the +[configuration](#pgenv-config). ### pgenv restart Restarts the currently active version of PostgreSQL, or starts it if it's not already running. - $ pgenv restart - PostgreSQL 10.1 restarted - Logging to pgsql/data/server.log +``` +$ pgenv restart +PostgreSQL 10.1 restarted +Logging to pgsql/data/server.log +``` It is possible to specify flags to pass to `pg_ctl(1)` when performing the -`restart` action, setting the `PGENV_RESTART_OPTS` in the [configuration](#pgenv-config). - +`restart` action, setting the `PGENV_RESTART_OPTIONS` array in the +[configuration](#pgenv-config). ### pgenv available Shows all the versions of PostgreSQL available to download and build. Handy to -help you finding a version to pass to the `build` command. Note that the `available` -command produces copious output. - - $ pgenv available - ... - Available PostgreSQL Versions - ======================================================== - - PostgreSQL 9.6 - ------------------------------------------------ - 9.6.0 9.6.1 9.6.2 9.6.3 9.6.4 9.6.5 - 9.6.6 9.6.7 9.6.8 9.6.9 9.6.10 +help you finding a version to pass to the `build` command. Note that the +`available` command produces copious output. - PostgreSQL 10 - ------------------------------------------------ - 10.0 10.1 10.2 10.3 10.4 10.5 - - PostgreSQL 11 - ------------------------------------------------ - 11beta1 11beta2 11beta3 +``` +$ pgenv available +... + Available PostgreSQL Versions +======================================================== + + PostgreSQL 9.6 + ------------------------------------------------ + 9.6.0 9.6.1 9.6.2 9.6.3 9.6.4 9.6.5 + 9.6.6 9.6.7 9.6.8 9.6.9 9.6.10 + + PostgreSQL 10 + ------------------------------------------------ + 10.0 10.1 10.2 10.3 10.4 10.5 + + PostgreSQL 11 + ------------------------------------------------ + 11beta1 11beta2 11beta3 +``` The versions are organized and sorted by major release number. Any listed version may be passed to the `build` command. @@ -486,103 +520,107 @@ version may be passed to the `build` command. To limit the list to versions for specific major releases, pass them to `available`. For example, to list only the `9.6` and `10` available versions: - $ pgenv available 10 9.6 - Available PostgreSQL Versions - ======================================================== - - PostgreSQL 9.6 - ------------------------------------------------ - 9.6.0 9.6.1 9.6.2 9.6.3 9.6.4 9.6.5 - 9.6.6 9.6.7 9.6.8 9.6.9 9.6.10 - - PostgreSQL 10 - ------------------------------------------------ - 10.0 10.1 10.2 10.3 10.4 10.5 +``` +$ pgenv available 10 9.6 + Available PostgreSQL Versions +======================================================== + + PostgreSQL 9.6 + ------------------------------------------------ + 9.6.0 9.6.1 9.6.2 9.6.3 9.6.4 9.6.5 + 9.6.6 9.6.7 9.6.8 9.6.9 9.6.10 + + PostgreSQL 10 + ------------------------------------------------ + 10.0 10.1 10.2 10.3 10.4 10.5 +``` ### pgenv check -Checks the list of commands required to download and build PostgreSQL. Prints -a result for each, with either the path to the command or an error reporting -that the command was not found. +Checks the list of commands required to download and build PostgreSQL. Prints a +result for each, with either the path to the command or an error reporting that +the command was not found. ### pgenv help -Outputs a brief usage statement and summary of available commands, like -the following: - - $ pgenv help - Usage: pgenv [] - - The opgenv commands are: - use Set and start the current PostgreSQL version - clear Stop and unset the current PostgreSQL version - start Start the current PostgreSQL server - stop Stop the current PostgreSQL server - restart Restart the current PostgreSQL server - build Build a specific version of PostgreSQL - rebuild Re-build a specific version of PostgreSQL - remove Remove a specific version of PostgreSQL - version Show the current PostgreSQL version - current Same as 'version' - versions List all PostgreSQL versions available to pgenv - help Show this usage statement and command summary - available Show which versions can be downloaded - check Check all program dependencies - config View, edit, delete the program configuration - log Inspects the log of the cluster, if exist. - - For full documentation, see: https://github.com/theory/pgenv#readme - - This is 'pgenv' version 1.0.0 [5839e72] - -The last line of the 'help' shows the `pgenv` version number and, if -`git` is available, the short commit hash (this can be useful when -reporting bugs and filling issue requests). -Please note that, in order to print out the git `HEAD` information, -the `pgenv` must be able to find a `git` executable (i.e., it must be -in your `PATH`) and the `PGENV_ROOT` must be a git *checkout* directory. +Outputs a brief usage statement and summary of available commands, like the +following: + +``` +$ pgenv help +Usage: pgenv [] + +The pgenv commands are: + use Set and start the current PostgreSQL version + clear Stop and unset the current PostgreSQL version + start Start the current PostgreSQL server + stop Stop the current PostgreSQL server + restart Restart the current PostgreSQL server + build Build a specific version of PostgreSQL + rebuild Re-build a specific version of PostgreSQL + remove Remove a specific version of PostgreSQL + version Show the current PostgreSQL version + current Same as 'version' + versions List all PostgreSQL versions available to pgenv + help Show this usage statement and command summary + available Show which versions can be downloaded + check Check all program dependencies + config View, edit, delete the program configuration + log Inspects the log of the cluster, if exist. + +For full documentation, see: https://github.com/theory/pgenv#readme + +This is 'pgenv' version 1.0.0 [5839e72] +``` + +The last line of the 'help' shows the `pgenv` version number and, if `git` is +available, the short commit hash (this can be useful when reporting bugs and +filling issue requests). Please note that, in order to print out the git `HEAD` +information, the `pgenv` must be able to find a `git` executable (i.e., it must +be in your `PATH`) and the `PGENV_ROOT` must be a git *checkout* directory. ### pgenv config View, set, and delete configuration variables, both globally or for specific versions of PostgreSQL. Stores the configuration in Bash files, one for each version, as well as a default configuration. If pgenv cannot find a -configuration variable in a version-specific configuration file, it will look -in the default configuration. If it doesn't find it there, it tries to guess -the appropriate values, or falls back on its own defaults. +configuration variable in a version-specific configuration file, it will look in +the default configuration. If it doesn't find it there, it tries to guess the +appropriate values, or falls back on its own defaults. The `config` command accepts the following subcommands: -- `show` prints the current or specified version configuration -- `write` store the current or specified version configuration -- `edit` opens the current or specified version configuration in an editor (Using $EDITOR, e.g: export EDITOR=/usr/bin/vim) -- `delete` removes the specified configuration +- `show` prints the current or specified version configuration +- `write` store the current or specified version configuration +- `edit` opens the current or specified version configuration in an editor + (Using $EDITOR, e.g: export `EDITOR=/usr/bin/vim`) +- `delete` removes the specified configuration Each sub-command accepts a PostgreSQL version number (e.g., `10.5`) or a special keyword: -- `current` or `version` tells pgenv to use the currently active version of - PostgreSQL -- `default` tells pgenv to use the default configuration; -- `earliest` and `latest` to indicate respectively the oldest or newest -version of PostgreSQL installed. As in other commands, these two keywords -can be combined with a PostgreSQL major version number to point to the -configuration of the earliest/latest version within that major number. - - +- `current` or `version` tells pgenv to use the currently active version of + PostgreSQL +- `default` tells pgenv to use the default configuration; +- `earliest` and `latest` to indicate respectively the oldest or newest + version of PostgreSQL installed. As in other commands, these two keywords + can be combined with a PostgreSQL major version number to point to the + configuration of the earliest/latest version within that major number. If no version is explicitly passed to any of the `config` subcommands, the program will work against the currently active version of PostgreSQL. In order to start with a default configuration, use the `write` subcommand: - $ pgenv config write default - pgenv configuration file ~/.pgenv/.pgenv.default.conf written +``` +$ pgenv config write default +pgenv configuration file ~/.pgenv/.pgenv.default.conf written +``` A subsequent `show` displays the defaults: ``` sh -$ pgenv config show default +pgenv config show default # Default configuration # pgenv configuration for PostgreSQL # File: /home/luca/git/misc/PostgreSQL/pgenv/.pgenv.default.conf @@ -597,12 +635,10 @@ $ pgenv config show default # PGENV_MAKE='' # Make flags -PGENV_MAKE_OPTS='-j3' +PGENV_MAKE_OPTIONS=(-j3) # Configure flags -# PGENV_CONFIGURE_OPTS='' - - +# PGENV_CONFIGURE_OPTIONS=( ) # ... ##### Runtime options ##### @@ -613,99 +649,112 @@ PGENV_LOG='/home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log' PGENV_PG_USER='postgres' # Initdb flags -PGENV_INITDB_OPTS='-U postgres --locale en_US.UTF-8 --encoding UNICODE' +PGENV_INITDB_OPTIONS=(-U postgres --locale en_US.UTF-8 --encoding UNICODE) # ... ``` You can edit the file and adjust parameters to your needs. -In order to create a configuration file for a specific version, pass the -version to the `write` subcommand: +In order to create a configuration file for a specific version, pass the version +to the `write` subcommand: - $ pgenv config write 10.5 - pgenv configuration file [~/.pgenv/.pgenv.10.5.conf] written +``` +$ pgenv config write 10.5 +pgenv configuration file [~/.pgenv/.pgenv.10.5.conf] written +``` -Each time pgenv writes a configuration file, it first creates a backup with -the suffix `.backup`. +Each time pgenv writes a configuration file, it first creates a backup with the +suffix `.backup`. -Use the `edit` subcommand to edit a configuration file in your favourite -editor: +Use the `edit` subcommand to edit a configuration file in your favorite editor: - $ pgenv config edit 10.5 - +``` +$ pgenv config edit 10.5 + +``` -The `edit` command will start your favourite editor, that is whatever -it is set within the `EDITOR` variable. If such variable is not set -you will be warned. +The `edit` command will start your favorite editor, that is whatever it is set +within the `EDITOR` variable. If such variable is not set you will be warned. Use the `delete` subcommand to delete a configuration: - $ pgenv config delete 10.5 - Configuration file ~/.pgenv/.pgenv.10.5.conf (and backup) deleted - -Note that you cannot delete the default configuration unless all other -versions have been removed (e.g., by `pgenv remove`). This prevents accidental -loss of configuration: +``` +$ pgenv config delete 10.5 +Configuration file ~/.pgenv/.pgenv.10.5.conf (and backup) deleted +``` - $ pgenv config delete - Cannot delete default configuration while version configurations exist - To remove it anyway, delete ~/.pgenv/.pgenv.default.conf. +Note that you cannot delete the default configuration unless all other versions +have been removed (e.g., by `pgenv remove`). This prevents accidental loss of +configuration: -The `delete` subcommand deletes both the configuration file and its backup -copy. The `pgenv remove` command also deletes any configuration for the -removed version. +``` +$ pgenv config delete +Cannot delete default configuration while version configurations exist +To remove it anyway, delete ~/.pgenv/.pgenv.default.conf. +``` +The `delete` subcommand deletes both the configuration file and its backup copy. +The `pgenv remove` command also deletes any configuration for the removed +version. -Please note that since commit [5839e721](https://github.com/theory/pgenv/commit/5839e721d43c9eae8b4a0d61ba78996c220a4da0) -the file name of the default configuration file has changed. In the case you want to convert your -default configuration file, please issue a rename like the following +Please note that since commit [5839e721] the file name of the default +configuration file has changed. In the case you want to convert your default +configuration file, please issue a rename like the following - $ cp .pgenv.conf .pgenv.default.conf +``` sh +cp .pgenv.conf .pgenv.default.conf +``` +### pgenv log +The `log` command provides a dump of the cluster log, if it exists, so that you +don't have to worry about the exact log location. The log is dumped using the +`tail` command, and every option passed to the command line is passed thru +`tail`. As an example: -### pgenv log +``` +$ pgenv log +Dumping the content of /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log + +2020-08-28 19:04:44.199 CEST [10702] LOG: could not bind IPv4 address "127.0.0.1": Address already in use +2020-08-28 19:04:44.199 CEST [10702] HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. +2020-08-28 19:04:44.199 CEST [10702] WARNING: could not create listen socket for "localhost" +2020-08-28 19:04:44.199 CEST [10702] FATAL: could not create any TCP/IP sockets +2020-08-28 19:04:44.199 CEST [10702] LOG: database system is shut down +2020-08-28 19:09:09.024 CEST [11867] LOG: starting PostgreSQL 12.1 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 8.3.0-6ubuntu1) 8.3.0, 64-bit +2020-08-28 19:09:09.024 CEST [11867] LOG: listening on IPv4 address "127.0.0.1", port 5432 +2020-08-28 19:09:09.028 CEST [11867] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432" +2020-08-28 19:09:09.045 CEST [11868] LOG: database system was shut down at 2020-08-28 12:57:33 CEST +2020-08-28 19:09:09.048 CEST [11867] LOG: database system is ready to accept connections + ``` -The `log` command provides a dump of the cluster log, if it exists, so that you don't have to worry about the exact log location. -The log is dumped using the `tail` command, and every option passed to -the command line is passed thru `tail`. As an example: - - $ pgenv log - Dumping the content of /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log - - 2020-08-28 19:04:44.199 CEST [10702] LOG: could not bind IPv4 address "127.0.0.1": Address already in use - 2020-08-28 19:04:44.199 CEST [10702] HINT: Is another postmaster already running on port 5432? If not, wait a few seconds and retry. - 2020-08-28 19:04:44.199 CEST [10702] WARNING: could not create listen socket for "localhost" - 2020-08-28 19:04:44.199 CEST [10702] FATAL: could not create any TCP/IP sockets - 2020-08-28 19:04:44.199 CEST [10702] LOG: database system is shut down - 2020-08-28 19:09:09.024 CEST [11867] LOG: starting PostgreSQL 12.1 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 8.3.0-6ubuntu1) 8.3.0, 64-bit - 2020-08-28 19:09:09.024 CEST [11867] LOG: listening on IPv4 address "127.0.0.1", port 5432 - 2020-08-28 19:09:09.028 CEST [11867] LOG: listening on Unix socket "/tmp/.s.PGSQL.5432" - 2020-08-28 19:09:09.045 CEST [11868] LOG: database system was shut down at 2020-08-28 12:57:33 CEST - 2020-08-28 19:09:09.048 CEST [11867] LOG: database system is ready to accept connections - The above is equivalent to manually executing - $ tail /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log +``` sh +tail /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log +``` It is possible to pass arguments to `tail` as command line flags: - $ pgenv log -n 2 - Dumping the content of /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log +``` +$ pgenv log -n 2 +Dumping the content of /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log - 2020-08-28 19:09:09.045 CEST [11868] LOG: database system was shut down at 2020-08-28 12:57:33 CEST - 2020-08-28 19:09:09.048 CEST [11867] LOG: database system is ready to accept connections +2020-08-28 19:09:09.045 CEST [11868] LOG: database system was shut down at 2020-08-28 12:57:33 CEST +2020-08-28 19:09:09.048 CEST [11867] LOG: database system is ready to accept connections +``` which results in executing - $ tail -n 2 /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log - -and of course, you can inspect the log of live system continuosly: +``` sh +tail -n 2 /home/luca/git/misc/PostgreSQL/pgenv/pgsql/data/server.log +``` +and of course, you can inspect the log of live system continuously: - $ pgenv log -f - - +``` sh +pgenv log -f +``` # Bug Reporting @@ -733,3 +782,4 @@ Distributed under [The MIT License]; see [`LICENSE.md`] for terms. [GitHub issues]: https://github.com/theory/pgenv/issues/ [The MIT License]: https://opensource.org/licenses/MIT [`LICENSE.md`]: https://github.com/theory/pgenv/blob/master/LICENSE.md +[5839e721]: https://github.com/theory/pgenv/commit/5839e721d43c9eae8b4a0d61ba78996c220a4da0 diff --git a/bin/pgenv b/bin/pgenv index 5e7dd35..80f12b8 100755 --- a/bin/pgenv +++ b/bin/pgenv @@ -4,7 +4,6 @@ # PGENV_VERSION="1.1.0" - # https://stackoverflow.com/a/19622569/79202 trap 'exit' ERR set -E @@ -32,22 +31,23 @@ INITDB="$PGSQL/bin/initdb" # Configuration variable and default settings PGENV_LOG=$PG_DATA/server.log -PGENV_INITDB_OPTS='-U postgres --locale en_US.UTF-8 --encoding UNICODE' -PGENV_MAKE_OPTS="-j3" -PGENV_CONFIGURE_OPTS="" -PGENV_START_OPTS="" -PGENV_STOP_OPTS="" +PGENV_MAKE_OPTIONS=(-j3) +PGENV_CONFIGURE_OPTIONS=() +PGENV_INITDB_OPTIONS=(-U postgres --locale en_US.UTF-8 --encoding UNICODE) +PGENV_START_OPTIONS=() +PGENV_STOP_OPTIONS=() +PGENV_RESTART_OPTIONS=() + ############################################# # Prints a debug message if PGENV_DEBUG # variable enabled pgenv_debug(){ if [ ! -z "$PGENV_DEBUG" ]; then - echo "[DEBUG] $1" >&2 + echo "[DEBUG] $@" >&2 fi } - # This function connects to the PostgreSQL web site # (i.e., PGENV_DOWNLOAD_ROOT) and gets the list of # available versions. @@ -102,7 +102,6 @@ pgenv_get_downloadable_versions(){ } - pgenv_versions() { if [ -e "pgsql" ]; then local curr=$(readlink pgsql) @@ -133,7 +132,7 @@ pgenv_help() { # get current git version if possible if [ ! -z "$( command -v git )" -a -d "${PGENV_ROOT}/.git" ]; then - git_version="[$( git log -n 1 --format='%h' )]" + git_version="[$( git -c log.showSignature=false log -n 1 --format='%h' )]" fi cat <> "$file" + if [[ "$name" =~ _OPTIONS$ ]]; then + typeset -p "${name}" >> "$file" + else + if [ -z "$value" ]; then + echo -n "#" >> "$file" + fi + echo "${name}='${value}'" >> "$file" fi - echo "${name}='${value}'" >> "$file" echo >> "$file" } @@ -618,8 +636,8 @@ pgenv_configuration_write() { echo "###### Build settings #####" >> "$CONF" pgenv_configuration_write_variable "$CONF" "PGENV_MAKE" "$PGENV_MAKE" 'Make command to use for build' - pgenv_configuration_write_variable "$CONF" "PGENV_MAKE_OPTS" "$PGENV_MAKE_OPTS" 'Make flags' - pgenv_configuration_write_variable "$CONF" "PGENV_CONFIGURE_OPTS" "$PGENV_CONFIGURE_OPTS" 'Configure flags, including PL languages but without --prefix' + pgenv_configuration_write_variable "$CONF" "PGENV_MAKE_OPTIONS" "" 'Make flags' + pgenv_configuration_write_variable "$CONF" "PGENV_CONFIGURE_OPTIONS" "" 'Configure flags, including PL languages but without --prefix' pgenv_configuration_write_variable "$CONF" "PGENV_PATCH_INDEX" "$PGENV_PATCH_INDEX" 'A file that lists ordered patches to apply before building starts' @@ -629,10 +647,10 @@ pgenv_configuration_write() { echo "##### Runtime options #####" >> "$CONF" pgenv_configuration_write_variable "$CONF" "PGENV_LOG" "$PGENV_LOG" 'Path to the cluster log file (mandatory)' - pgenv_configuration_write_variable "$CONF" "PGENV_INITDB_OPTS" "$PGENV_INITDB_OPTS" 'Initdb flags' - pgenv_configuration_write_variable "$CONF" "PGENV_STOP_OPTS" "$PGENV_STOP_OPTS" 'Stop configuration flags' - pgenv_configuration_write_variable "$CONF" "PGENV_START_OPTS" "$PGENV_START_OPTS" 'Start configuration flags' - pgenv_configuration_write_variable "$CONF" "PGENV_RESTART_OPTS" "$PGENV_RESTART_OPTS" 'Restart configuration flags' + pgenv_configuration_write_variable "$CONF" "PGENV_INITDB_OPTIONS" "" 'Initdb flags' + pgenv_configuration_write_variable "$CONF" "PGENV_STOP_OPTIONS" "" 'Stop configuration flags' + pgenv_configuration_write_variable "$CONF" "PGENV_START_OPTIONS" "" 'Start configuration flags' + pgenv_configuration_write_variable "$CONF" "PGENV_RESTART_OPTIONS" "" 'Restart configuration flags' pgenv_configuration_write_variable "$CONF" "PGENV_SCRIPT_POSTINSTALL" "" 'Script to execute when the build process finishes' pgenv_configuration_write_variable "$CONF" "PGENV_SCRIPT_POSTINITDB" "" 'Script to execute when initdb finishes' @@ -641,7 +659,6 @@ pgenv_configuration_write() { pgenv_configuration_write_variable "$CONF" "PGENV_SCRIPT_POSTSTART" "" 'Script to execute when the cluster has been started' pgenv_configuration_write_variable "$CONF" "PGENV_SCRIPT_POSTRESTART" "" 'Script to execute when the cluster has been restarted' - echo "pgenv configuration written to file $CONF" } @@ -734,7 +751,6 @@ EOF return fi - # check that the PGENV path is ahead of other PostgreSQL binaries # in order to do so count a few common executables and see # if they are the same path as what is expected to be @@ -769,7 +785,6 @@ EOF } - # Wrapper function to start the current instance. # If the instance is already running, nothing happens. # If the instance does not have already a PG_DATA @@ -786,8 +801,8 @@ pgenv_start_instance(){ # Init the database if needed. pgenv_initdb - pgenv_debug "pg_ctl starting instance with flags [$PGENV_START_OPTS] log [$PGENV_LOG]" - $PG_CTL start -D "$PG_DATA" -l "$PGENV_LOG" $PGENV_START_OPTS &> /dev/null + pgenv_debug "pg_ctl starting instance with flags [${PGENV_START_OPTIONS[@]}] log [$PGENV_LOG]" + $PG_CTL start -D "$PG_DATA" -l "$PGENV_LOG" "${PGENV_START_OPTIONS[@]}" &> /dev/null if [ $? -eq 0 ]; then echo "PostgreSQL $v started" echo "Logging to $PGENV_LOG" @@ -814,8 +829,8 @@ pgenv_start_instance(){ # It is safe to call multiple times. pgenv_initdb(){ if [ ! -d $PG_DATA ]; then - pgenv_debug "initdb running with flags [$PGENV_INITDB_OPTS]" - $INITDB -D "$PG_DATA" $PGENV_INITDB_OPTS + pgenv_debug "initdb running with flags [${PGENV_INITDB_OPTIONS[@]}]" + $INITDB -D "$PG_DATA" "${PGENV_INITDB_OPTIONS[@]}" # if there is a post-initdb script to run, run it if [ -x "$PGENV_SCRIPT_INITDB" ]; then @@ -843,13 +858,11 @@ pgenv_stop_or_restart_instance(){ # Don't exit on error. trap "" ERR - if $PG_CTL status -D "$PG_DATA" &> /dev/null; then # ok, server running, apply the command case $command in stop) - pgenv_debug "pg_ctl stopping with flags [$PGENV_STOP_OPTS]" - + pgenv_debug "pg_ctl stopping with flags [${PGENV_STOP_OPTIONS[@]}]" # if there is a pre-stop script to run, run it if [ -x "$PGENV_SCRIPT_PRESTOP" ]; then @@ -857,7 +870,7 @@ pgenv_stop_or_restart_instance(){ $PGENV_SCRIPT_PRESTOP "$PG_DATA" fi - $PG_CTL stop -D "$PG_DATA" $PGENV_STOP_OPTS &> /dev/null + $PG_CTL stop -D "$PG_DATA" "${PGENV_STOP_OPTIONS[@]}" &> /dev/null echo "PostgreSQL $v stopped" # if there is a post-stop script to run, run it @@ -867,8 +880,8 @@ pgenv_stop_or_restart_instance(){ fi ;; restart) - pgenv_debug "pg_ctl restarting with flags [$PGENV_RESTART_OPTS]" - $PG_CTL restart -D "$PG_DATA" -l "$PGENV_LOG" $PGENV_RESTART_OPTS &> /dev/null + pgenv_debug "pg_ctl restarting with flags [${PGENV_RESTART_OPTIONS[@]}]" + $PG_CTL restart -D "$PG_DATA" -l "$PGENV_LOG" "${PGENV_RESTART_OPTIONS[@]}" &> /dev/null echo "PostgreSQL $v restarted" echo "Logging to $PGENV_LOG" @@ -892,7 +905,6 @@ pgenv_stop_or_restart_instance(){ fi } - # A function to provide the list, in the right order, of # patch index files to try for patching the source tree. # The idea is that the priority goes to an index that matches @@ -928,9 +940,6 @@ EOF } - - - # Utility function to patch a source tree. # The function accepts a version number, that is the version number of PostgreSQL # that is going to be built. The function gets the list of available patch index files @@ -962,7 +971,6 @@ pgenv_patch_source_tree() { done fi - pgenv_debug "Patch index file [$PGENV_PATCH_INDEX]" if [ ! -r "$PGENV_PATCH_INDEX" ]; then # no patch to apply @@ -997,7 +1005,6 @@ pgenv_patch_source_tree() { done } - case $1 in use) v=$( pgenv_guess_postgresql_version $2 $3) @@ -1055,7 +1062,6 @@ case $1 in # check PATH settings pgenv_warning_path - # either stop or restart command="$1" @@ -1086,7 +1092,6 @@ case $1 in # build the hash of the versions pgenv_get_downloadable_versions - if [ -z "$current_major" ]; then # easy: get the first or last index of the hash majors=("${!pg_versions_hash[@]}") @@ -1101,7 +1106,6 @@ case $1 in current_major=$(( current_major * 10 )) fi - # loop thru the array for the selected major version number # and extract the first or last position for vv in $( echo ${pg_versions_hash[$current_major]} \ @@ -1126,7 +1130,6 @@ case $1 in pgenv_configuration_load $v pgenv_check_dependencies - # Skip it if we already have it, and are not rebuilding if [ "$command" != 'rebuild' ]; then if [ -e "pgsql-$v" ]; then @@ -1221,23 +1224,20 @@ EOF pgenv_debug "Patching version $v" pgenv_patch_source_tree "$v" 'verbose' - - pgenv_debug "configure command line [--prefix=$PGENV_ROOT/pgsql-$v] + [$PGENV_CONFIGURE_OPTS]" - # need to keep a single string to pass to configure or - # will get an 'invalid package' - ./configure --prefix=$PGENV_ROOT/pgsql-$v $PGENV_CONFIGURE_OPTS + pgenv_debug "configure command line [--prefix=$PGENV_ROOT/pgsql-$v] + [${PGENV_CONFIGURE_OPTIONS[@]}]" + ./configure --prefix=$PGENV_ROOT/pgsql-$v "${PGENV_CONFIGURE_OPTIONS[@]}" # make and make install if [[ $v =~ ^[1-8]\. ]]; then # 8.x (and prior versions?) doesn't have `make world`. - $PGENV_MAKE $PGENV_MAKE_OPTS + $PGENV_MAKE "${PGENV_MAKE_OPTIONS[@]}" $PGENV_MAKE install cd contrib - $PGENV_MAKE $PGENV_MAKE_OPTS + $PGENV_MAKE "${PGENV_MAKE_OPTIONS[@]}" $PGENV_MAKE install else # Yay, make world! - $PGENV_MAKE world $PGENV_MAKE_OPTS + $PGENV_MAKE world "${PGENV_MAKE_OPTIONS[@]}" $PGENV_MAKE install-world fi @@ -1402,7 +1402,6 @@ EOF config|configuration) action=$2 - if [ -z "$3" ]; then v="default" else @@ -1502,7 +1501,6 @@ EOF fi ;; - *) if [ $# -gt 0 ]; then echo "Unknown command \`$@\`"