- Two different repositories being queried at once
- The same one being queried twice, at different depths
- Tests for --tree and --recurse that should break in the future when that’s implemented
- Also just more tests in general
This adds support for the EXA_COLORS environment variable, and defines a bunch of exa-specific two-letter codes that I pretty much made up arbitrarily that control parts of the interface.
Fixes#160, which I didn’t expect to actually fix this release cycle, but it unexpectedly became easy to do!
This commit meddles about with both the Colours and the FileExtensions.
Even though all the renderable fields were turned into traits, the FileName struct kept on accessing fields directly on the Colours value instead of calling methods on it. It also did the usual amount of colour misappropriation (such as ‘punctuation’ instead of specifying ‘normal_arrow’)
In preparation for when custom file colours are configurable (any day now), the colourise-file-by-kind functionality (links, sockets, or directories) was separated from the colourise-file-by-name functionality (images, videos, archives). The FileStyle struct already allowed for both to be separate; it was only changed so that a type other than FileExtensions could be used instead, as long as it implements the FileColours trait. (I feel like I should re-visit the naming of all these at some point in the future)
The decision to separate the two means that FileExtensions is the one assigning the colours, rather than going through the fields on a Colours value, which have all been removed. This is why a bunch of arbitrary Styles now exist in filetype.rs.
Because the decision on which colourise-file-by-name code to use (currently just the standard extensions, or nothing if we aren’t colourising) is now determined by the Colours type (instead of being derived), it’s possible to get it wrong. And wrong it was! There was a bug where file names were colourised even though the rest of the --long output wasn’t, and this wasn’t caught by the xtests. It is now.
Every time I had to build exa, I copied the files manually and checked to make sure they all had the same name. There’s now a script that does all that stuff for me, so I don’t need to remember to do it anymore.
It also does some things that weren’t being done before, including stripping the binary and listing its linked dependencies to we can tell if something like libhttp_parser has slipped in there (see #194)
This was touched on in #209 where I got the docs wrong compared to the actual implementation, but after thinking about it, I’d like to switch it round. (The --sort=Name and --sort=name difference has also been switched.) See the big ol’ comment for my reasons.
Because this changes core functionality, it broke many, many tests. You can see that this doesn’t change the -star- tests because the shell, rather than exa, orders the globbed files.
I kept on forgetting which way round Sensitive and Insensitive went, so I named them after the effect they have.
The Debug impl was being used instead of the Display one. Also, remove the full stops from the ends of all the error messages because I’ve decided it looks weird.
exa now ignores errors when checking for extended attributes when the user didn’t explicitly demand that they be checked. If a file does have xattrs, it’ll still display the @ in the permissions column; errors will now just cause the @ to be hidden instead.
This changed a lot of the xtests, which were displaying the error message in a few situations. Those tests have gained @-suffixed companions so the actual error messages can still be tested.
Fixes#178 (finally)
It’s a good test to be able to switch strict mode on in run.sh and not have it break anything! Now, the EXA_STRICT environment variable will toggle it on. We can even switch it off and see that it doesn’t error.
This commit modifies a specific file timestamp so we test both July (which is 5 characters in French) and December (which is 4 characters in Japanese). It’s also kind of a test for locales as well.
This commit removes the dependency on the ‘getopts’ crate entirely, and re-writes all its uses to use the new options parser instead.
As expected there are casualties galore:
- We now need to collect the options into a vector at the start, so we can use references to them, knowing they’ll be stored *somewhere*.
- Because OsString isn’t Display, its Debug impl gets used instead. (This is hopefully temporary)
- Options that take values (such as ‘sort’ or ‘time-style’) now parse those values with ‘to_string_lossy’. The ‘lossy’ part means “I’m at a loss for what to do here”
- Error messages got a lot worse, but “--tree --all --all” is now a special case of error rather than just another Misfire::Useless.
- Some tests had to be re-written to deal with the fact that the parser works with references.
- ParseError loses its lifetime and owns its contents, to avoid having to attach <'a> to Misfire.
- The parser now takes an iterator instead of a slice.
- OsStrings can’t be ‘match’ patterns, so the code devolves to using long Eq chains instead.
- Make a change to the xtest that assumed an input argument with invalid UTF-8 in was always an error to stderr, when that now in fact works!
- Fix a bug in Vagrant where ‘exa’ and ‘rexa’ didn’t properly escape filenames with spaces in.
There was a bug where if you tried to recurse into a directory you didn’t have permission to read the contents of, the error would be ignored.
It now displays the errors.
It now tests a lot more combinations of xattrs on files, as well as xattrs and files and errors as the children of directories.
The recent code changes have touched the part where directories’ xattrs and children are displayed at the same tree level, and there weren’t enough tests for this.
This is going to be used to test time formatting.
Casualty here is that the “have you not ran the provisioning script in a year?” checker complained about there being files more than a year old, so that now has to ignore the times directory.
This isn’t perfect, as a file’s type isn’t cached, so it gets recomputed for every comparison in the sort! We can’t go off the file’s `st_mode` flag because it’s not guaranteed to be in any order between systems.
There was a problem when displaying . and .. in directory listings: their names would normalise to actual names! So instead of literally seeing `.`, you’d see the current directory’s name, inserted in sort order into the list of results. Obviously this is not what we want.
In unrelated news, putting `.` and `..` into the list of paths read from a directory just takes up more heap space for something that’s basically constant.
We can solve both these problems at once by moving the DotFilter to the files iterator in Dir, rather than at the Dir’s creation. Having the iterator know whether it should display `.` and `..` means it can emit those files first, and because it knows what those files really represent, it can override their file names to actually be those sequences of dots.
This is not a perfect solution: the main casualty is that a File can now be constructed with a name, some metadata, both, or neither. This is currently handled with a bunch of Options, and returns IOResult even without doing any IO operations.
But at least all the tests pass!
exa assumed that the COLUMNS environment variable being present always meant that the output was to a terminal, so it should use colours. But because this variable can be overridden, colours were being incorrectly set!
The ‘fix’ is to stop trying to be clever while only calculating the terminal width once, and instead just stick it in a lazy_static so it’s usable everywhere.
Finally, re-do the permissions extended tests to include the setuid, setgid, and sticky bits, and rename the last two existing ones to match the others (files with the same names as their permissions).
Override the size column for block and charater devices, so it shows the major and minor device IDs instead (which are in the Metadata struct somewhere).
This is what ls does when faced with a device.
By parsing OsStrings rather than Strings, it’s the getopts crate that’s doing the UTF-8 checking rather than us, so if one of them isn’t valid, it’ll just fail to parse rather than crash exa.
Also, save a few allocations here and there.
Fixes#134, a bug that showed symlinks incorrectly as broken, but only when the file was listed directly on the command-line *and* the file was in a different directory to the one exa was being run in.
I’m not sure why the old code used `String::new()`, but it doesn’t seem to affect anything.
Because the link style and status are now both available to the function that picks the colour style, we can have it highlight broken links differently.
Fixes#131.
For some reason, the code that calculated the width of a cell with a path in counted the width of the path twice: once from the ANSIStrings containing it, and once more added on afterwards. This meant that the grid view thought that columns were wider than they really were, meaning fewer could be fit into a grid.
Doing this meant that the escaping functionality got used in three places, so it was extracted into a generalised function in its own module.
This is slighly slower for the case where escaped characters are displayed in the same colour as the displayable characters, which happens when listing a directory’s name when recursing. Optimise this, yeah?
Rather than the *entire* file name.
The current method is extremely inefficient, but having control characters in file names is also extremely uncommon; it’s something that should be fixed, only eventually.
It's confusing, and `ls` doesn't do this either. We're not prepending
the current path to all of the directory entries, and the user is going
to interpret the symlink target as relative to the directory containing
the symlink.
It’s the only file where its path is the same as its file name, and has been the source of numerous bugs in the past… this special-case isn’t very clean, but it works.
I think I took this off to see how the output was different. Which means there should really be a better way to check how the output is different, other than running the command and looking!
This name more accurately reflects which code is being tested (things like .png and Makefile, rather than pipes and sockets), freeing up file-types for *actual* file types to be tested.
The Vagrant tests assumed that there’d be a user called “vagrant” that would run the tests and create the files by default. Files would be owned by vagrant:vagrant by default, and this worked, until it came time to change that username. The naïve method was a search-and-replace, but this caused problems when the new user’s name wasn’t exactly the same length as the previous one.
So to fix this, we now have our own user, named after the first animal I thought of, that makes the files’ owners and groups independent of the default user of whichever VM image the xtests are running on.
Another place where it was hard-coded was the home directory, which was “/home/vagrant”, where the awkward testcases live. That last one has been changed to just “/testcases”, which has no mention of the user in it.
There was a problem with the Vagrant tests where the year 2016 was hard-coded in as the modified date. This had to be done to make the --long tests use the correct date format, which varies depending on whether the timestamp is in the current year.
Unfortunately, time progresses [citation needed], and what was once 2016 is now 2017, so the date format changed and the tests broke.
Because the Vagrantfile is just a Ruby script, we can look up the current year at runtime and use that instead. There’s also a check added to the test runner that makes sure none of the files are more than 365 days old, because if any are, then it’s time to update the timestamps (or it’s the last day of a leap year)
See #97 and recently #130 too.
This allows the user to pass in options such as "--ignore '*.pyc'" to not list any files ending in '.pyc' in the output. It uses the Rust glob crate and currently does a simple split on pipe, without any escaping, so it’s not really *complete*, but is at least something.
Fixes#123. The code assumes that every File that has its link_target() method called would first have been checked to make sure it’s actually a link first. Unfortunately it also assumed that the only thing that can go wrong while following a link is if the file wasn’t a link, meaning it crashes when given a link it doesn’t have permission to follow.
This makes the file_target() method able to return either a file or path for displaying, as before, but also an IO error for when things go wrong.
This changes the way that views are used to display the actual lists of files. It used to pass empty vectors to the view methods, which most of the time would not print anything because there are no files to list — except when there’s a header row which gets printed for no files.
By not calling the view method at all when there’s nothing to print, exa won’t ever print extra things in the view unless it needs to for a file.
This fixes#106 “Don’t print the header if the result set is empty”
See the README section for more details. Basically, with this way, we can store a bunch of existing valid exa outputs, change a VM's environment to match our values, then check that exa still works by comparing outputs.