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

feat: add a newline after commands that don't end their output with one #810

Merged
merged 3 commits into from
May 17, 2024

Conversation

chankruze
Copy link
Contributor

@chankruze chankruze commented May 16, 2024

Issue: #776

@antongolub
Copy link
Contributor

antongolub commented May 16, 2024

@chankruze,

  1. There should be a test.
  2. No need to convert the buffer to string.
const eol = Buffer.from('\n', 'utf-8')

if (!entry.data.slice(-1).equals(eol)) {
  entry.data = Buffer.concat([entry.data, eol])
}

@chankruze
Copy link
Contributor Author

@antongolub What's your opinion about this ?

This method is not compatible with the Uint8Array.prototype.slice(), which is a superclass of Buffer. To copy the slice, useUint8Array.prototype.slice().

const eol = Buffer.from('\n', 'utf-8');
if (Uint8Array.prototype.slice.call(entry.data, -1)[0] !== eol[0]) {
  entry.data = Buffer.concat([entry.data, eol]);
}

Signed-off-by: chankruze <[email protected]>
@antongolub
Copy link
Contributor

antongolub commented May 16, 2024

cc @antonmedv

Uint8Array... Ok, we get some kind of Buffer here. Maybe we should try to keep the original proto:

const B = entry.data.constructor
const eol = B.from('\n')

if (entry.data.slice(-1).equal(eol)) {
  entry.data = B.concat([entry.data, eol])
}

Does Uint8Array have own static concat helper? It does not.

@antongolub
Copy link
Contributor

Well, it seems too verbose to modify the value. Let's keep the initial approach. Just move this helper to util.ts and add a test plz.

export function ensureEol (buffer: Buffer): Buffer {
  if (buffer.toString('utf8', buffer.length - 1) !== '\n') {
    return Buffer.concat([buffer, Buffer.from('\n')])
  }

  return buffer
}

@antongolub
Copy link
Contributor

antongolub commented May 16, 2024

buffer.toString('utf8', buffer.length - 1) bothers me. I don't know how it works inside. If it is just a shortcut for .toString('utf8').slice() we could get a doubled mem usage here.

@chankruze
Copy link
Contributor Author

chankruze commented May 16, 2024

@antongolub sure! will do that.

  1. buffer.toString('utf8') converts the entire Buffer object buffer into a string using the UTF-8 encoding.
  2. buffer.length - 1 calculates the index of the last character in the Buffer.

So, buffer.toString('utf8', buffer.length - 1) will start the conversion from the character at the position buffer.length - 1.

It's not equivalent to toString('utf8').slice() because slice() creates a new string by extracting a section of the original string, which would indeed duplicate memory usage. However, toString('utf8', buffer.length - 1) directly converts from the given index to the end of the buffer without creating a new string instance.

I think toString('utf8', buffer.length - 1) may be slightly more efficient because it doesn't involve creating an intermediate string that would contain the entire contents of the Buffer.

@chankruze
Copy link
Contributor Author

chankruze commented May 16, 2024

@antongolub what about this approach ?

export function ensureEol(buffer: Buffer): Buffer {
  if (!buffer.toString('utf8').endsWith('\n')) {
    return Buffer.concat([buffer, Buffer.from('\n')])
  }

  return buffer
}

I'm currently writing test. Just to confirm, do I need to write test for both this function and the core behavior or just the core test is good enough ?

@antongolub
Copy link
Contributor

  1. buffer.toString('utf8').endsWith('\n') creates a new string same size as the buffer.
  2. unit test for ensureEol is enough for now

@chankruze
Copy link
Contributor Author

@antongolub please review the changes and comment if anything needs to be done.

Copy link
Contributor

@antongolub antongolub left a comment

Choose a reason for hiding this comment

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

mention the method

test/util.test.js Outdated Show resolved Hide resolved
Copy link
Contributor

@antongolub antongolub left a comment

Choose a reason for hiding this comment

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

lgtm

@antonmedv antonmedv merged commit dfeb166 into google:main May 17, 2024
21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants