Skip to content

Conversation

mjcuva
Copy link
Member

@mjcuva mjcuva commented Nov 8, 2017

Added support for sending files to build services.

  • Posts as multipart/form-data
  • Added api.file, which takes a path to a file
  • Parses response to handle files being returned, as well as object responses

Todo

  • Add support for urls in api.file
  • api local
  • api link

@mjcuva mjcuva changed the title First pass at supporting sending files to build services Support sending files to build services Jan 8, 2018
Copy link
Member

@domharrington domharrington left a comment

Choose a reason for hiding this comment

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

Can you fix the code climate issues?

Has this been tested with particularly big files? Doing streamToBuffer() might be quite memory intensive.

This PR really scares me due to the sheer amount of conversion code in here. It seems like we're constantly having to convert things between JSON/Streams/Buffers. I'm sure it's all necessary, but it's scary and seems like there's lots that could go wrong with it.

};
// If no data is passed in, default to {}
if (typeof data === 'function') {
callback = data;
Copy link
Member

Choose a reason for hiding this comment

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

It looks as though we've lost some coverage here... did this used to be covered?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm pretty sure it never was

const parsedError = JSON.parse(err);
console.log(parsedError);
} else if (Buffer.isBuffer(response)) {
process.stdout.write(response);
Copy link
Member

Choose a reason for hiding this comment

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

Any way to test this? Could monkey path over process.stdout.write for the test? Is this any different that doing console.log(response)?

Copy link
Member Author

Choose a reason for hiding this comment

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

console.log formats the output, so for writing binary data it doesn't work. process.stdout.write just dumps the output as is

return invoke(team.key, service, action, data, true).then((response) => {
console.log(response.body);
if (Buffer.isBuffer(response.file)) {
process.stdout.write(response.file);
Copy link
Member

Choose a reason for hiding this comment

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

Same as above. Maybe this piece can be abstracted out, might make it easier to test.

});

it('should return false if not valid url', () => {
assert.equal(false, fileUtils.isUrl('/path/to/image'));
Copy link
Member

Choose a reason for hiding this comment

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

This should be the other way around assert.equal(fileUtils.isUrl('/path/to/image'), false);


exports.file = (p) => {
if (exports.isUrl(p)) {
return request.get({ url: p, encoding: null });
Copy link
Member

Choose a reason for hiding this comment

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

Anyway to write a test for this and mock out the response?

exports.streamToBuffer = (s) => {
return new Promise((resolve) => {
const out = [];
s.on('data', (data) => {
Copy link
Member

Choose a reason for hiding this comment

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

I think we need to add an error case to this:

s.on('error', reject)

};

// Converts buffers in response to file type
exports.parseFileResponse = (response) => {
Copy link
Member

Choose a reason for hiding this comment

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

Not sure what to do to simplify this. Maybe pull that parse reviver function outside of this function into a named one? Wondering if you came across this to do the buffer part? https://github.com/jprichardson/buffer-json Ours looks like it does more than that though....


module.exports.getSecret = secrets => secret => secrets.find(s => s.key === secret).value;

module.exports.fixBuffers = (d) => {
Copy link
Member

Choose a reason for hiding this comment

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

What's this for?

Copy link
Member Author

Choose a reason for hiding this comment

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

When a file gets passed to lambda, it gets stringified into that weird buffer string format, so we have to convert it back to being a buffer

const data = {};
const passedData = exports.fixMinimistSpaces(args);
for (const arg of passedData) {
const i = arg.indexOf('=');
Copy link
Member

Choose a reason for hiding this comment

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

Can you pull this whole chunk into a separate part to simplify the complexity?

let parsedResponse = response.body;
try {
parsedResponse = JSON.parse(response.body, (k, v) => {
return v && v.type === 'Buffer' ? Buffer.from(v.data) : v;
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

They do slightly different things, but I think I should combine them

@mjcuva mjcuva merged commit 1213368 into master Jan 12, 2018
@erunion erunion deleted the enhancement/files branch May 1, 2020 05:47
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.

2 participants