Skip to content

Commit

Permalink
Add option to enforce refs on whippet deps validate
Browse files Browse the repository at this point in the history
This commit adds an `--enforce-refs` option that can be passed into
`whippet deps validate` that will cause it to fail if a dependency in
whippet.json is missing a "ref" property.

This will facilitate us in enabling automatic plugin updates, we we'll
be able to update our shared whippet validation workflow to fail if
references are missing, thereby ensuring that all dependencies have a
reference and therefore can't be accidentally updated beyond e.g. a
major version tag, or a specific pinned version.

Note that like the other checks in `whippet deps validate`, this does
not check whether the reference provided exists and is valid, it just
checks one is provided. An implicit check on the validity of the
reference itself happens when `whippet deps update` or `whippet deps
install` is run.
  • Loading branch information
RobjS committed Jul 17, 2024
1 parent 19d6be6 commit 136546a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
88 changes: 88 additions & 0 deletions spec/dependencies/validator.spec.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,94 @@
expect($result->getErr())->toEqual('Missing revision property in whippet.lock for plugins: advanced-custom-fields-pro');
});
});
context('but an entry in .json is missing a ref when --enforce-refs is set', function () {
it('returns an error', function () {
$whippetContents = '{
"src": {
"plugins": "[email protected]:wordpress-plugins/"
},
"plugins": [
{"name": "akismet", "ref": "v1"},
{"name": "advanced-custom-fields-pro"}
]
}';
allow('file_get_contents')->toBeCalled()->andReturn($whippetContents);
allow('sha1')->toBeCalled()->andReturn('a_matching_sha');
expect('sha1')->toBeCalled()->once()->with($whippetContents);
allow($this->whippetLock)->toReceive('getHash')->andReturn('a_matching_sha');
allow($this->whippetJson)->toReceive('getDependencies')->andReturn([], [
[
'name' => 'akismet',
'ref' => 'v1'
],
[
'name' => 'advanced-custom-fields-pro'
]
]);
allow($this->whippetLock)->toReceive('getDependencies')->andReturn([], [
[
'name' => 'akismet',
'src' => 'a_src_1',
'revision' => 'a_revision_1'
],
[
'name' => 'advanced-custom-fields-pro',
'src' => 'a_src_2',
'revision' => 'a_revision_2'
]
]);
ob_start();
$result = $this->validator->validate(true);
$output = ob_get_clean();
expect($result->getErr())->toEqual("Missing reference in whippet.json for plugins: advanced-custom-fields-pro");
expect($result)->toBeAnInstanceOf(\Result\Result::class);
expect($result->isErr())->toEqual(true);
});
});
context('but an entry in whippet.json is missing a ref when --enforce-refs is not set', function () {
it('returns an ok result', function () {
$whippetContents = '{
"src": {
"plugins": "[email protected]:wordpress-plugins/"
},
"plugins": [
{"name": "akismet", "ref": "v1"},
{"name": "advanced-custom-fields-pro"}
]
}';
allow('file_get_contents')->toBeCalled()->andReturn($whippetContents);
allow('sha1')->toBeCalled()->andReturn('a_matching_sha');
expect('sha1')->toBeCalled()->once()->with($whippetContents);
allow($this->whippetLock)->toReceive('getHash')->andReturn('a_matching_sha');
allow($this->whippetJson)->toReceive('getDependencies')->andReturn([], [
[
'name' => 'akismet',
'ref' => 'v1'
],
[
'name' => 'advanced-custom-fields-pro'
]
]);
allow($this->whippetLock)->toReceive('getDependencies')->andReturn([], [
[
'name' => 'akismet',
'src' => 'a_src_1',
'revision' => 'a_revision_1'
],
[
'name' => 'advanced-custom-fields-pro',
'src' => 'a_src_2',
'revision' => 'a_revision_2'
]
]);
ob_start();
$result = $this->validator->validate();
$output = ob_get_clean();
expect($output)->toEqual("Valid whippet.json and whippet.lock \n");
expect($result)->toBeAnInstanceOf(\Result\Result::class);
expect($result->isErr())->toEqual(false);
});
});
context('and everything is good', function () {
it('returns an ok result', function () {
$whippetContents = '{
Expand Down
7 changes: 6 additions & 1 deletion src/Dependencies/Validator.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function __construct(
$this->dir = $dir;
}

public function validate()
public function validate(bool $enforceRefs = false)
{
$whippetLock = $this->loadWhippetLock();
if ($whippetLock->isErr()) {
Expand Down Expand Up @@ -57,6 +57,11 @@ public function validate()
if (!$this->lockMatchFoundForDependency($whippetJsonDependency, $whippetLockDependencies)) {
return \Result\Result::err(sprintf('No entry found in whippet.lock for %s: %s', $type, $whippetJsonDependency["name"]));
}
if ($enforceRefs) {
if (!array_key_exists('ref', $whippetJsonDependency)) {
return \Result\Result::err(sprintf("Missing reference in whippet.json for %s: %s", $type, $whippetJsonDependency["name"]));
}
}
}

foreach ($whippetLockDependencies as $whippetLockDependency) {
Expand Down
7 changes: 5 additions & 2 deletions src/Modules/Dependencies.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public function commands()
};
$this->command('install', 'Installs dependencies', $inspections_host_option);
$this->command('update', 'Updates dependencies to their latest versions. Use deps update [type]/[name] to update a specific dependency', $inspections_host_option);
$this->command('validate', 'Validate whippet.json and whippet.lock files');
$this->command('validate', 'Validate whippet.json and whippet.lock files', function ($option_parser) {
$option_parser->addRule('r|enforce-refs', "Enforce refs for all whippet dependencies");
});
$this->command('describe', 'List dependencies and their versions');
}

Expand Down Expand Up @@ -78,7 +80,8 @@ public function validate()
{
$dir = $this->getDirectory();
$validator = new \Dxw\Whippet\Dependencies\Validator($this->factory, $dir);
$this->exitIfError(($validator->validate()));
$enforceRefs = isset($this->options->{'enforce-refs'}) ? true : false;
$this->exitIfError(($validator->validate($enforceRefs)));
}

public function describe()
Expand Down

0 comments on commit 136546a

Please sign in to comment.