Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nix flake show: add the description if it exists #10980

Merged
merged 9 commits into from
Aug 18, 2024

Conversation

kjeremy
Copy link
Contributor

@kjeremy kjeremy commented Jun 27, 2024

Motivation

Displays the description of the package if it exists. This information is already present in the json output.

I have a flake with many packages and dev shells and this helps discoverability.

Context

#10977

Priorities and Process

Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@kjeremy kjeremy requested a review from edolstra as a code owner June 27, 2024 19:42
@github-actions github-actions bot added the new-cli Relating to the "nix" command label Jun 27, 2024
@kjeremy
Copy link
Contributor Author

kjeremy commented Jul 1, 2024

This has been really helpful for my team. What do I need to do to get it merged?

@edolstra
Copy link
Member

edolstra commented Jul 1, 2024

The problem with showing descriptions in nix flake show is that they can be pretty long, which can break the tree output rendering (especially if they contain newlines).

@kjeremy
Copy link
Contributor Author

kjeremy commented Jul 1, 2024

@edolstra I can think of a few approaches:

  1. Strip newlines and maybe limit the length
  2. Fix the tree views to work with multiline output

I can tackle either one if I get some direction.

@kjeremy
Copy link
Contributor Author

kjeremy commented Jul 8, 2024

I've pushed a change to stop at the first new line

@kjeremy
Copy link
Contributor Author

kjeremy commented Jul 8, 2024

I'm not quite sure how to test the output. The tests in tests/functional/flakes/show.sh all depend on the json output but this needs to check stdout.

@cole-h
Copy link
Member

cole-h commented Jul 8, 2024

As a bystander, I think the following implementation might make the most sense:

  • Strip all whitespace from the beginning of the description until you get to a non-whitespace character
  • Read up to the next newline (if any)
  • If the resulting string is longer than, say, 100 characters, trim it to that and add an ellipsis at the end

I'm not quite sure how to test the output. The tests in tests/functional/flakes/show.sh all depend on the json output but this needs to check stdout.

You could try using <the command> | grepQuiet "what you're looking for", I think.

@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Jul 8, 2024
@kjeremy
Copy link
Contributor Author

kjeremy commented Jul 8, 2024

I chose 80 and added tests.

@kjeremy
Copy link
Contributor Author

kjeremy commented Jul 10, 2024

@edolstra is this a reasonable solution to the tree rendering?

src/nix/flake.cc Outdated Show resolved Hide resolved
@kjeremy kjeremy force-pushed the flake-show-description branch 2 times, most recently from 74da3f4 to 1cc808c Compare July 18, 2024 18:44
@kjeremy
Copy link
Contributor Author

kjeremy commented Jul 23, 2024

@Ericson2314 is there any thing I can do to move this along?

lf- pushed a commit to lix-project/lix that referenced this pull request Aug 2, 2024
(cherry picked from commit 8cd1d02f90eb9915e640c5d370d919fad9833c65)

nix flake show: Only print up to the first new line if it exists.

(cherry picked from commit 5281a44927bdb51bfe6e5de12262d815c98f6fe7)

add tests

(cherry picked from commit 74ae0fbdc70a5079a527fe143c4832d1357011f7)

Handle long strings, embedded new lines and empty descriptions

(cherry picked from commit 2ca7b3afdbbd983173a17fa0a822cf7623601367)

Account for total length of 80

(cherry picked from commit 1cc808c18cbaaf26aaae42bb1d7f7223f25dd364)

docs: add nix flake show description release note

fix: remove white space

nix flake show: trim length based on terminal size

test: account for terminal size

docs(flake-description): before and after commands; add myself to credits

Upstream-PR: NixOS/nix#10980
Change-Id: Ie1c667dc816b3dd81e65a1f5395e57ea48ee0362
@kjeremy kjeremy requested a review from fzakaria August 5, 2024 14:25
@kjeremy
Copy link
Contributor Author

kjeremy commented Aug 5, 2024

It looks like lix just merged this into their code base.

