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

UpdateVcfSequenceDictionary handles stdout #741

Merged
merged 1 commit into from
Feb 15, 2017

Conversation

ronlevine
Copy link
Contributor

Description

Implements the handling of stdout in #507.
If stdout is the output file, set to write to a stream instead of a file.


Checklist (never delete this)

Never delete this, it is our record that procedure was followed. If you find that for whatever reason one of the checklist points doesn't apply to your PR, you can leave it unchecked but please add an explanation below.

Content

  • Added or modified tests to cover changes and any new functionality
  • Edited the README / documentation (if applicable)
  • All tests passing on Travis

Review

  • Final thumbs-up from reviewer
  • Rebase, squash and reword as applicable

For more detailed guidelines, see https://github.com/broadinstitute/picard/wiki/Guidelines-for-pull-requests

@ronlevine ronlevine self-assigned this Jan 31, 2017
@ronlevine
Copy link
Contributor Author

@yfarjoun Please review.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.004%) to 73.512% when pulling bb3f99f on rhl_uvsd_stdin_stdout_507 into 2105a1e on master.

@@ -59,7 +59,7 @@
@Option(shortName = StandardOptionDefinitions.INPUT_SHORT_NAME, doc = "Input VCF")
public File INPUT;

@Option(shortName = StandardOptionDefinitions.OUTPUT_SHORT_NAME, doc = "Output VCF to be written.")
@Option(shortName = StandardOptionDefinitions.OUTPUT_SHORT_NAME, doc = "Output VCF to be written to a file or stdout")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Reverted the change.

