Skip to content

Commit 535407c

Browse files
committed
Implemented missing version features
1 parent d28469f commit 535407c

File tree

9 files changed

+183
-34
lines changed

9 files changed

+183
-34
lines changed

features/bootstrap/FeatureContext.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,17 @@ public function iExecuteTheCommand($args)
150150
$this->executeCommand($args);
151151
}
152152

153+
/**
154+
* @Given /^I execute the following commands:$/
155+
*/
156+
public function iExecuteTheFollowingCommands(TableNode $table)
157+
{
158+
foreach ($table->getRows() as $row) {
159+
$this->executeCommand($row[0]);
160+
$this->theCommandShouldNotFail();
161+
}
162+
}
163+
153164
/**
154165
* @Then /^I should see a table containing the following rows:$/
155166
*/
@@ -190,6 +201,15 @@ public function iShouldSeeTheFollowing(PyStringNode $string)
190201
PHPUnit_Framework_Assert::assertContains($string->getRaw(), $output);
191202
}
192203

204+
/**
205+
* @Then /^I should not see the following:$/
206+
*/
207+
public function iShouldNotSeeTheFollowing(PyStringNode $string)
208+
{
209+
$output = $this->getOutput();
210+
PHPUnit_Framework_Assert::assertNotContains($string->getRaw(), $output);
211+
}
212+
193213
/**
194214
* @Given /^the "([^"]*)" fixtures are loaded$/
195215
*/