src/nix/flake.cc Outdated
name);
"package";
if (description && !description->empty()) {
// Trim the string and only display the first line of the description.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be done using filterANSIEscapes():

/**
 * Truncate a string to 'width' printable characters. If 'filterAll'
 * is true, all ANSI escape sequences are filtered out. Otherwise,
 * some escape sequences (such as colour setting) are copied but not
 * included in the character count. Also, tabs are expanded to
 * spaces.
 */
std::string filterANSIEscapes(std::string_view s,
    bool filterAll = false,
    unsigned int width = std::numeric_limits<unsigned int>::max());

I.e. something like filterANSIEscapes(s, false, getWindowSize().second()).

Copy link
Contributor Author

@kjeremy kjeremy Aug 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edolstra At this point getWindowSize() returns 0,0. I tried calling updateWindowSize() manually but I keep getting 0,0 in the test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be running headless in tests. Does it work when calling it interactive?

Copy link
Contributor Author

@kjeremy kjeremy Aug 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, I see values if I run nix flake show on the console. Do I need to provide a maximum length for headless mode? If so then what is the recommended way to detect it (isTTY?)?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty nice would be to output relative to current terminal? (Or 80-ish if headless)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty nice would be to output relative to current terminal? (Or 80-ish if headless)

I think that's what the getWindowSize approach is supposed to do unless I'm misunderstanding something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly, I was thinking that it would call getWindowSize, if 0, use 80-ish, otherwise use what was returned. Be careful about some pathological tiny windows!

@kjeremy
Copy link
Contributor Author

kjeremy commented Aug 5, 2024

I think the macos test failure is spurious

@tomberek
Copy link
Contributor

tomberek commented Aug 7, 2024

I tried this out and I still get overflow. Am I reading the logic wrong? Shouldn't the window size limitation be on the entire string rather than only the desc?

logger->cout("%s: %s '%s' - '%s'", headerPrefix, type, name, desc);
             ^-----------------^

@kjeremy
Copy link
Contributor Author

kjeremy commented Aug 7, 2024

I guess it could be. I was thinking it should just be on the description but maybe it should be on the whole string but we should only cut off the description if too long to match existing behavior

src/nix/flake.cc Outdated
Comment on lines 1287 to 1296
auto line = beginningOfLine + restOfLine;
// FIXME: Specifying `true` here gives the correct length
// BUT removes colors/bold so something is not quite right here.
line = filterANSIEscapes(line, true, maxLength);

// NOTE: This test might be incorrect since I get things like:
// 168 or 161 > maxLength.
if (line.length() > maxLength) {
line = line.replace(line.length() - 3, 3, "...");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the FIXME: here. I think this is pretty close but it's not 100% correct yet. filterANSIEscapes(..., true) seems to give a reasonable character count but I'm losing color information. filterANSIEscapes(..., false) gives funky length values so I think I'm missing something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edolstra @tomberek it's close! but I'm missing something with the escapes:

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there might be a known number of escapes that you need to correct for, but then also use the original line (plus some terminating ANSI codes). Perhaps do:

  1. check length without codes
  2. start with string with codes
  3. subtract the difference from the max
  4. subtract a additional known amount as correction
  5. pad with a "reset" ANSI sequence
  6. ????
  7. Happiness

Copy link
Contributor Author

@kjeremy kjeremy Aug 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all fairly terrible. The filtering function definitely doesn't strip ascii codes out and this all depends on the nested level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a less perfect solution we could implement for now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice if filterANSIEscapes filtered out color codes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new version uses a modified version of filterANSIEscapes with the tree characters taken into account. It's kind of ugly but seems to work!

Copy link
Member

@roberth roberth Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is all fairly terrible.

Absolutely. Terminal color logic, layout logic and flake attribute logic should all be separated out into distinct functions, classes, etc.
However, since we know the solution for the tech debt and we're not dealing with crazy compatibility requirements in this part of the code, I'd be happy to merge this and do the refactoring after.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be great

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@roberth Are we good to go as-is?

@kjeremy kjeremy marked this pull request as draft August 8, 2024 18:52
@kjeremy kjeremy marked this pull request as ready for review August 12, 2024 18:52
@kjeremy kjeremy requested a review from roberth August 17, 2024 13:33
@tomberek
Copy link
Contributor

Tested and works as expected. Thanks!

@tomberek tomberek merged commit 1c5ad15 into NixOS:master Aug 18, 2024
12 checks passed
@kjeremy kjeremy deleted the flake-show-description branch August 18, 2024 22:46
edolstra added a commit to DeterminateSystems/nix-src that referenced this pull request Nov 7, 2024
…ption"

This reverts commit 1c5ad15, reversing
changes made to 67de193.
edolstra added a commit to DeterminateSystems/nix-src that referenced this pull request Nov 7, 2024
…ption"

This reverts commit 1c5ad15, reversing
changes made to 67de193.

This reverts commit ce4e4a1, reversing
changes made to 43e82c9.
edolstra added a commit that referenced this pull request Nov 7, 2024
Revert "Merge pull request #10980 from kjeremy/flake-show-description"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flakes new-cli Relating to the "nix" command with-tests Issues related to testing. PRs with tests have some priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants