Setting up dev environment can be a nightmare.yem intends to make it easier.

Inspiration

yem is inspired from SDKMan, Chocolatey and other alternatives. The main differences are:

  • yem does not come with a remote storage but it tries to reuse existing ones - priviledging immutable one when possible (compared to SDKMan where you can loose the version you picked),

  • yem intends to be portable (linux/windows at least),

  • yem is extensible if needed (new source or tool/distribution).

Configuration

IMPORTANT

the atomic configuration is listed there but used on the command line you must ensure to prefix any option by - and replace dots by -. Example: central.base becomes --central-base.

  • central.base (central_base) (default: "https://repo.maven.apache.org/maven2/"): Base repository URL..

  • central.gavs (central_gavs) (default: "org.apache.maven:apache-maven:tar.gz:bin"): List of GAV to register (comma separated). Such a provider can be enabled/disabled using artifactId.enabled property..

  • central.header (central_header): Headers to add if the repository is authenticated. Syntax uses HTTP one: --central-header 'Authorization: Basic xxxxx' for example.

  • central.local (central_local) (default: System.getProperty("user.home", "") + "/.m2/repository"): Local repository path..

  • delete.provider (delete_provider): Provider to use to delete the version (if not t is deduced from the tool/version parameters)..

  • delete.tool (delete_tool)*: Tool to delete..

  • delete.version (delete_version)*: Version of tool to delete - we recommend to use the actual identifier to avoid to delete more than the expected instance..

  • env.defaultRc (env_defaultRc) (default: System.getProperty("user.home") + "/.yupiik/yem/rc"): Should ~/.yupiik/yem/rc be ignored or not. If present it defines default versions and uses the same syntax than yemrc..

  • env.enableAutoDetection (env_enableAutoDetection) (default: false): EXPERIMENTAL. If enabled and no .yemrc nor .sdkmanrc setup any tool (ie empty does not count) then try to detect some well known tools like Java (there is a pom.xml and the compiler version can be extracted for example) and Maven (pom.xml presence). Note that it is done using ./ folder and bubbles up with a max of 10 levels..

  • env.inlineRc (env_inlineRc): Enables to set inline a rc file, ex: eval $(yem env --inlineRc 'java.version=17.0.9'), you can use EOL too: eval $(yem env --inlineRc 'java.version=17.\njava.relaxed = true'). Note that to persist the change even if you automatically switch from the global yemrc file the context, we set YEM_$TOOLPATHVARNAME_OVERRIDEN environment variable. To reset the value to the global configuration just unset this variable (ex: unset YEM_JAVA_PATH_OVERRIDEN). Note that you can also just set the values inline as args without that option: eval $(yem env --java-version 17. --java-relaxed true ...)..

  • env.rc (env_rc) (default: "auto"): Env file location to read to generate the script. Note that auto will try to pick .yemrc and if not there will use .sdkmanrc if present..

  • env.skipReset (env_skipReset) (default: false): By default if YEM_ORIGINAL_PATH exists in the environment variables it is used as PATH base to not keep appending path to the PATH indefinively. This can be disabled setting this property to false.

  • github.base (github_base) (default: "https://api.github.com"): Base repository URL..

  • github.header (github_header): Header to add to every request (authorization one for example)..

  • github.local (github_local) (default: System.getProperty("user.home", "") + "/.yupiik/yem/github"): Local repository path..

  • http.address (http_address) (default: "localhost"): Binding address..

  • http.cacheValidity (http_cacheValidity) (default: 86_400_000L): Cache validity of requests (1 day by default) in milliseconds. A negative or zero value will disable cache..

  • http.cache (http_cache) (default: System.getProperty("user.home", "") + "/.yupiik/yem/cache/http"): Where to cache slow updates (version fetching). none will disable cache..

  • http.connectTimeout (http_connectTimeout) (default: 10_000L): Connection timeout in milliseconds, in case of offline mode it should stay low enough to not block any new command too long when set up automatically. You can set in ~/.yupiik/yem/rc the line http.offlineMode=true or http.connectTimeout = 3000 to limit this effect..

  • http.ignoreSSLErrors (http_ignoreSSLErrors) (default: false): Should SSL errors be ignored..

  • http.log (http_log) (default: false): Should HTTP calls be logged..

  • http.offlineMode (http_offlineMode) (default: false): Force offline mode..

  • http.offlineTimeout (http_offlineTimeout) (default: 5_000): Check offline timeout. Per uri a test is done to verify the system is offline..

  • http.open (http_open) (default: true): Should the server be opened ASAP if possible on your system or just the server be launched..

  • http.port (http_port) (default: 0): Port to open the server to, by default it is random..

  • http.proxy.host (http_proxy_host) (default: "none"): Proxy host. none means ignore..

  • http.proxy.ignoredHosts (http_proxy_ignoredHosts) (default: java.util.List.of()): Hosts to connect directly to (ignoring the proxy)..

  • http.proxy.password (http_proxy_password) (default: "none"): Proxy password. none means ignore..

  • http.proxy.port (http_proxy_port) (default: 3128): Proxy port..

  • http.proxy.username (http_proxy_username) (default: "none"): Proxy username. none means ignore..

  • http.requestTimeout (http_requestTimeout) (default: 900_000L): Request timeout in milliseconds..

  • http.threads (http_threads) (default: 4): Number of NIO threads..

  • install.provider (install_provider): Provider to use to install the version (if not t is deduced from the tool/version parameters)..

  • install.relaxed (install_relaxed) (default: false): Should version be matched with a startsWith logic (ex: install --install-tool java --install-relaxed true --install-version 21.)..

  • install.skipProgress (install_skipProgress) (default: System.getenv("CI") != null): Should progress bar be skipped (can be useful on CI for example)..

  • install.tool (install_tool)*: Tool to install..

  • install.version (install_version)*: Version of tool to install..

  • list-local.tool (list_local_tool): Tool to filter..

  • list.providers (list_providers): List of providers to use (comma separated)..

  • list.tools (list_tools): List of tools to list (comma separated)..

  • messages.disableColors (messages_disableColors) (default: "auto"): Are colors disabled for the terminal..

  • messages.disableEmoji (messages_disableEmoji) (default: "auto"): If false emoji are totally disabled. auto will test /usr/share/fonts/truetype/noto/NotoColorEmoji.ttf and /usr/share/fonts/google-noto-emoji/NotoColorEmoji.ttf presence to enable emojis. true/false disable/enable emoji whatever the available fonts..

  • messages.errorColor (messages_errorColor) (default: "31"): Error message color..

  • messages.toolColor (messages_toolColor) (default: "0;49;34"): When color are enabled the tool name color..

  • messages.versionColor (messages_versionColor) (default: "0;49;96"): When color are enabled the version color..

  • messages.warningColor (messages_warningColor) (default: "33"): Warning message color..

  • minikube.enabled (minikube_enabled) (default: false): Is Minikube (Github) support enabled. It is disabled by default cause it also depends on local dependencies (docker or cri depending how you plan to run - driver)..

  • resolve.provider (resolve_provider): Provider to use to resolve the version (if not t is deduced from the tool/version parameters)..

  • resolve.relaxed (resolve_relaxed) (default: false): Should version be matched with a startsWith logic (ex: resolve --resolve-tool java --resolve-relaxed true --resolve-version 21.)..

  • resolve.tool (resolve_tool)*: Tool to resolve..

  • resolve.version (resolve_version)*: Version of tool to resolve..

  • run.defaultRc (run_defaultRc) (default: System.getProperty("user.home") + "/.yupiik/yem/rc"): Should ~/.yupiik/yem/rc be ignored or not. If present it defines default versions and uses the same syntax than yemrc..

  • run.rc (run_rc) (default: ".yemrc"): Env file location to read to generate the script. Note that auto will try to pick .yemrc and if not there will use .sdkmanrc if present..

  • sdkman.base (sdkman_base) (default: "https://api.sdkman.io/2/"): Base URL for SDKMan API..

  • sdkman.enabled (sdkman_enabled) (default: true): Is SDKMan support enabled..

  • sdkman.local (sdkman_local) (default: java.util.Optional.ofNullable(System.getenv("SDKMAN_DIR")).map(b -> java.nio.file.Path.of(b).resolve("candidates").toString()).orElseGet(() -> System.getProperty("user.home", "") + "/.sdkman/candidates")): SDKMan local candidates directory, generally $HOME/.sdkman/candidates..

  • sdkman.platform (sdkman_platform) (default: "auto"): SDKMan platform value - if auto it will be computed..

  • zulu.apiBase (zulu_apiBase) (default: "https://api.azul.com"): This property is the Zulu API base URI..

  • zulu.base (zulu_base) (default: "https://cdn.azul.com/zulu/bin/"): Base URL for zulu CDN archives..

  • zulu.enabled (zulu_enabled) (default: true): Is Zulu CDN support enabled..

  • zulu.local (zulu_local) (default: System.getProperty("user.home", "") + "/.yupiik/yem/zulu"): Local cache of distributions..

  • zulu.platform (zulu_platform) (default: "auto"): Zulu platform value - if auto it will be computed..

  • zulu.preferApi (zulu_preferApi) (default: true): YEM is able to scrape the CDN index page but it is slow when not cached so by default we prefer the Zulu API. This property enables to use the scrapping by being set to false..

  • zulu.preferJre (zulu_preferJre) (default: false): Should JRE be preferred over JDK..