features/node_info.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Feature: Show information about node
1919
| Index | 1 |
2020
| Primary node type | nt:unstructured |
2121
| Mixin node types | |
22-
| Checked out? | [ERROR] Not implemented by jackalope |
22+
| Checked out? | N/A |
2323
| Locked? | [ERROR] Not implemented by jackalope |
2424
+-------------------+--------------------------------------+
2525
"""

features/version_checkout.feature

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,13 @@ Feature: Checkout a version
1010
Scenario: Checkout a a given node
1111
Given I execute the "version:checkout /tests_version_base/versioned" command
1212
Then the command should not fail
13-
And the node "/tests_version_base/verionable" should be checked out
13+
And the current node is "/tests_version_base/versioned"
14+
And I execute the "node:info" command
15+
Then I should see the following:
16+
"""
17+
| Checked out? | yes
18+
"""
19+
1420

1521
Scenario: Checkout a non-versionable node
1622
Given I execute the "version:checkout /tests_version_base" command

features/version_checkpoint.feature

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,23 @@ Feature: Checkpoint
88
And the "versionable.xml" fixtures are loaded
99

1010
Scenario: Checkpoint a a given node
11-
Given I execute the "version:checkpoint /tests_version_base/versioned" command
11+
Given I execute the following commands:
12+
| cd /tests_version_base/versioned |
13+
| node:set foo bar |
14+
| session:save |
15+
| version:checkpoint /tests_version_base/versioned |
16+
| node:set foo baz |
17+
| session:save |
18+
| version:checkpoint /tests_version_base/versioned |
1219
Then the command should not fail
13-
And the node "/tests_version_base/verionable" should be checked out
1420
And I should see the following:
1521
"""
16-
Version:
22+
Version: 1.1
23+
"""
24+
And I execute the "node:info" command
25+
Then I should see the following:
26+
"""
27+
| Checked out? | yes
1728
"""
1829

1930
Scenario: Checkpoint a non versionable node

features/version_remove.feature

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,23 @@ Feature: Remove node version
55

66
Background:
77
Given that I am logged in as "testuser"
8-
And the "session_data.xml" fixtures are loaded
8+
And the "versionable.xml" fixtures are loaded
99

1010
Scenario: Checkout a a given node
11-
Given the node "/tests_general_base" has a version with label "mylabel"
12-
And I execute the "version:remove /tests_general_base mylabel" command
11+
Given I execute the following commands:
12+
| cd /tests_version_base/versioned |
13+
| version:checkout /tests_version_base/versioned |
14+
| node:set foo baz |
15+
| session:save |
16+
| version:checkin /tests_version_base/versioned |
17+
| version:checkout /tests_version_base/versioned |
18+
| node:set foo bar |
19+
| session:save |
20+
| version:checkin /tests_version_base/versioned |
21+
And I execute the "version:remove /tests_version_base/versioned 1.0" command
1322
Then the command should not fail
14-
And the node "/tests_general_base" should have a node version labeled "mylabel"
23+
And I execute the "version:history /tests_version_base/versioned" command
24+
Then I should not see the following:
25+
"""
26+
| 1.0 |
27+
"""

features/version_restore.feature

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,21 @@ Feature: Restore a version
55

66
Background:
77
Given that I am logged in as "testuser"
8-
And the "session_data.xml" fixtures are loaded
8+
And the "versionable.xml" fixtures are loaded
99

1010
Scenario: Restore node version
11-
Given there exists a node version "asd" for node "/tests_general_base"
12-
And I execute the "version:restore --version=asd" command
11+
Given I execute the following commands:
12+
| cd /tests_version_base/versioned |
13+
| node:set foo initalbar |
14+
| session:save |
15+
| version:checkpoint /tests_version_base/versioned |
16+
| node:set foo baz |
17+
| session:save |
18+
| version:checkpoint /tests_version_base/versioned |
19+
And I execute the "version:restore /tests_version_base/versioned 1.0" command
1320
Then the command should not fail
14-
And the version of "/tests_general_base" should be "asd"
15-
16-
Scenario: Restore node version by label
17-
Given there exists a node version "asd" for node "/tests_general_base"
18-
And I execute the "version:restore --label=asd" command
19-
Then the command should not fail
20-
And the version of "/tests_general_base" should be "asd"
21-
22-
Scenario: Restore multiple node versions
23-
Given there exists a node version "asd" for node "/tests_general_base"
24-
And I execute the "version:restore --version=asd --version=dsa" command
25-
Then the command should not fail
26-
And the version of "/tests_general_base" should be "asd"
21+
And I execute the "ls" command
22+
Then I should see the following:
23+
"""
24+
| foo | STRING | inital
25+
"""

src/PHPCR/Shell/Console/Command/NodeInfoCommand.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ protected function configure()
2626
public function execute(InputInterface $input, OutputInterface $output)
2727
{
2828
$session = $this->getHelper('phpcr')->getSession();
29+
$nodeHelper = $this->getHelper('node');
2930
$currentNode = $session->getCurrentNode();
3031
$formatter = $this->getHelper('result_formatter');
3132

@@ -36,10 +37,14 @@ public function execute(InputInterface $input, OutputInterface $output)
3637
$mixinNodeTypeNames[] = $mixin->getName();
3738
}
3839

39-
try {
40-
$isCheckedOut = $currentNode->isCheckedOut() ? 'yes' : 'no';
41-
} catch (\Exception $e) {
42-
$isCheckedOut = $formatter->formatException($e);
40+
if ($nodeHelper->nodeHasMixinType($currentNode, 'mix:versionable')) {
41+
try {
42+
$isCheckedOut = $currentNode->isCheckedOut() ? 'yes' : 'no';
43+
} catch (\Exception $e) {
44+
$isCheckedOut = $formatter->formatException($e);
45+
}
46+
} else {
47+
$isCheckedOut = 'N/A';
4348
}
4449

4550
try {

src/PHPCR/Shell/Console/Command/VersionRemoveCommand.php

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,36 @@ protected function configure()
1414
$this->setName('version:remove');
1515
$this->setDescription('Remove a node version');
1616
$this->addArgument('absPath', null, InputArgument::REQUIRED, 'Absolute path to node');
17+
$this->addArgument('versionName', null, InputArgument::REQUIRED, 'Name of version to remove');
1718
$this->setHelp(<<<HERE
19+
Removes the named version from this version history and automatically
20+
repairs the version graph.
21+
22+
If the version to be removed is V, V's predecessor set is P and V's
23+
successor set is S, then the version graph is repaired s follows:
24+
25+
- For each member of P, remove the reference to V from its successor
26+
list and add references to each member of S.
27+
- For each member of S, remove the reference to V from its predecessor
28+
list and add references to each member of P.
29+
30+
<b>Note</b> that this change is made immediately; there is no need to
31+
call save. In fact, since the the version storage is read-only with
32+
respect to normal repository methods, save does not even function in
33+
this context.
1834
HERE
1935
);
2036
}
2137

2238
public function execute(InputInterface $input, OutputInterface $output)
2339
{
24-
$session = $this->getHelper('phpcr')->getSession();
2540
$absPath = $input->getArgument('absPath');
41+
$versionName = $input->getArgument('versionName');
42+
$session = $this->getHelper('phpcr')->getSession();
2643
$workspace = $session->getWorkspace();
27-
2844
$versionManager = $workspace->getVersionManager();
29-
$version = $versionManager->checkin($absPath);
3045

31-
$output->writeln('Version: ' . $version);
46+
$history = $versionManager->getVersionHistory($absPath);
47+
$history->removeVersion($versionName);
3248
}
3349
}

src/PHPCR/Shell/Console/Command/VersionRestoreCommand.php

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,99 @@
66
use Symfony\Component\Console\Input\InputInterface;
77
use Symfony\Component\Console\Output\OutputInterface;
88
use Symfony\Component\Console\Input\InputArgument;
9+
use Symfony\Component\Console\Input\InputOption;
910

1011
class VersionRestoreCommand extends Command
1112
{
1213
protected function configure()
1314
{
1415
$this->setName('version:restore');
1516
$this->setDescription('Restore a node version');
17+
$this->addArgument('absPath', null, InputArgument::REQUIRED, 'Absolute path to node');
18+
$this->addArgument('versionName', null, InputArgument::REQUIRED, 'Name of version to retore');
19+
$this->addOption('remove-existing', null, InputOption::VALUE_NONE, 'Flag that governs what happens in case of identifier collision');
1620
$this->setHelp(<<<HERE
21+
Attempt to restore an old version of a node.
22+
23+
<em>If <info>absPath</info> is given and <info>versionName</info> is a version name:</em>
24+
Restores the node at <info>absPath</info> to the state defined by the version with
25+
the specified version name (<info>versionName</info>).
26+
This method will work regardless of whether the node at absPath is
27+
checked-in or not.
28+
29+
30+
<em>If <info>absPath</info> is given and <info>versionName</info> is a VersionInterface instance:
31+
</em>
32+
Restores the specified version to <info>absPath</info>. There must be no existing
33+
node at <info>absPath</info>. If one exists, a VersionException is thrown.
34+
There must be a parent node to the location at <info>absPath</info>, otherwise a
35+
PathNotFoundException is thrown.
36+
If the would-be parent of the location <info>absPath</info> is actually a property,
37+
or if a node type restriction would be violated, then a
38+
ConstraintViolationException is thrown.
39+
40+
41+
<em>If <info>versionName</info> is VersionInterface instance:</em>
42+
Restores the node in the current workspace that is the versionable node
43+
of the specified version to the state reflected in that version.
44+
This method ignores checked-in status.
45+
46+
47+
<em>If <info>versionName</info> is an array of VersionInterface instances:</em>
48+
Restores a set of versions at once. Used in cases where a "chicken and
49+
egg" problem of mutually referring REFERENCE properties would prevent
50+
the restore in any serial order.
51+
The following restrictions apply to the set of versions specified: If S
52+
is the set of versions being restored simultaneously,
53+
- For every version V in S that corresponds to a missing node, there
54+
must also be a parent of V in S.
55+
- S must contain at least one version that corresponds to an existing
56+
node in the workspace.
57+
- No V in S can be a root version (jcr:rootVersion).
58+
If any of these restrictions does not hold, the restore will fail
59+
because the system will be unable to determine the path locations to
60+
which one or more versions are to be restored. In this case a
61+
VersionException is thrown.
62+
The versionable nodes in the current workspace that correspond to the
63+
versions being restored define a set of (one or more) subgraphs.
64+
65+
<em>If the restore succeeds the changes made are dispatched immediately;
66+
</em>
67+
there is no need to call save.
68+
69+
If an array of VersionInterface instances is restored, an identifier
70+
collision occurs when the current workspace contains a node outside these
71+
subgraphs that has the same identifier as one of the nodes that would be
72+
introduced by the restore operation into one of these subgraphs.
73+
Else, an identifier collision occurs when a node exists outside the
74+
subgraph rooted at absPath with the same identifier as a node that would
75+
be introduced by the restore operation into the affected subgraph.
76+
The result in such a case is governed by the removeExisting flag. If
77+
<info>removeExisting</info> is true, then the incoming node takes precedence, and the
78+
existing node (and its subgraph) is removed (if possible; otherwise a
79+
RepositoryException is thrown). If <info>removeExisting</info> is false, then an
80+
ItemExistsException is thrown and no changes are made. Note that this
81+
applies not only to cases where the restored node itself conflicts with
82+
an existing node but also to cases where a conflict occurs with any node
83+
that would be introduced into the workspace by the restore operation. In
84+
particular, conflicts involving subnodes of the restored node that have
85+
OnParentVersion settings of COPY or VERSION are also governed by the
86+
<info>removeExisting</info> flag.
87+
88+
<b>Note:</b> The Java API defines this with multiple differing
89+
signatures, you need to act accordingly in your implementation.
1790
HERE
1891
);
1992
}
2093

2194
public function execute(InputInterface $input, OutputInterface $output)
2295
{
23-
throw new \Exception('TODO');
96+
$absPath = $input->getArgument('absPath');
97+
$versionName = $input->getArgument('versionName');
98+
$removeExisting = $input->getOption('remove-existing');
99+
$session = $this->getHelper('phpcr')->getSession();
100+
$workspace = $session->getWorkspace();
101+
$versionManager = $workspace->getVersionManager();
102+
$versionManager->restore($removeExisting, $versionName, $absPath);
24103
}
25104
}

0 commit comments

Comments
 (0)