txt: ## dist_zef-hythm-Pakku.md
  [![Linux](https://github.com/hythm7/Pakku/actions/workflows/linux.yml/badge.svg)](https://github.com/hythm7/Pakku/actions/workflows/linux.yml)
  [![macOS](https://github.com/hythm7/Pakku/actions/workflows/mac.yml/badge.svg)](https://github.com/hythm7/Pakku/actions/workflows/mac.yml)
  [![Windows](https://github.com/hythm7/Pakku/actions/workflows/windows.yml/badge.svg)](https://github.com/hythm7/Pakku/actions/workflows/windows.yml)
  
  [![SparrowCI](https://ci.sparrowhub.io/project/git-hythm7-Pakku/badge?foo=bar)](https://ci.sparrowhub.io)
  
  # Pakku
  
  Package Manager for the Raku Programming Language.
  
  # Installation
  
  ```
  
  # Install
  git clone https://github.com/hythm7/Pakku.git
  cd Pakku
  raku -I. bin/pakku add .
  
  # Install using Zef
  zef install Pakku
  
  ```
  
  # Usage
  
  Pakku manages Raku distributions with commands like `add`, `remove`, `update` etc.
  
  Full command consists of:
  
  `pakku [general-options] <command> [command-options] <dists>`
  
  There are two types of options:
  
  **General options:**
  
  These are the options that control the general behavior of Pakku, eg. specify the configuration file, run asynchronously or disable colors. The general options are valid for all commands, and must be placed before the command.
  
  **Command options:**
  
  These are the options that control the specified command, for example when installing a distributions one can add `notest` option to disable testing. these options must be placed after the command.
  
  ## Pakku Commands
  
  ### add
  
  Install distributions
  
  **options:**
  
  ```
  
  deps                → all dependencies
  deps    < build >   → build dependencies only
  deps    < test >    → test dependencies only
  deps    < runtime > → runtime dependencies only
  deps    < only >    → install dependencies but not the dist
  exclude < Spec >    → exclude Spec
  test                → test distribution
  xtest               → xTest distribution
  build               → build distribution
  serial              → add distributions in serial order
  contained           → add distributions and all transitive deps (regardless if they are installed)
  precomp             → precompile distribution 
  to < repo >         → add distribution to repo < home site vendor core /path/to/MyApp >
  nodeps              → no dependencies
  nobuild             → bypass build
  notest              → bypass test
  noxtest             → bypass xtest
  noserial            → no serial
  noprecomp           → no precompile
  
  ```
  
  **Examples:**
  
  ```
  
  pakku add dist                           # add dist
  pakku add notest  dist                   # add dist without testing
  pakku add nodeps  dist                   # add dist but dont add dependencies
  pakku add serial  dist                   # add dists in serial order
  pakku add deps only dist                 # add dist dependencies but dont add dist
  pakku add exclude Dep1 dist              # add dist and exclude Dep1 from dependenncies
  pakku add noprecomp notest  dist         # add dist without testing and no precompilation
  pakku add contained to   /opt/MyApp dist # add dist and all transitive deps to custom repo
  pakku add to   vendor     dist1 dist2    # add dist1 and dist2 to vendor repo even if they are installed
  
  ```
  
  ### remove
  
  Remove distributions
  
  **options:**
  
  ```
  
  from < repo > → remove distribution from provided repo only
  
  ```
  
  **Examples:**
  
  ```
  
  pakku remove dist            # remove dist from all repos
  pakku remove from site dist  # remove dist from site repo only
  
  ```
  
  ### list
  
  List installed distributions
  
  **options:**
  
  ```
  
  details               → details
  repo < name-or-path > → list specific repo
  
  ```
  
  **Examples:**
  
  ```
  
  pakku list                         # list all installed dists
  pakku list dist                    # list installed dist
  pakku list details dist            # list installed dist details
  pakku list repo home               # list all dists installed to home repo
  pakku list repo /opt/MyApp dist    # list installed dist in custom repo
  
  ```
  
  ### search
  
  Search available distributions
  
  **options:**
  
  ```
  
  latest           → latest version
  relaxed          → relaxed search
  details          → details of dist
  count < number > → number of dists to be returned
  norelaxed        → no relaxed search
  
  ```
  
  **Examples:**
  
  ```
  
  pakku search dist               # search distributions matching dist (ignored case) on online recman
  pakku search latest dist        # show latest version
  pakku search norelaxed dist     # no relaxed search
  pakku search count 4 dist       # search dist and return the lates 4 versions only
  pakku search details dist       # search dist and list all details
  
  ```
  
  ### build
  
  Build distributions
  
  **Examples:**
  
  ```
  
  pakku build dist
  pakku build .
  
  ```
  
  ### test
  
  Test distributions
  
  **options:**
  
  ```
  
  xtest   → XTest distribution
  build   → Build distribution
  noxtest → Bypass xtest
  nobuild → Bypass build
  
  ```
  
  **Examples:**
  
  ```
  
  pakku test dist
  pakku test ./dist
  pakku test xtest ./dist
  pakku test nobuild ./dist
  
  ```
  
  ### update
  
  Update distributions to latest version
  
  **options:**
  
  ```
  
  clean        → clean not needed dists after update 
  deps         → update dependencies
  nodeps       → no dependencies
  exclude Dep1 → exclude Dep1
  deps only    → dependencies only
  build        → build distribution
  nobuild      → bypass build
  test         → test distribution
  notest       → bypass test
  xtest        → xTest distribution
  noxtest      → bypass xtest
  precomp      → precompile distribution 
  noprecomp    → no precompile
  noclean      → dont clean unneeded dists 
  in < repo >  → update distribution and install in repo < home site vendor core /path/to/MyApp >
  
  ```
  
  **Examples:**
  
  ```
  
  pakku update       # update all installed distribution
  pakku update dist
  pakku update nodeps dist
  pakku update notest dist1 dist2
  
  ```
  
  ### state
  
  Check the state of installed distributions
  
  **options:**
  
  ```
  
  updates   → check updates for dists
  clean     → clean older versions of dists
  noupdates → dont check updates for dists
  noclean   → dont clean older versions
  
  ```
  
  **Examples:**
  
  ```
  
  pakku state
  pakku state dist
  pakku state clean  dist
  pakku state noupdates  dist
  
  ```
  
  ### download
  
  Download distribution source
  
  **Examples:**
  
  ```
  
  pakku download dist     # download dist and extract to temp directory
  
  ```
  
  ### nuke
  
  Nuke directories
  
  **Examples:**
  
  ```
  
  pakku nuke cache    # nuke cache 
  pakku nuke pakku    # nuke pakku home directory
  pakku nuke home     # nuke home repo
  pakku nuke site     # nuke site repo
  pakku nuke vendor   # nuke vendor repo
  
  ```
  
  ### config
  
  Each Pakku command like `add`, `remove`, `search` etc. corresponds to a config module with the same name in the config file.
  one can use config command to `enable`, `disable`, `set`, `unset` an option in the config file.
  
  **options:**
  
  ```
  
  enable        → enable option
  disable       → disable option
  set < value > → set option to value 
  unset         → unset option
  
  ```
  
  **Examples:**
  
  ```
  
  pakku config                             # view all config modules
  pakku config new                         # create a new config file
  pakku config add                         # view add config module
  pakku config add precompile              # view precompile option in add config module
  pakku config add enable xtest            # enable option xtest in add module 
  pakku config add set to home             # set option to to home (change default repo to home) in add module 
  pakku config pakku enable async          # enable  option async in pakku module (general options) 
  pakku config pakku unset verbose         # unset option verbose in pakku module 
  pakku config recman MyRec disable        # disable recman named MyRec in recman module
  pakku config recman MyRec set priority 1 # set recman MyRec's priority to 1 in recman module
  pakku config add reset                   # reset add config module to default
  pakku config reset                       # reset all config modules to default
  
  ```
  
  ### help
  
  Get help on a specific command
  
  **Examples:**
  
  ```
  
  pakku
  pakku help add
  pakku help list
  pakku help remove
  pakku add
  pakku help
  pakku help help
  
  ```
  
  ## Pakku General Options
  
  **Options:**
  
  ```
  
  pretty              → use colors
  force               → use force
  async               → run asynchronously (disabled by default because some dists tests are not async safe) 
  dont                → do everything but dont do it (dry run)
  bar                 → use progress bar
  spinner             → use spinner
  verbose  < level >  → verbosity < nothing error warn info now debug all >
  cores    < number > → number of cores used when run in async mode
  config   < path >   → specify config file
  recman              → enable all remote recommendation manager
  recman   < MyRec >  → use MyRec recommendation manager only
  norecman            → disable all remote recommendation manager
  norecman < MyRec >  → use all recommendation managers excepts MyRec
  nopretty            → no colors
  noforce             → no force
  nobar               → no progress bar
  nospinner           → no spinner
  noasync             → dont run asynchronously
  nocache             → disable cache
  yolo                → proceed if error occured (eg. test failure)
  please              → be nice to butterflies
  
  ```
  
  **Examples:**
  
  ```
  
  pakku async   add dist                # run in async mode while adding dist
  pakku nocache add dist                # dont use cache
  pakku dont    add dist                # dont add dist (dry run)
  pakku pretty  please remove dist
  
  ```
  
  ### Feeling Rakuish Today?
  
  Most of `Pakku` commands and options can be written in shorter form, for example:
  
  ```
  
  add    → a  update   → u  yolo     → y  nopretty → np  nothing → «N 0»
  remove → r  download → d  exclude  → x  nodeps   → nd  all     → «A 6»
  list   → l  help     → h  deps     → d  noforce  → nf  debug   → «D 5»
  search → s  verbose  → v  force    → f  notest   → nt  now     → «N 4»
  build  → b  pretty   → p  details  → d  nobuild  → nb  info    → «I 3»
  test   → t  only     → o  norecman → nr nocache  → nc  warn    → «W 2»
  									     
  
  ```
  
  The below are `Pakku` commands as well!
  
  ```
  
  pakku 👓 🧚 ↓   dist
  pakku ↪
  pakku ❓
  
  ```
  
  ## ENV Options
  
  Options can be set via environment variables as well:
  
  **General**
  
  ```
  
  PAKKU_VERBOSE PAKKU_CACHE PAKKU_RECMAN PAKKU_NORECMAN PAKKU_CONFIG PAKKU_DONT
  PAKKU_FORCE PAKKU_PRETTY PAKKU_BAR PAKKU_SPINNER PAKKU_ASYNC PAKKU_CORES PAKKU_YOLO 
  
  ```
  
  **Add**
  
  ```
  
  PAKKU_ADD_TO PAKKU_ADD_DEPS PAKKU_ADD_TEST PAKKU_ADD_BUILD PAKKU_ADD_XTEST
  PAKKU_ADD_SERIAL PAKKU_ADD_PRECOMPILE PAKKU_ADD_EXCLUDE
  
  ```
  
  **Test**
  
  ```
  
  PAKKU_TEST_BUILD PAKKU_TEST_XTEST
  
  ```
  
  **Remove**
  
  ```
  
  PAKKU_REMOVE_FROM
  
  ```
  
  **List**
  
  ```
  
  PAKKU_LIST_REPO PAKKU_LIST_DETAILS
  
  ```
  
  **Search**
  
  ```
  
  PAKKU_SEARCH_LATEST PAKKU_SEARCH_DETAILS PAKKU_SEARCH_RELAXED PAKKU_SEARCH_COUNT 
  
  ```
  
  **Update**
  
  ```
  
  PAKKU_UPDATE_IN PAKKU_UPDATE_DEPS PAKKU_UPDATE_TEST PAKKU_UPDATE_XTEST PAKKU_UPDATE_BUILD
  PAKKU_UPDATE_CLEAN PAKKU_UPDATE_PRECOMPILE PAKKU_UPDATE_EXCLUDE
  
  ```
  
  **State**
  
  ```
  
  PAKKU_STATE_CLEAN> PAKKU_STATE_UPDATES
  
  ```
  
  # Pakku Output
  
  Pakku output aims to be tidy and concise, uses emojis, colors and three letters key words to convey messages.
  
  For example, the `🦋` emoji indicates that Pakku is starting a task, while `🧚` means Pakku successfully completed a task.
  
  An output line like:
  
  `🦋 BLD: ｢Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>｣`
  
  means Pakku is starting to build `Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>`, and based on the result another output line could be:
  
  `🧚 BLD: ｢Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>｣` # build success
  
  `🦗 BLD: ｢Inline::Perl5:ver<0.60>:auth<cpan:NINE>:api<>｣` # build failure
  
  Below is a list of output lines that one can see and their meaning:
  
  ```
  🧚 ADD → start add command
  🦋 SPC → processing Spec
  🦋 MTA → processing Meta
  🦋 FTC → fetching
  🦋 BLD → building
  🦋 STG → staging
  🦋 TST → testing
  🧚 BLD → build success
  🧚 TST → test success
  🧚 BIN → binary added
  🐞 WAI → waiting
  🐞 TOT → timed out
  🦗 SPC → error processing Spec
  🦗 MTA → error processing Meta
  🦗 BLD → build failure
  🦗 TST → test failure
  🦗 CNF → config error
  🦗 CMD → command error
  
  ```
  
  **Pakku verbosity levels:**
  
  ```
  - 1 `｢ all ｣`   🐝 → All avaialble output
  - 2 `｢debug｣`   🐛 → Debug output
  - 3 `｢ now ｣`   🦋 → What is happenning now
  - 4 `｢info ｣`   🧚 → Important things only
  - 5 `｢warn ｣`   🐞 → Warnings only
  - 6 `｢error｣`   🦗 → Errors only
  - 0 `｢nothing｣`    → Nothing
  
  ```
  
  > [!WARNING]
  > Pakku uses emoji and ANSI escape codes, If your terminal doesn't support them, you can disable colors, bars and spinners, (eg. `pakku nopretty nobar nospinner add Foo`), or disable permanently in config file. also for emojis, eg. to change the `debug` emoji for example, in config file replace `"debug": {"prefix": "🐛"}` with `"debug": {"prefix": "D"}`.
  
  **Command result**:
  
  * `-Ofun` - Success
  * `Nofun` - Failure
  
  # Gotchas
  
  **Caching downloaded distributions**
  
  When one installs a distribution via `pakku add dist`, Pakku first looks in the local cache to see if there is a downloaded distribution matches `dist` specification, if nothing found in the cache, Pakku then searches the configured `RecMan` and obtain the latest version of `dist` (e.g. `dist:ver<0.4.1>`), download, cache, and install it.
  
  After sometime when a new version `dist:ver<0.4.2>` is released and available in `RecMan`, if one try to install `dist` via `pakku add dist`, what happens is Pakku will find `dist:ver<0.4.1>` available in local cache and will install that version because it matches `dist` specification. so one will not get the latest version `dist:ver<0.4.2>`.
  
  There are two ways to avoid this and get the latest version, either specify the version e.g. `pakku add dist:ver<0.4.2>` or disable cache lookup e.g. `pakku nocache add dist` (also, one can permenantly disable cache in config file).
  
  **Pakku installs to *site* repo by default**
  
  If the user doesn't have `rw` permision to `site` repo, one can change the default repo to `home` in config file using:
  
  `pakku config add set to home`
  
  or specify the repo in the command e.g. `pakku add to home dist`
  
  # Credits
  
  Thanks to `Panda` and `Zef` for `Pakku` inspiration.
  also Thanks to the nice `#raku` community.
  
  # Motto
  
  Light like a 🧚, Colorful like a 🧚
  
  # Author
  
  Haytham Elganiny `elganiny.haytham at gmail.com`
  
  # Copyright and License
  
  Copyright 2023 Haytham Elganiny
  
  This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.
  