CLI

The command line uses spaces between option and value: yem install --tool java --version 21.0.2.

Commands

  • config: Show configuration.

  • delete: Delete a distribution.
    • Parameters:
      • --delete-provider: Provider to use to delete the version (if not t is deduced from the tool/version parameters).

      • --delete-tool: Tool to delete.

      • --delete-version: Version of tool to delete - we recommend to use the actual identifier to avoid to delete more than the expected instance.

  • env: Creates a script you can eval in a shell to prepare the environment from a file. Often used as eval $(yem env--env-rc .yemrc)
    • Parameters:
      • --env-defaultRc: Should ~/.yupiik/yem/rc be ignored or not. If present it defines default versions and uses the same syntax than yemrc.

      • --env-enableAutoDetection: EXPERIMENTAL. If enabled and no .yemrc nor .sdkmanrc setup any tool (ie empty does not count) then try to detect some well known tools like Java (there is a pom.xml and the compiler version can be extracted for example) and Maven (pom.xml presence). Note that it is done using ./ folder and bubbles up with a max of 10 levels.

      • --env-inlineRc: Enables to set inline a rc file, ex: eval $(yem env --inlineRc 'java.version=17.0.9'), you can use EOL too: `eval $(yem env --inlineRc 'java.version=17. java.relaxed = true'). Note that to persist the change even if you automatically switch from the globalyemrcfile the context, we setYEM$TOOLPATHVARNAMEOVERRIDENenvironment variable. To reset the value to the global configuration justunsetthis variable (ex:unset YEMJAVAPATH_OVERRIDEN). Note that you can also just set the values inline as args without that option:eval $(yem env --java-version 17. --java-relaxed true ...)`.

      • --env-rc: Env file location to read to generate the script. Note that auto will try to pick .yemrc and if not there will use .sdkmanrc if present.

      • --env-skipReset: By default if YEM_ORIGINAL_PATH exists in the environment variables it is used as PATH base to not keep appending path to the PATH indefinively. This can be disabled setting this property to false

  • http: Show configuration in a web browser.
    • Parameters:
      • --http-address: Binding address.

      • --http-open: Should the server be opened ASAP if possible on your system or just the server be launched.

      • --http-port: Port to open the server to, by default it is random.

  • install: Install a distribution.
    • Parameters:
      • --install-provider: Provider to use to install the version (if not t is deduced from the tool/version parameters).

      • --install-relaxed: Should version be matched with a startsWith logic (ex: install --install-tool java --install-relaxed true --install-version 21.).

      • --install-skipProgress: Should progress bar be skipped (can be useful on CI for example).

      • --install-tool: Tool to install.

      • --install-version: Version of tool to install.

  • list: List remote (available) distributions.
    • Parameters:
      • --list-providers: List of providers to use (comma separated).

      • --list-tools: List of tools to list (comma separated).

  • list-local: List local available distributions.
    • Parameters:
      • --list-local-tool: Tool to filter.

  • list-providers: List available providers.

  • resolve: Resolve a distribution.
    • Parameters:
      • --resolve-provider: Provider to use to resolve the version (if not t is deduced from the tool/version parameters).

      • --resolve-relaxed: Should version be matched with a startsWith logic (ex: resolve --resolve-tool java --resolve-relaxed true --resolve-version 21.).

      • --resolve-tool: Tool to resolve.

      • --resolve-version: Version of tool to resolve.

  • run: Similar to env spirit but for aliases or execution in the shell context of the .yemrc file. Important: it is recommended to use -- to separate yem args from the command: yem run --rc .yemrc -- mvn clean package. Note that the first arg after -- will be tested against an alias in the .yemrc (or global one) so you can pre-define complex commands there. Ex: build.alias = mvn package in .yemrc will enable to run yem run -- build which will actually execute mvn package and if you configure maven version (maven.version = 3.9.6 for example) the execution environment will use the right distribution.
    • Parameters:
      • --run-defaultRc: Should ~/.yupiik/yem/rc be ignored or not. If present it defines default versions and uses the same syntax than yemrc.

      • --run-rc: Env file location to read to generate the script. Note that auto will try to pick .yemrc and if not there will use .sdkmanrc if present.

