forthebadge forthebadge Gem Version

This gem was last updated on the 10.11.2023 (dd.mm.yyyy notation), at 15:59:10 o’clock.

The directory_paradise gem - an introduction

The directory_paradise gem originated from the older directory_content gem.

I got tired of trying to fix bugs derived from the old code base, though, so I decided to just start a new project altogether, while re-using the parts of the code that works.

As I gained a bit of experience, I decided to adapt the old approach. This will be mentioned at a later time in this document.

This small gem may be useful whenever you wish to display the content of a (local) directory, similar to how the linux/unix program called ls operates.

I needed a variant of ls for my ruby-shell (the roebe-shell), so this project here was created years ago. Unfortunately over the years I changed parts of the code, without properly designing it, leading to quite some confusion as to what the project really should do, and how it should achieve this.

Thus, this README here shall not only explain the use cases of the project as such, but document a few internal decisions as well, including the rationale behind having made that decision.

That way we can use the documentation as some form of specification as well, and check to see that the code adheres to this specification. This may be helpful in the future, because I already rewrote this project several times before already.

There are now two main classes for the directory_paradise project:

(1) class Report, which will be in the report/ subdirectory.

This class will be responsible for displaying the content of a directory to the user.

(2) class Content which will reside in the content/ directory.

This class will be responsible for obtaining all the necessary information to provide data to class Report. It may no longer report anything to the user, except for debug output when we test or modify it.

Hopefully these design choices will make it easier to maintain the code base. In the past the old class that was similar to class Content also displayed some information, which led to code duplication and confusion, aka where to put new code in.

Furthermore, a new class called Base will now exist that can be used to share code between these two classes, such return_pwd (which is similar to Dir.pwd, but always ensures that a trailing / will be there).

class Content

This is the main class of module DirectoryParadise. It will not report anything to the user, but it will parse the entries in a given directory and store these entries in a hash that is available via .entries?.

The method .entries? will return which entries (files, directories or symlinks) were found in the given directory.

The method .n_entries? will return a number, indicating how many such entries could be found.

The method .obtain_entries_from() can be used to fill up the entries. If you also want to change the target directory, make use of the method .set_target_directory().

The method .report() can be used to report the content. It is, however had, not called by default for class DirectoryContent. Note that another class, called ShowDirectoryContent, is the one that is more apt and adjusted to displaying content.

This class is the one that should be used when you wish to display the content of a directory. It will make use of class DirectoryContent, so there is a separation-of-concern.

Note that you could also use class DirectoryContent to display content too, via the .report() method - but this is mostly just as a way to quickly debug something. For a more advanced display of files and directories, use class DirectoryContent::ShowDirectoryContent as it has been created precisely for that use case.

Specification for class Content - the individual entries explained

Essentially class Content has a hash that describes the content of a directory. This subsection will explain some of the entries that can be found in that hash, and thus may serve as some kind of specification.

First, the path to the file or directory at hand will be the main key. So, for example, if you have an archive called Images.tar.xz at the directory /Depot/, then the key to the description of that entry will be /Depot/Images.tar.xz. That way we always know where class DirectoryContent ‘points’ at.

Now knowing this key, let’s have a look at the individual entries:

:type=>"file"                       # keep track of the file type, e. g. file, directory or link.
:size=>47626780                     # we want to know the file size too, so that we don't have to call any other method querying this again.
:is_executable=>false               # is our file executable? Typically entries in /usr/bin/ will be executables
:path=>"/Depot/Images.tar.xz"       # here we store the path again, to simplify querying the path.
:ascii_representation=>"-rw-r--r--" # This is mostly used to keep compatibility to GNU coreutils "ls"
:last_modified=>2021-03-09 01:20:09.432056708 +0000 # Keep track as to when this entry was last modified.
:gid=>0                             # group id
:inode_number=>93857180             # its inode number
:uid=>0                             # user id
:access_mode=>"644"                 # access mode
:name_of_owner=>"root"              # name of the current owner of that entry
:name_of_group=>"root"              # name of the current group of that entry

If a missing symlink (that is, the target to which this symlink points to does not exist) is encountered, then class ShowDirectoryContent will either ignore this, or display to the user that a symlink is missing. Additionally it may stop altogether when a missing symlink is discovered. That way the user is sort of forced to fix this issue - I needed this once on GoboLinux, which is why this functionality had to exist.

This is handled internally via the method call stop_on_missing_symlink?.

The next subsection deals with class DirectoryParadise::Report, which is the main class when you wish to display the content of a directory.

Display only directory in the current working directory

If you only wish to display all directories in the current working directory then you can use the method called .only_directories, or, from the commandline:

sdc --only-directories

Do not show the header

By default, class DirectoryParadise::Report will show a header on top, to explain some of the options.

This may not always be wanted, so a commandline option exists to NOT show the header.

Example for this:

sdc --noheader
sdc --no-header

This is more similar to how “ls” works by default too, by the way.

Show hidden files

This should show hidden files aka those with a leading ‘.’:

sdc --show

Several aliases exist to this. Have a look at menu.rb to see all aliases to it, at directory_paradise/report/menu.rb.

Customising colours via the yaml file called colours_for_bytes_values.yml

You can customize the existing colours for KB, MB and GB values, via the yaml file called colours_for_bytes_values.yml. Currently only a few colours are supported, though. This may be extended one day, if people want to use other colours by default for the KB, MB and GB entries.

Since as of January 2022 the code will also check whether the colour names are correct. I had a typo called mediumpurples which did not exist, leading to another project break. This is bad, so now the directory_paradise gem will verify whether the colours exist or not.

Contact information and mandatory 2FA coming up in 2022

If your creative mind has ideas and specific suggestions to make this gem more useful in general, feel free to drop me an email at any time, via:

shevy@inbox.lt

Before that email I used an email account at Google gmail, but in 2021 I decided to slowly abandon gmail, for various reasons. In order to limit the explanation here, allow me to just briefly state that I do not feel as if I want to promote any Google service anymore when the user becomes the end product (such as via data collection by upstream services, including other proxy-services). My feeling is that this is a hugely flawed business model to begin with, and I no longer wish to support this in any way, even if only indirectly so, such as by using services of companies that try to promote this flawed model.

In regards to responding to emails: please keep in mind that responding may take some time, depending on the amount of work I may have at that moment. So it is not that emails are ignored; it is more that I have not (yet) found the time to read and reply. This means there may be a delay of days, weeks and in some instances also months. There is, unfortunately, not much I can do when I need to prioritise my time investment, but I try to consider all feedback as an opportunity to improve my projects nonetheless.

In 2022 rubygems.org decided to make 2FA mandatory for every gem owner eventually:

see https://blog.rubygems.org/2022/06/13/making-packages-more-secure.html

Mandatory 2FA will eventually be extended to all rubygems.org developers and maintainers. As I can not use 2FA, for reasons I will skip explaining here, this means that my projects will eventually be removed, as I no longer have any control over my projects hosted on rubygems.org (because I can not use 2FA).

At that point, I no longer have any control what is done to my projects since whoever is controlling the gems ecosystem took away our control here. I am not sure at which point ruby became corporate-controlled - that was not the case several years ago, so something has changed.

Ruby also only allows 2FA users to participate on the issue tracker these days:

https://bugs.ruby-lang.org/issues/18800

But this has been reverted some months ago, so it is no longer applicable. Suffice to say that I do not think that we should only be allowed to interact on the world wide web when some ‘authority’ authenticated us, such as via mandatory 2FA, so I hope this won’t come back again.

Fighting spam is a noble goal, but when it also means you lock out real human people then this is definitely NOT a good situation to be had.