Skip to content

Commit

Permalink
Implemented CatCommand
Browse files Browse the repository at this point in the history
  • Loading branch information
lincolnthree committed Jan 14, 2014
1 parent 668c49e commit 88464de
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.jboss.forge.addon.shell.commands;

import java.util.Collections;
import java.util.Iterator;

import javax.inject.Inject;

import org.jboss.forge.addon.resource.Resource;
import org.jboss.forge.addon.resource.ResourceFactory;
import org.jboss.forge.addon.shell.Shell;
import org.jboss.forge.addon.shell.ui.AbstractShellCommand;
import org.jboss.forge.addon.shell.util.PathspecParser;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIContext;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.hints.InputType;
import org.jboss.forge.addon.ui.input.UIInputMany;
import org.jboss.forge.addon.ui.metadata.UICommandMetadata;
import org.jboss.forge.addon.ui.metadata.WithAttributes;
import org.jboss.forge.addon.ui.output.UIOutput;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;
import org.jboss.forge.addon.ui.util.Metadata;

/**
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
public class CatCommand extends AbstractShellCommand
{
@Inject
private ResourceFactory resourceFactory;

@Inject
@WithAttributes(label = "Arguments", type = InputType.FILE_PICKER)
private UIInputMany<String> arguments;

@Override
public UICommandMetadata getMetadata(UIContext context)
{
return Metadata
.from(super.getMetadata(context), getClass())
.name("cat")
.description(
"The cat utility reads files sequentially, writing them to the standard output. "
+ "The file operands are processed in command-line order.");
}

@Override
public void initializeUI(UIBuilder builder) throws Exception
{
builder.add(arguments);
}

@Override
public Result execute(UIExecutionContext context) throws Exception
{
Shell shell = (Shell) context.getUIContext().getProvider();
Resource<?> currentResource = shell.getCurrentResource();
Iterator<String> it = arguments.getValue() == null ? Collections.<String> emptyList().iterator() : arguments
.getValue().iterator();

Result result = Results.success();
UIOutput output = shell.getOutput();
while (it.hasNext())
{
final Resource<?> resource = it.hasNext() ?
(new PathspecParser(resourceFactory, currentResource, it.next()).resolve().get(0)) : currentResource;

if (!resource.exists())
{
output.err().println("cat: " + resource.getName() + ": No such file or directory");
result = Results.fail();
}
else
{
output.out().println(resource.getContents());
}
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class LsCommand extends AbstractShellCommand
{

@Inject
ResourceFactory resourceFactory;
private ResourceFactory resourceFactory;

@Inject
@WithAttributes(label = "Arguments", type = InputType.FILE_PICKER)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2013 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jboss.forge.addon.shell.aesh;

import static org.hamcrest.CoreMatchers.containsString;

import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.forge.addon.shell.MockCommandExecutionListener;
import org.jboss.forge.addon.shell.mock.command.Career;
import org.jboss.forge.addon.shell.mock.command.FooCommand;
import org.jboss.forge.addon.shell.test.ShellTest;
import org.jboss.forge.addon.ui.result.Failed;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.arquillian.AddonDependency;
import org.jboss.forge.arquillian.Dependencies;
import org.jboss.forge.arquillian.archive.ForgeArchive;
import org.jboss.forge.furnace.repositories.AddonDependencyEntry;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
* @author <a href="mailto:lincolnbaxter@gmail.com">Lincoln Baxter, III</a>
*/
@RunWith(Arquillian.class)
public class CatCommandTest
{
@Deployment
@Dependencies({
@AddonDependency(name = "org.jboss.forge.addon:shell-test-harness")
})
public static ForgeArchive getDeployment()
{
ForgeArchive archive = ShrinkWrap.create(ForgeArchive.class)
.addClasses(FooCommand.class, Career.class)
.addBeansXML()
.addClass(MockCommandExecutionListener.class)
.addAsAddonDependencies(
AddonDependencyEntry.create("org.jboss.forge.addon:shell-test-harness"),
AddonDependencyEntry.create("org.jboss.forge.furnace.container:cdi")
);

return archive;
}

private final int timeoutQuantity = 5000;

@Inject
private ShellTest test;

@Test(timeout = 10000000)
public void testCatCommand() throws Exception
{
Result result = test.execute("cat foo bar", timeoutQuantity, TimeUnit.SECONDS);
Assert.assertTrue(result instanceof Failed);
String out = test.getStdOut();
Assert.assertThat(out, containsString("cat: foo: No such file or directory"));
Assert.assertThat(out, containsString("cat: bar: No such file or directory"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ public static final Result success(String message)
return new SuccessfulResult(message);
}

public static final Result fail()
{
return fail(null);
}

public static final Result fail(String message)
{
return new FailedResult(message);
Expand Down

6 comments on commit 88464de

@gastaldi
Copy link
Member

Choose a reason for hiding this comment

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

Instead of writing to err(), Results.fail(msg) should be used

@lincolnthree
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 disagree in this case. I thought about that but I think that to behave more like a traditional shell, this is how it should be done. Errors are printed to STDERR and the return code of 1 is set. I spent a while looking at how this is done in UNIX before I ended up here. Why do you think we should use Results.fail() ?

@gastaldi
Copy link
Member

@gastaldi gastaldi commented on 88464de Jan 15, 2014 via email

Choose a reason for hiding this comment

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

@gastaldi
Copy link
Member

@gastaldi gastaldi commented on 88464de Jan 15, 2014 via email

Choose a reason for hiding this comment

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

@lincolnthree
Copy link
Member Author

@lincolnthree lincolnthree commented on 88464de Jan 15, 2014 via email

Choose a reason for hiding this comment

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

@lincolnthree
Copy link
Member Author

@lincolnthree lincolnthree commented on 88464de Jan 15, 2014 via email

Choose a reason for hiding this comment

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

Please sign in to comment.