Auto-path

A bit like SDKMan, yem supports to initialize an environment from a file but with some differences.

The file must be a properties file. Each tool/distribution setup has several properties:

prefix.version = 1.2.3 (1)
prefix.provider = xxxx (2)
prefix.relaxed = [true|false] (3)
prefix.envVarName = xxxx (4)
prefix.addToPath = [true|false] (5)
prefix.failOnMissing = [true|false] (6)
prefix.installIfMissing = [true|false] (7)
prefix.toolName = 1.2.3 (8)
  1. Version of the tool to install, using relaxed option it can be a version prefix ( 21. for ex),
  2. Provider to use to resolve the tool, if you want to force zulu provider instead of using SDKMan to install Java versions for example,
  3. Should version be matched exactly or the first matching one be used,
  4. When addToPath is true (default) the environment name to setup for this tool - deduced from tool name otherwise, generally uppercase(tool)_HOME with dot replaced by underscores,
  5. Should the PATH be set too - note that when it is the case YEM_ORIGINAL_PATH is set too allowing to reset PATH when exiting the folder,
  6. Should the execution fail if a tool is missing (mainly for debug purposes),
  7. Should tools be installed automatically when missing - CI friendly,
  8. If your prefix does not match the tool name, the tool name to use.

Only the version property is required of prefix matches a tool name. You can get as much group of properties as needed tools (one for java 11, one for java 17, one for maven 4 etc...).

