Day 5: Raku & Pakku

A hobby

One day I woke and decided I want to learn programming as a hobby. For someone who doesn’t know much about the subject other than writing a few Bash scripts, words like Functional Programming, Object Oriented or even the word class by itself were mysterious.

Lost

Doing my research to find out where to start, very soon I was lost in tons of information available online, but I wanted to start learning anyway, and it is time to pick a programming language.

There are so many programming languages out there, deciding which language to learn was a difficult task for me, mainly because comparing languages based on technical knowledge was not an option.

A naive plan, but worked!

I decided to read as much code from different languages as I could trying to solve the same problem and take notes of which code is easy to reason about, what I like and what I don’t like. Rosetta Code made it easy to compare different languages solutions for same the problem.

butterfly

I started looking at code there, going down the list reading code from different languages without paying attention to the language name, just focusing on the code. All looks fine, most code looked similar in one way or another to me.

Deep down the list, I noticed code that at first sight looked weird. “What is that!” I asked myself. Staring for a few seconds, a second look and the code doesn’t look weird anymore, but now looks strange! “What are these colons and arrows doing!” I asked myself again. A third look at the code and somehow the code looked familiar, then beautiful and easy to follow (even without knowing what colons or arrows do). I was curious to know the name of that language; It was Raku! (Actually Perl6 at that time :-))

This pattern repeated with solutions to different problems, most languages looked similar in one way or another; it was only Raku code that stood out to me in a nice and attractive way. So I decided to learn Raku, and went ahead with reading Learn Raku in Y Minutes and the documentation.

Pakku

-Ofun

Enjoying what I learned so far with Raku, I wanted to write a package manager for fun and learning. Writing a package manager can be challenging for someone new to programming like me, but I started anyway knowing it will be fun. At the end of the day Raku is -Ofun!

I looked at the Panda and Zef package managers to learn what a package manager for Raku would entail. Panda was simple and easy to understand but also was deprecated (panda has been considered obsolete for some time now). Zef looked updated and complete features-wise but wasn’t easy to follow for me. Checking Panda and Zef gave me an idea what I need to do.

Know Pakku

A package manager for Raku, Designed with simplicity in mind.

Camelia

I wanted Pakku to be Simple, Fast, Light and Colorful like Camelia – the Raku mascot.

–hyphen

To me running commands is like communicating to a program, so I wanted the commands sent to a program be as close as possible to sentences people use to communicate with each other, no hyphens, no double hyphens…

For example instead of writing:

program delete --from=somewhere --recurse dirname

I can write:

program delete from somewhere recurse dirname

and program should take care of identifying commands, sub-commands, options of sub-commands; and also DWIM, for example if dirname above is replaced with recurse, program should parse the first recurse as an option and the last as the directory to be deleted and cover other corner cases.

I wouldn’t be able to achieve that using Raku’s MAIN command line arguments; fortunately Raku’s Grammar made that easy.

These are examples of Pakku commands:

pakku add to site MyModule    
pakku list repo site details
pakku pretty please dont remove from home MyModule

Pipeline

Pakku commands are processed in an easy to follow way, like stages in a pipeline.

Lets examine how Pakku installs a module:

Stage 1

1- Pakku receives the module(s) spec to be installed (module name or local path)

2- Check if the specified module is installed (satisfied) already or needs to force install

3- Try to satisfy the spec, this means obtain the meta info for the module and dependencies if needed, in the correct order to install

@spec

  ==> map( -> $spec { Spec.new: $spec } )

  ==> grep( -> $spec { $force or not self.satisfied: :$spec } )

  ==> map( -> $spec { self.satisfy: :$spec } )

  ==> map( -> $dep {

    my @dep = self.get-deps( $dep, :$deps );

    @dep.append: $dep unless $deps ~~ <only>;

    @dep;

  } )
  ...
  ...
  ==> my @meta;

Stage 2

1- Download the distribution archive and extract it

2- Prepare the fetched distribution directory to be installed by CompUnit::Repository::Installation

@meta

    ==> map( -> $meta {

      my $prefix = $!fetcher.fetch: $meta.recman-src;
    
      $meta.to-dist: :$prefix;

    } )

    ==> my @dist;

Stage 3

1- Build the distribution, if needed

2- Test the distribution, if needed

3- Add the distribution

  @dist 

    ==> map( -> $dist {
  
      $!builder.build: :$dist if $build;

      $!tester.test:   :$dist if $test;
  
      $*repo.add: :$dist, :$force     unless $!dont;

      πŸ¦‹ "ADD: ο½’$distο½£" unless $!dont;
  
    } );

You may have noticed that I used ==> feed operator (which takes the result from the left and passes it to the next (right) routine as the last parameter) quite a few times. The reason I used it is because it fits well in this pipeline analogy.

Pakku Output

Pakku logs on 7 levels

  • 0 (silent) – No output what so ever
  • 1 (trace) nerd_face – If you want to see everything
  • 2 (debug) beetle – To debug some issue
  • 3 (info ) butterfly – Camelia delivers important things
  • 4 (warn ) bell – Only when some warnings happen
  • 5 (error) x – When errors are what you care about!
  • 6 (fatal) skull – You probably don’t like to see that when running Pakku, me neither!

Log symbols and messages colors can be changed and customized in the pakku.cnf file.

Sample log messages you may see and their meaning:

πŸ¦‹ PRC: ο½’ ... ο½£ β†’ Start processing...
🐞 SPC: ο½’ ... ο½£ β†’ Processing spec
🐞 MTA: ο½’ ... ο½£ β†’ Processing meta
πŸ€“ FTC: ο½’ ... ο½£ β†’ Fetch URL
🐞 BLD: ο½’ ... ο½£ β†’ Start building dist
πŸ¦‹ BLT: ο½’ ... ο½£ β†’ Built dist successfully
🐞 TST: ο½’ ... ο½£ β†’ Start testing dist
πŸ¦‹ TST: ο½’ ... ο½£ β†’ Tested dist successfully
πŸ¦‹ ADD: ο½’ ... ο½£ β†’ Added dist successfully
πŸ’€ MTA: ο½’ ... ο½£ β†’ No valid meta obtained for spec
πŸ’€ BLD: ο½’ ... ο½£ β†’ Bulding dist failed
πŸ’€ TST: ο½’ ... ο½£ β†’ Testing dist failed
πŸ’€ CNF: ο½’ ... ο½£ β†’ Config file error
πŸ’€ CMD: ο½’ ... ο½£ β†’ Could not understand command

Time Machine (WIP)

Pakku timemachine figured out how to time travel not only to the future but also to the past!

Pakku timemachine can save the current state of Raku repositories, store a list
of installed distributions per repo, and can go back to this state any time
when needed (for example after reinstalling Raku)

This is still a work in progress, however by the time you are reading this, this feature may be ready.

# list available events
pakku timemachine

# save the current repos state to event name "xmas"
pakku timemachine event xmas

# restore the repo state (by removing or adding distributions) 
pakku timemachine travel yesterday
pakku timemachine travel 12012020

Screenshot

List details of a distribution

list-details1

Try Pakku

Pakku currently runs on Linux (more operating systems will be supported in the future), give it a try you may like it πŸ™‚

Thanks

Thanks for reading. Have -Ofun using Raku!

2 thoughts on “Day 5: Raku & Pakku

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: