Skip to content

Commit

Permalink
allow to generate all sbom Spec versions supported by CycloneDX library
Browse files Browse the repository at this point in the history
  • Loading branch information
llaville committed Mar 12, 2023
1 parent a4981d4 commit 0ac39af
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 16 deletions.
44 changes: 30 additions & 14 deletions src/Composer/ManifestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
use CycloneDX\Core\Serialization\JsonSerializer;
use CycloneDX\Core\Serialization\XmlSerializer;
use CycloneDX\Core\Spec\SpecFactory;
use CycloneDX\Core\Spec\Version;

use KevinGH\Box\Box;
use KevinGH\Box\Configuration\Configuration;
use ValueError;
use function array_column;
use function KevinGH\Box\FileSystem\make_path_absolute;

use DomainException;
use InvalidArgumentException;
use function array_key_exists;
use function class_exists;
Expand All @@ -31,6 +35,7 @@
use function is_string;
use function pathinfo;
use function realpath;
use function sprintf;
use const PATHINFO_EXTENSION;

/**
Expand All @@ -42,22 +47,22 @@ public function __construct(private Configuration $config, private Box $box, pri
{
}

public function build(string $format, ?string $output): string
public function build(string $format, ?string $output, string $sbomSpec): string
{
return match ($format) {
'auto' => match ($output) {
null, 'manifest.txt' => $this->toText(),
'sbom.xml' => $this->toSbomXml1dot3(),
'sbom.json' => $this->toSbomJson1dot3(),
'sbom.xml' => $this->toSbom('xml', $sbomSpec),
'sbom.json' => $this->toSbom('json', $sbomSpec),
default => match (pathinfo($output, PATHINFO_EXTENSION)) {
'xml' => $this->toSbomXml1dot3(),
'json' => $this->toSbomJson1dot3(),
'xml' => $this->toSbom('xml', $sbomSpec),
'json' => $this->toSbom('json', $sbomSpec),
'', 'txt' => $this->toText(),
}
},
'plain' => $this->toText(),
'ansi' => $this->toHighlight(),
'sbom' => $this->toSbomJson1dot3(),
'sbom' => $this->toSbom('json', $sbomSpec),
default => class_exists($format)
? self::create($format, $this->config, $this->box)
: throw new InvalidArgumentException(sprintf('Format "%s" is not supported', $format))
Expand Down Expand Up @@ -150,15 +155,26 @@ public function toHighlight(): ?string
return self::create(new DecorateTextManifestBuilder(), $this->config, $this->box);
}

public function toSbomXml1dot3(): ?string
public function toSbom(string $format, string $specVersion): ?string
{
$xmlSerializer = new XmlSerializer(new DomNormalizerFactory(SpecFactory::make1dot3()));
return self::create(new SbomManifestBuilder($xmlSerializer, $this->boxVersion), $this->config, $this->box);
}
try {
$version = Version::from($specVersion);
} catch (ValueError) {
throw new DomainException(
sprintf(
'Unsupported spec version "%s" for SBOM format. Expected one of these values: %s',
$specVersion,
implode(', ', array_column(Version::cases(), 'value'))
)
);
}
$spec = SpecFactory::makeForVersion($version);

public function toSbomJson1dot3(): ?string
{
$jsonSerializer = new JsonSerializer(new JsonNormalizerFactory(SpecFactory::make1dot3()));
return self::create(new SbomManifestBuilder($jsonSerializer, $this->boxVersion), $this->config, $this->box);
$serializer = match ($format) {
'xml' => new XmlSerializer(new DomNormalizerFactory($spec)),
'json' => new JsonSerializer(new JsonNormalizerFactory($spec)),
default => throw new DomainException(sprintf('Format "%s" is not supported.', $format)),
};
return self::create(new SbomManifestBuilder($serializer, $this->boxVersion), $this->config, $this->box);
}
}
17 changes: 15 additions & 2 deletions src/Console/Command/Manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

use Bartlett\BoxManifest\Composer\ManifestFactory;

use CycloneDX\Core\Spec\Version;

use Fidry\Console\Command\CommandAware;
use Fidry\Console\Command\CommandAwareness;
use Fidry\Console\Command\Configuration as CommandConfiguration;
Expand All @@ -27,9 +29,11 @@
use Symfony\Component\Console\Output\StreamOutput;

use stdClass;
use function array_column;
use function fclose;
use function file_exists;
use function fopen;
use function implode;
use function sprintf;

/**
Expand All @@ -50,6 +54,7 @@ final class Manifest implements CommandAware, LazyCommand

private const BOOTSTRAP_OPTION = 'bootstrap';
private const FORMAT_OPTION = 'format';
private const SBOM_SPEC_OPTION = 'sbom-spec';
private const OUTPUT_OPTION = 'output-file';

public function __construct(private string $header)
Expand All @@ -73,6 +78,13 @@ public function getConfiguration(): CommandConfiguration
'Format of the output: auto, plain, ansi, sbom',
'auto'
),
new InputOption(
self::SBOM_SPEC_OPTION,
's',
InputOption::VALUE_REQUIRED,
'SBOM specification version: ' . implode(', ', array_column(Version::cases(), 'value')),
'1.4'
),
new InputOption(
self::OUTPUT_OPTION,
'o',
Expand All @@ -89,7 +101,7 @@ public function getConfiguration(): CommandConfiguration
];

return new CommandConfiguration(
// The name of the command (the part after "bin/console")
// The name of the command (the part after "bin/console")
static::getName(),
// The short description shown while running "php bin/console list"
static::getDescription(),
Expand Down Expand Up @@ -123,9 +135,10 @@ public function execute(IO $io): int

$output = $io->getOption(self::OUTPUT_OPTION)->asNullableString();
$format = $io->getOption(self::FORMAT_OPTION)->asString();
$sbomSpec = $io->getOption(self::SBOM_SPEC_OPTION)->asString();

$factory = new ManifestFactory($config, $box, get_box_version());
$manifest = $factory->build($format, $output);
$manifest = $factory->build($format, $output, $sbomSpec);

if ($io->isVerbose() || empty($output)) {
$io->writeln($manifest);
Expand Down

0 comments on commit 0ac39af

Please sign in to comment.