Alias support

The run command supports aliases. They globally use a .yemrc file as for env command but support additional properties.

These additional properties must match the pattern xxx.alias = yyyy where xxx is an alias name and yyyy a command. The usage of yem run -- xxxx will be equivalent to run yyyy command (can have arguments predefined) in the context of the .yemrc file, including the environment - Java, Apache Maven etc...

TIP

If you need to see more logs from yem you can add the following system properties: -Djava.util.logging.manager=io.yupiik.logging.jul.YupiikLogManager -Dio.yupiik.logging.jul.handler.StandardHandler.level=FINEST -Dio.yupiik.level=FINEST.

You can also force some default configuration (typically central gavs or offlineMode) in ~/.yupiik/yem/rc. If you don't want this global file to be taken into account temporarly (or not) you can set the environment variable YEM_DISABLE_GLOBAL_RC_FILE to true.

Shell/Bash setup

Yem is portable but we detail there only shell setup.

The idea is to leverage env command. Add to your global ~/.bashrc (or ~/.profile) configuration the following line:

yem_env() {
  eval $(yem env)
}
if [[ -n "$ZSH_VERSION" ]]; then
  chpwd_functions+=(yem_env)
else
  trimmed_prompt_command="${PROMPT_COMMAND%"${PROMPT_COMMAND##*[![:space:]]}"}"
  [[ -z "$trimmed_prompt_command" ]] && PROMPT_COMMAND="yem_env" || PROMPT_COMMAND="${trimmed_prompt_command%\;};yem_env"
fi
yem_env
TIP
if you don't use zsh shell you can simplify it:
yem_env() {
  eval $(yem env)
}
trimmed_prompt_command="${PROMPT_COMMAND%"${PROMPT_COMMAND##*[![:space:]]}"}"
[[ -z "$trimmed_prompt_command" ]] && PROMPT_COMMAND="yem_env" || PROMPT_COMMAND="${trimmed_prompt_command%\;};yem_env"
yem_env
TIP

it is also recommended to set some default versions in ~/.yupiik/yem/rc