@@ -89,7 +91,15 @@ protected int doWork() {
if (CREATE_INDEX)
builder.setOption(Options.INDEX_ON_THE_FLY);

final VariantContextWriter vcfWriter = builder.setOutputFile(OUTPUT).build();
// handle stdout
if ( OUTPUT.getPath().equals(STD_OUT) ) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Stdout would be specified with O=/dev/stdout. How about:
builder.setOutputStream(new FileOutputStream(OUTPUT, false));
instead of the if/else?

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's cleaner but how can the stdout be redirected to a file for validation by a test? With System.out, it's easy by using System.setOut(PrintStream out).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@yfarjoun I like the code change suggestion but it would it would be tough to validate the output. I can bypass that check in my test.Thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think you need the if statement here at all, as @nh13 said. please remove it and wrap OUTPUT with a FileOutputStream (and remove the STD_OUT constant)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


/**
* @author George Grant
*/
public class UpdateVcfSequenceDictionaryTest {
private static final File TEST_DATA_PATH = new File("testdata/picard/vcf/");
private static final File OUTPUT_DATA_PATH = IOUtil.createTempDir("UpdateVcfSequenceDictionaryTest", null);
private static final File STD_OUT_FILE = new File(OUTPUT_DATA_PATH, "stdout.vcf");
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am not so sure about these tests, @yfarjoun

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 intent is to redirect stdout into a file, so it could be verified. Do you have a better idea for verification?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, I meant to say I didn't review the tests, sorry for the confusion.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think you should be calling System.setOut(PrintStream out) from the test and not modify the code in UpdateVcfSequenceDictionary.

so the test would be something like

File STD_OUT_FILE = new File(OUTPUT_DATA_PATH, "stdout.vcf");
Stream stdout = new OutputStream(STD_OUT_FILE);
System.setOut(stdout);

//run test

//close stream if needed

//examine file.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.004%) to 73.512% when pulling 8418079 on rhl_uvsd_stdin_stdout_507 into 2105a1e on master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.004%) to 73.512% when pulling 9ef506c on rhl_uvsd_stdin_stdout_507 into 2105a1e on master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.0006%) to 73.508% when pulling f005494 on rhl_uvsd_stdin_stdout_507 into 2105a1e on master.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.0006%) to 73.508% when pulling f005494 on rhl_uvsd_stdin_stdout_507 into 2105a1e on master.

@ronlevine
Copy link
Contributor Author

@nh13 @yfarjoun I cleaned up the test and removed the "if" statement so that the OUTPUT is a stream. Removing that logic makes the code more concise and flexible. Note that setOutputFile is just and adapter, it converts the file to a stream. Let know if you have any more comments.

@yfarjoun
Copy link
Contributor

yfarjoun commented Feb 3, 2017

something isn't right.

The value of OUTPUT has to be the string "/dev/stdout"

Then you should be setting the output stream to point to a file using System.setOut()

@ronlevine
Copy link
Contributor Author

@yfarjoun How about this? OUTPUT=/dev/stdout.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) to 73.517% when pulling ef13c61 on rhl_uvsd_stdin_stdout_507 into 2105a1e on master.

outputFile.deleteOnExit();

// Stream standard output a file
if ( outputFileName.equals(UpdateVcfSequenceDictionary.STD_OUT) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

use a local variable for STD_OUT.

final UpdateVcfSequenceDictionary updateVcfSequenceDictionary = new UpdateVcfSequenceDictionary();
updateVcfSequenceDictionary.INPUT = input;
updateVcfSequenceDictionary.SEQUENCE_DICTIONARY = samSequenceDictionaryVcf;
updateVcfSequenceDictionary.OUTPUT = outputFile;

Assert.assertEquals(updateVcfSequenceDictionary.instanceMain(new String[0]), 0);

if ( outputFileName.equals(UpdateVcfSequenceDictionary.STD_OUT) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

a bit fewer spaces

if (outputFileName.equals(UpdateVcfSequenceDictionary.STD_OUT)) {

outputFile.deleteOnExit();

// Stream standard output a file
if ( outputFileName.equals(UpdateVcfSequenceDictionary.STD_OUT) ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

same here (fewer spaces)

@yfarjoun
Copy link
Contributor

yfarjoun commented Feb 4, 2017

back to you @ronlevine

@yfarjoun
Copy link
Contributor

yfarjoun commented Feb 5, 2017

@ronlevine I have uploaded a branch with hat I would imagine would be a "clean" solution to the following branch (sorry about the ) in the branch name...typo) : https://github.com/broadinstitute/picard/tree/yf)uvsd_streams

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.03%) to 73.475% when pulling 8a7b965 on rhl_uvsd_stdin_stdout_507 into 2105a1e on master.

@ronlevine
Copy link
Contributor Author

ronlevine commented Feb 5, 2017

@yfarjoun Please take a look at my changes. I took a look at your branch and incorporated the file stream redirection by file descriptor for stdout. Thanks, that solved the file validation problem. Note that only setOutputStream is needed and the if statement can be removed. I also found that if the test was run with STD_OUT_NAME as the first or only outputFileName, it would fail while writing the header:

htsjdk.samtools.util.RuntimeIOException: Couldn't write file java.io.FileOutputStream@7d907bac

	at htsjdk.variant.variantcontext.writer.VCFWriter.writeHeader(VCFWriter.java:139)

because
final FileOutputStream stream = new FileOutputStream(STD_OUT_FILE) goes out of scope and is destroyed. So, I moved it's declaration outside the if statement.

Copy link
Contributor

@yfarjoun yfarjoun left a comment

Choose a reason for hiding this comment

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

a few small comments and we'll be good to go.

outputFile.deleteOnExit();

final UpdateVcfSequenceDictionary updateVcfSequenceDictionary = new UpdateVcfSequenceDictionary();

FileOutputStream stream = null; // placed outside of if statement so it's not destroyed before executing updateVcfSequenceDictionary
Copy link
Contributor

Choose a reason for hiding this comment

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

can be final. (just set to null in the else branch)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


stream = new FileOutputStream(STD_OUT_FILE);

// Ugliness required to write to m a stream given as a string on the commandline.
Copy link
Contributor

Choose a reason for hiding this comment

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

is that m in my original comment? in any case, it's a typo, please fix.

Copy link
Contributor Author

@ronlevine ronlevine Feb 13, 2017

Choose a reason for hiding this comment

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

Nope, just a case of my fat fingers when changing the read from in your original comment to write to.

@ronlevine
Copy link
Contributor Author

ronlevine commented Feb 13, 2017

Squashed and rebased. Let me know if it's OK to merge.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 73.462% when pulling f196cb1 on rhl_uvsd_stdin_stdout_507 into bce0086 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.02%) to 73.462% when pulling f196cb1 on rhl_uvsd_stdin_stdout_507 into bce0086 on master.

@ronlevine
Copy link
Contributor Author

@yfarjoun OK to merge?

@yfarjoun
Copy link
Contributor

yes. I'm fine with it. 👍 from me.

In the future, please refrain from squashing your commits until the merge (you can squash during the final merge itself), so that your reviewers can have an easier time viewing the latest changes you made.

@ronlevine ronlevine merged commit b58a552 into master Feb 15, 2017
@ronlevine ronlevine deleted the rhl_uvsd_stdin_stdout_507 branch February 15, 2017 17:40
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.

4 participants