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

Know more about PHAR build contents #841

Closed
llaville opened this issue Jan 25, 2023 · 26 comments
Closed

Know more about PHAR build contents #841

llaville opened this issue Jan 25, 2023 · 26 comments

Comments

@llaville
Copy link
Contributor

Feature Request

Those who know me a little, already know that I've tried in past to include a manifest into the official BOX project.
Even if this feature is not available, a fork with patch was born : https://github.com/llaville/box-manifest

That allow to include in metadata field, the list of dependency constraints and versions installed. Something like this :

info

Now, with this feature request, I would like to ask if we could see the BOX version used to build the PHAR contents with the box info command.
Contents such as we see with box --version command.

That will allow to learn more about PHAR version generated, and perharps diagnose possible issues !

What do you think about this little add-on ?

Box info command will look like:

Box version 4.2.0@afc3a47 2022-11-21 22:20:19 UTC
API Version: 1.1.0

Compression: GZ

Signature: SHA-1
Signature Hash: 6E7E8BD57996B6B907BD3606C5B5A3996ED068BF

Metadata:

Contents: 1487 files (11.91MB)

 // Use the --list|-l option to list the content of the PHAR.
@theofidry
Copy link
Member

Hi @llaville!

I do remember your work on this, and had it in the back of my mind ever since then ;) Recently there's been some work on SBOM which in my mind is a perfect fit between what you're doing, and providing an internationally supported and understood format.

I briefly remember https://github.com/CycloneDX/cyclonedx-php-composer but ideally, after talking with Sebastian Bergmann, I think it is kind of expected of Composer to provide this at some point.

I unfortunately could not dig into any of this any further. I do not know if there is any alternative to cycloneDX, how it is expected to be shipped & co. Also even with it, I think it would be interesting to have a human readable format like you are proposing. But maybe this one can be based on the SBOM as the source of truth instead?

I am also not sure if this should be in the Metadata section and instead maybe it could be an entirely new section.

WDYT?

@llaville
Copy link
Contributor Author

Hello Théo,

Thanks for your feedback and especially to point to me the SBOM standard solution.
If it's related to my work on a PHAR manifest, I think it's could be pretty cool to have a possibility to embed such results into a PHAR.
I don't think it may be too much difficult to have a bridge with https://github.com/CycloneDX/cyclonedx-php-library and my fork of BOX v4 (https://github.com/llaville/box-manifest). I'll investigate later, when I'll have finished the major rewrites of https://github.com/overtrue/phplint v9.0

But, this feature report is not to talk about a manifest or SBOM or something equivalent. No, this report is just to add a little version about the product maker (BOX v4), as an indicator like API version.

Always ready to heard your proposals about BOX. I like this project.

@llaville
Copy link
Contributor Author

llaville commented Feb 9, 2023

As my works on PHPLint 9.0 is over, I'll be able now to work on a version of BOX Manifest that support SBOM format.
Keep an eye open, solution will come in next days ...

@llaville
Copy link
Contributor Author

llaville commented Feb 9, 2023

@theofidry Integration of CycloneDX SBOM feature is very easy.
Code is ready for preview: Need more tests and polish for a final version !!!

An operational prototype is already available (see commit llaville/box-manifest@75fd437) on my repository (sbom branch).

IMPORTANT notes:

If you want to give it a try for another project than BOX-Manifest itself, don't forget to provide --boostrap vendor/autoload.php (to load your project autoloader) on box compile invocation.

But If you review code of static manifest builder calls, a new specification may be include easily : https://github.com/llaville/box-manifest/blob/sbom/src/Composer/ManifestFactory.php#L97-L105

Here are some examples of SBOM manifest production:

XML format (for specification 1.3)

With "metadata": "Bartlett\\BoxManifest\\Composer\\ManifestFactory::toSbomXml1dot3" setting in your box.json config file

Output of `box compile` command
Box version 4.2.0@afc3a47

 // Loading the configuration file "/shared/backups/bartlett/box-manifest/box.json".

🔨  Building the PHAR "/shared/backups/bartlett/box-manifest/box-manifest.phar"

? No compactor to register
? Adding main file: /shared/backups/bartlett/box-manifest/bin/box
? Adding requirements checker
? Adding binary files
    > 24 file(s)
? Auto-discover files? No
? Exclude dev files? Yes
? Adding files
    > 3181 file(s)
? Generating new stub
  - Using shebang line: #!/usr/bin/env php
  - Using banner:
    > Generated by Humbug Box 4.2.0@afc3a47.
    >
    > @link https://github.com/humbug/box
? Setting metadata
  - Using composer.json : /shared/backups/bartlett/box-manifest/composer.json
  - Using composer.lock : /shared/backups/bartlett/box-manifest/composer.lock
  - <?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.3" version="1">
  <components>
    <component type="library" bom-ref="BomRef.63e4db60af06b9.33832544">
      <name><![CDATA[bartlett/box-manifest]]></name>
      <version><![CDATA[2.x-dev@781abd9]]></version>
      <description><![CDATA[Create a manifest to a PHP Archive (PHAR) for the BOX project (https://github.com/box-project/box)]]></description>
      <licenses>
        <license>
          <id><![CDATA[MIT]]></id>
        </license>
      </licenses>
      <purl><![CDATA[pkg:pkg/composer/bartlett/box-manifest@2.x-dev%40781abd9]]></purl>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0765.72056477">
      <name><![CDATA[amphp/amp]]></name>
      <version><![CDATA[v2.6.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af07c4.49693879">
      <name><![CDATA[amphp/byte-stream]]></name>
      <version><![CDATA[v1.8.1]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0828.99947060">
      <name><![CDATA[amphp/parallel]]></name>
      <version><![CDATA[v1.4.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0879.09361219">
      <name><![CDATA[amphp/parallel-functions]]></name>
      <version><![CDATA[v1.1.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af08c9.01676642">
      <name><![CDATA[amphp/parser]]></name>
      <version><![CDATA[v1.1.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0928.93118982">
      <name><![CDATA[amphp/process]]></name>
      <version><![CDATA[v1.1.4]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0975.41876408">
      <name><![CDATA[amphp/serialization]]></name>
      <version><![CDATA[v1.0.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af09c5.37482634">
      <name><![CDATA[amphp/sync]]></name>
      <version><![CDATA[v1.4.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0a29.75578812">
      <name><![CDATA[composer/ca-bundle]]></name>
      <version><![CDATA[1.3.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0a77.70899659">
      <name><![CDATA[composer/class-map-generator]]></name>
      <version><![CDATA[1.0.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0ad7.07160633">
      <name><![CDATA[composer/composer]]></name>
      <version><![CDATA[2.5.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0b24.93850498">
      <name><![CDATA[composer/metadata-minifier]]></name>
      <version><![CDATA[1.0.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0b79.49487430">
      <name><![CDATA[composer/pcre]]></name>
      <version><![CDATA[3.1.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0bd0.07782255">
      <name><![CDATA[composer/semver]]></name>
      <version><![CDATA[3.3.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0c26.90570614">
      <name><![CDATA[composer/spdx-licenses]]></name>
      <version><![CDATA[1.5.7]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0c85.80806620">
      <name><![CDATA[composer/xdebug-handler]]></name>
      <version><![CDATA[3.0.3]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0ed0.39656576">
      <name><![CDATA[cweagans/composer-patches]]></name>
      <version><![CDATA[1.7.3]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0f33.17805410">
      <name><![CDATA[cyclonedx/cyclonedx-library]]></name>
      <version><![CDATA[v1.6.3]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af0f90.12536240">
      <name><![CDATA[fidry/console]]></name>
      <version><![CDATA[0.5.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af11d7.76724527">
      <name><![CDATA[humbug/box]]></name>
      <version><![CDATA[4.2.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1247.78731507">
      <name><![CDATA[humbug/php-scoper]]></name>
      <version><![CDATA[0.18.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af12a1.19575157">
      <name><![CDATA[jetbrains/phpstorm-stubs]]></name>
      <version><![CDATA[v2022.3]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1308.99008977">
      <name><![CDATA[justinrainbow/json-schema]]></name>
      <version><![CDATA[5.2.12]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af14c6.30073505">
      <name><![CDATA[laravel/serializable-closure]]></name>
      <version><![CDATA[v1.3.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1533.96577275">
      <name><![CDATA[nikic/iter]]></name>
      <version><![CDATA[v2.2.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af15a9.84231214">
      <name><![CDATA[nikic/php-parser]]></name>
      <version><![CDATA[v4.15.3]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1627.82971049">
      <name><![CDATA[package-url/packageurl-php]]></name>
      <version><![CDATA[1.0.4]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1699.90760433">
      <name><![CDATA[paragonie/constant_time_encoding]]></name>
      <version><![CDATA[v2.6.3]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1706.69021979">
      <name><![CDATA[paragonie/pharaoh]]></name>
      <version><![CDATA[v0.6.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1775.55802671">
      <name><![CDATA[phpdocumentor/reflection-common]]></name>
      <version><![CDATA[2.2.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af17e1.34158040">
      <name><![CDATA[phpdocumentor/reflection-docblock]]></name>
      <version><![CDATA[5.3.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1935.51579062">
      <name><![CDATA[phpdocumentor/type-resolver]]></name>
      <version><![CDATA[1.6.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af19a7.17348585">
      <name><![CDATA[phplang/scope-exit]]></name>
      <version><![CDATA[1.0.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1a05.74488281">
      <name><![CDATA[psr/container]]></name>
      <version><![CDATA[2.0.2]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1a69.96843355">
      <name><![CDATA[psr/event-dispatcher]]></name>
      <version><![CDATA[1.0.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1c31.19447839">
      <name><![CDATA[psr/log]]></name>
      <version><![CDATA[3.0.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1d95.82658295">
      <name><![CDATA[react/promise]]></name>
      <version><![CDATA[v2.9.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1df8.89010663">
      <name><![CDATA[seld/jsonlint]]></name>
      <version><![CDATA[1.9.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1e66.03710661">
      <name><![CDATA[seld/phar-utils]]></name>
      <version><![CDATA[1.2.1]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1ec4.51210666">
      <name><![CDATA[seld/signal-handler]]></name>
      <version><![CDATA[2.0.1]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1f21.26886162">
      <name><![CDATA[swaggest/json-diff]]></name>
      <version><![CDATA[v3.10.4]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af1f86.63551834">
      <name><![CDATA[swaggest/json-schema]]></name>
      <version><![CDATA[v0.12.41]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2117.58081631">
      <name><![CDATA[symfony/console]]></name>
      <version><![CDATA[v6.2.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2179.54907157">
      <name><![CDATA[symfony/deprecation-contracts]]></name>
      <version><![CDATA[v3.2.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af21e6.12679875">
      <name><![CDATA[symfony/event-dispatcher-contracts]]></name>
      <version><![CDATA[v3.2.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2248.71723997">
      <name><![CDATA[symfony/filesystem]]></name>
      <version><![CDATA[v6.2.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2384.41663867">
      <name><![CDATA[symfony/finder]]></name>
      <version><![CDATA[v6.2.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af23e3.70878406">
      <name><![CDATA[symfony/polyfill-ctype]]></name>
      <version><![CDATA[v1.27.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2440.23966030">
      <name><![CDATA[symfony/polyfill-intl-grapheme]]></name>
      <version><![CDATA[v1.27.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af25f4.91551612">
      <name><![CDATA[symfony/polyfill-intl-normalizer]]></name>
      <version><![CDATA[v1.27.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2667.32567055">
      <name><![CDATA[symfony/polyfill-mbstring]]></name>
      <version><![CDATA[v1.27.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af27a2.60198123">
      <name><![CDATA[symfony/polyfill-php73]]></name>
      <version><![CDATA[v1.27.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af27f9.04760373">
      <name><![CDATA[symfony/process]]></name>
      <version><![CDATA[v6.2.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2850.48262492">
      <name><![CDATA[symfony/serializer]]></name>
      <version><![CDATA[v6.2.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af28b4.45182365">
      <name><![CDATA[symfony/service-contracts]]></name>
      <version><![CDATA[v3.2.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2900.26516787">
      <name><![CDATA[symfony/string]]></name>
      <version><![CDATA[v6.2.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2968.13175245">
      <name><![CDATA[symfony/var-dumper]]></name>
      <version><![CDATA[v6.2.5]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2aa4.59835856">
      <name><![CDATA[thecodingmachine/safe]]></name>
      <version><![CDATA[v2.4.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2af5.82966449">
      <name><![CDATA[ulrichsg/getopt-php]]></name>
      <version><![CDATA[v3.4.0]]></version>
    </component>
    <component type="library" bom-ref="BomRef.63e4db60af2b55.68568814">
      <name><![CDATA[webmozart/assert]]></name>
      <version><![CDATA[1.11.0]]></version>
    </component>
  </components>
  <dependencies>
    <dependency ref="BomRef.63e4db60af06b9.33832544"/>
    <dependency ref="BomRef.63e4db60af0765.72056477"/>
    <dependency ref="BomRef.63e4db60af07c4.49693879"/>
    <dependency ref="BomRef.63e4db60af0828.99947060"/>
    <dependency ref="BomRef.63e4db60af0879.09361219"/>
    <dependency ref="BomRef.63e4db60af08c9.01676642"/>
    <dependency ref="BomRef.63e4db60af0928.93118982"/>
    <dependency ref="BomRef.63e4db60af0975.41876408"/>
    <dependency ref="BomRef.63e4db60af09c5.37482634"/>
    <dependency ref="BomRef.63e4db60af0a29.75578812"/>
    <dependency ref="BomRef.63e4db60af0a77.70899659"/>
    <dependency ref="BomRef.63e4db60af0ad7.07160633"/>
    <dependency ref="BomRef.63e4db60af0b24.93850498"/>
    <dependency ref="BomRef.63e4db60af0b79.49487430"/>
    <dependency ref="BomRef.63e4db60af0bd0.07782255"/>
    <dependency ref="BomRef.63e4db60af0c26.90570614"/>
    <dependency ref="BomRef.63e4db60af0c85.80806620"/>
    <dependency ref="BomRef.63e4db60af0ed0.39656576"/>
    <dependency ref="BomRef.63e4db60af0f33.17805410"/>
    <dependency ref="BomRef.63e4db60af0f90.12536240"/>
    <dependency ref="BomRef.63e4db60af11d7.76724527"/>
    <dependency ref="BomRef.63e4db60af1247.78731507"/>
    <dependency ref="BomRef.63e4db60af12a1.19575157"/>
    <dependency ref="BomRef.63e4db60af1308.99008977"/>
    <dependency ref="BomRef.63e4db60af14c6.30073505"/>
    <dependency ref="BomRef.63e4db60af1533.96577275"/>
    <dependency ref="BomRef.63e4db60af15a9.84231214"/>
    <dependency ref="BomRef.63e4db60af1627.82971049"/>
    <dependency ref="BomRef.63e4db60af1699.90760433"/>
    <dependency ref="BomRef.63e4db60af1706.69021979"/>
    <dependency ref="BomRef.63e4db60af1775.55802671"/>
    <dependency ref="BomRef.63e4db60af17e1.34158040"/>
    <dependency ref="BomRef.63e4db60af1935.51579062"/>
    <dependency ref="BomRef.63e4db60af19a7.17348585"/>
    <dependency ref="BomRef.63e4db60af1a05.74488281"/>
    <dependency ref="BomRef.63e4db60af1a69.96843355"/>
    <dependency ref="BomRef.63e4db60af1c31.19447839"/>
    <dependency ref="BomRef.63e4db60af1d95.82658295"/>
    <dependency ref="BomRef.63e4db60af1df8.89010663"/>
    <dependency ref="BomRef.63e4db60af1e66.03710661"/>
    <dependency ref="BomRef.63e4db60af1ec4.51210666"/>
    <dependency ref="BomRef.63e4db60af1f21.26886162"/>
    <dependency ref="BomRef.63e4db60af1f86.63551834"/>
    <dependency ref="BomRef.63e4db60af2117.58081631"/>
    <dependency ref="BomRef.63e4db60af2179.54907157"/>
    <dependency ref="BomRef.63e4db60af21e6.12679875"/>
    <dependency ref="BomRef.63e4db60af2248.71723997"/>
    <dependency ref="BomRef.63e4db60af2384.41663867"/>
    <dependency ref="BomRef.63e4db60af23e3.70878406"/>
    <dependency ref="BomRef.63e4db60af2440.23966030"/>
    <dependency ref="BomRef.63e4db60af25f4.91551612"/>
    <dependency ref="BomRef.63e4db60af2667.32567055"/>
    <dependency ref="BomRef.63e4db60af27a2.60198123"/>
    <dependency ref="BomRef.63e4db60af27f9.04760373"/>
    <dependency ref="BomRef.63e4db60af2850.48262492"/>
    <dependency ref="BomRef.63e4db60af28b4.45182365"/>
    <dependency ref="BomRef.63e4db60af2900.26516787"/>
    <dependency ref="BomRef.63e4db60af2968.13175245"/>
    <dependency ref="BomRef.63e4db60af2aa4.59835856"/>
    <dependency ref="BomRef.63e4db60af2af5.82966449"/>
    <dependency ref="BomRef.63e4db60af2b55.68568814"/>
  </dependencies>
</bom>

? Dumping the Composer autoloader

... MORE ...

JSON format (for specification 1.3)

With "metadata": "Bartlett\\BoxManifest\\Composer\\ManifestFactory::toSbomJson1dot3" setting in your box.json config file

Output of `box compile` command
Box version 4.2.0@afc3a47

 // Loading the configuration file "/shared/backups/bartlett/box-manifest/box.json".

🔨  Building the PHAR "/shared/backups/bartlett/box-manifest/box-manifest.phar"

? No compactor to register
? Adding main file: /shared/backups/bartlett/box-manifest/bin/box
? Adding requirements checker
? Adding binary files
    > 24 file(s)
? Auto-discover files? No
? Exclude dev files? Yes
? Adding files
    > 3181 file(s)
? Generating new stub
  - Using shebang line: #!/usr/bin/env php
  - Using banner:
    > Generated by Humbug Box 4.2.0@afc3a47.
    >
    > @link https://github.com/humbug/box
? Setting metadata
  - Using composer.json : /shared/backups/bartlett/box-manifest/composer.json
  - Using composer.lock : /shared/backups/bartlett/box-manifest/composer.lock
  - {
    "$schema": "http://cyclonedx.org/schema/bom-1.3.schema.json",
    "bomFormat": "CycloneDX",
    "specVersion": "1.3",
    "version": 1,
    "components": [
        {
            "bom-ref": "BomRef.63e4d9734534f6.38451246",
            "type": "library",
            "name": "bartlett/box-manifest",
            "version": "2.x-dev@781abd9",
            "description": "Create a manifest to a PHP Archive (PHAR) for the BOX project (https://github.com/box-project/box)",
            "licenses": [
                {
                    "license": {
                        "id": "MIT"
                    }
                }
            ],
            "purl": "pkg:pkg/composer/bartlett/box-manifest@2.x-dev%40781abd9"
        },
        {
            "bom-ref": "BomRef.63e4d9734535a9.32620257",
            "type": "library",
            "name": "amphp/amp",
            "version": "v2.6.2"
        },
        {
            "bom-ref": "BomRef.63e4d9734535f1.45766001",
            "type": "library",
            "name": "amphp/byte-stream",
            "version": "v1.8.1"
        },
        {
            "bom-ref": "BomRef.63e4d973453657.79591835",
            "type": "library",
            "name": "amphp/parallel",
            "version": "v1.4.2"
        },
        {
            "bom-ref": "BomRef.63e4d9734536a1.53425918",
            "type": "library",
            "name": "amphp/parallel-functions",
            "version": "v1.1.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734536f5.01557534",
            "type": "library",
            "name": "amphp/parser",
            "version": "v1.1.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453749.60432189",
            "type": "library",
            "name": "amphp/process",
            "version": "v1.1.4"
        },
        {
            "bom-ref": "BomRef.63e4d973453793.01513239",
            "type": "library",
            "name": "amphp/serialization",
            "version": "v1.0.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734537f3.95248878",
            "type": "library",
            "name": "amphp/sync",
            "version": "v1.4.2"
        },
        {
            "bom-ref": "BomRef.63e4d973453844.80145505",
            "type": "library",
            "name": "composer/ca-bundle",
            "version": "1.3.5"
        },
        {
            "bom-ref": "BomRef.63e4d973453893.65497216",
            "type": "library",
            "name": "composer/class-map-generator",
            "version": "1.0.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734538e5.83391063",
            "type": "library",
            "name": "composer/composer",
            "version": "2.5.2"
        },
        {
            "bom-ref": "BomRef.63e4d973453943.58706484",
            "type": "library",
            "name": "composer/metadata-minifier",
            "version": "1.0.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453999.05140837",
            "type": "library",
            "name": "composer/pcre",
            "version": "3.1.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734539e6.55954756",
            "type": "library",
            "name": "composer/semver",
            "version": "3.3.2"
        },
        {
            "bom-ref": "BomRef.63e4d973453a30.04146509",
            "type": "library",
            "name": "composer/spdx-licenses",
            "version": "1.5.7"
        },
        {
            "bom-ref": "BomRef.63e4d973453a93.12001829",
            "type": "library",
            "name": "composer/xdebug-handler",
            "version": "3.0.3"
        },
        {
            "bom-ref": "BomRef.63e4d973453ae7.40314373",
            "type": "library",
            "name": "cweagans/composer-patches",
            "version": "1.7.3"
        },
        {
            "bom-ref": "BomRef.63e4d973453b35.57954406",
            "type": "library",
            "name": "cyclonedx/cyclonedx-library",
            "version": "v1.6.3"
        },
        {
            "bom-ref": "BomRef.63e4d973453b84.91307449",
            "type": "library",
            "name": "fidry/console",
            "version": "0.5.5"
        },
        {
            "bom-ref": "BomRef.63e4d973453bd9.85296233",
            "type": "library",
            "name": "humbug/box",
            "version": "4.2.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453c20.34079885",
            "type": "library",
            "name": "humbug/php-scoper",
            "version": "0.18.2"
        },
        {
            "bom-ref": "BomRef.63e4d973453c80.84227468",
            "type": "library",
            "name": "jetbrains/phpstorm-stubs",
            "version": "v2022.3"
        },
        {
            "bom-ref": "BomRef.63e4d973453cd2.53088170",
            "type": "library",
            "name": "justinrainbow/json-schema",
            "version": "5.2.12"
        },
        {
            "bom-ref": "BomRef.63e4d973453d21.60672700",
            "type": "library",
            "name": "laravel/serializable-closure",
            "version": "v1.3.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453d76.20112253",
            "type": "library",
            "name": "nikic/iter",
            "version": "v2.2.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453dc8.14147066",
            "type": "library",
            "name": "nikic/php-parser",
            "version": "v4.15.3"
        },
        {
            "bom-ref": "BomRef.63e4d973453e16.92947232",
            "type": "library",
            "name": "package-url/packageurl-php",
            "version": "1.0.4"
        },
        {
            "bom-ref": "BomRef.63e4d973453e76.88297640",
            "type": "library",
            "name": "paragonie/constant_time_encoding",
            "version": "v2.6.3"
        },
        {
            "bom-ref": "BomRef.63e4d973453ec2.07295699",
            "type": "library",
            "name": "paragonie/pharaoh",
            "version": "v0.6.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453f17.99014230",
            "type": "library",
            "name": "phpdocumentor/reflection-common",
            "version": "2.2.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453f67.86064717",
            "type": "library",
            "name": "phpdocumentor/reflection-docblock",
            "version": "5.3.0"
        },
        {
            "bom-ref": "BomRef.63e4d973453fb4.10919146",
            "type": "library",
            "name": "phpdocumentor/type-resolver",
            "version": "1.6.2"
        },
        {
            "bom-ref": "BomRef.63e4d973454015.51823671",
            "type": "library",
            "name": "phplang/scope-exit",
            "version": "1.0.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454063.32484167",
            "type": "library",
            "name": "psr/container",
            "version": "2.0.2"
        },
        {
            "bom-ref": "BomRef.63e4d9734540b4.97123813",
            "type": "library",
            "name": "psr/event-dispatcher",
            "version": "1.0.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454105.15869587",
            "type": "library",
            "name": "psr/log",
            "version": "3.0.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454155.62619226",
            "type": "library",
            "name": "react/promise",
            "version": "v2.9.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734541a6.08183031",
            "type": "library",
            "name": "seld/jsonlint",
            "version": "1.9.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454205.28327426",
            "type": "library",
            "name": "seld/phar-utils",
            "version": "1.2.1"
        },
        {
            "bom-ref": "BomRef.63e4d973454251.29611770",
            "type": "library",
            "name": "seld/signal-handler",
            "version": "2.0.1"
        },
        {
            "bom-ref": "BomRef.63e4d9734542a2.89308850",
            "type": "library",
            "name": "swaggest/json-diff",
            "version": "v3.10.4"
        },
        {
            "bom-ref": "BomRef.63e4d9734542f6.01989774",
            "type": "library",
            "name": "swaggest/json-schema",
            "version": "v0.12.41"
        },
        {
            "bom-ref": "BomRef.63e4d973454342.28675285",
            "type": "library",
            "name": "symfony/console",
            "version": "v6.2.5"
        },
        {
            "bom-ref": "BomRef.63e4d973454391.75533651",
            "type": "library",
            "name": "symfony/deprecation-contracts",
            "version": "v3.2.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734543e6.61754380",
            "type": "library",
            "name": "symfony/event-dispatcher-contracts",
            "version": "v3.2.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454446.81767806",
            "type": "library",
            "name": "symfony/filesystem",
            "version": "v6.2.5"
        },
        {
            "bom-ref": "BomRef.63e4d973454492.30985668",
            "type": "library",
            "name": "symfony/finder",
            "version": "v6.2.5"
        },
        {
            "bom-ref": "BomRef.63e4d9734544e5.23377575",
            "type": "library",
            "name": "symfony/polyfill-ctype",
            "version": "v1.27.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454538.15317547",
            "type": "library",
            "name": "symfony/polyfill-intl-grapheme",
            "version": "v1.27.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454588.49421534",
            "type": "library",
            "name": "symfony/polyfill-intl-normalizer",
            "version": "v1.27.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734545d6.10792906",
            "type": "library",
            "name": "symfony/polyfill-mbstring",
            "version": "v1.27.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454627.86577271",
            "type": "library",
            "name": "symfony/polyfill-php73",
            "version": "v1.27.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454688.53312552",
            "type": "library",
            "name": "symfony/process",
            "version": "v6.2.5"
        },
        {
            "bom-ref": "BomRef.63e4d9734546d6.66926150",
            "type": "library",
            "name": "symfony/serializer",
            "version": "v6.2.5"
        },
        {
            "bom-ref": "BomRef.63e4d973454722.78083635",
            "type": "library",
            "name": "symfony/service-contracts",
            "version": "v3.2.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454771.20632414",
            "type": "library",
            "name": "symfony/string",
            "version": "v6.2.5"
        },
        {
            "bom-ref": "BomRef.63e4d9734547c2.51140716",
            "type": "library",
            "name": "symfony/var-dumper",
            "version": "v6.2.5"
        },
        {
            "bom-ref": "BomRef.63e4d973454816.67915846",
            "type": "library",
            "name": "thecodingmachine/safe",
            "version": "v2.4.0"
        },
        {
            "bom-ref": "BomRef.63e4d973454869.33785473",
            "type": "library",
            "name": "ulrichsg/getopt-php",
            "version": "v3.4.0"
        },
        {
            "bom-ref": "BomRef.63e4d9734548c4.95591137",
            "type": "library",
            "name": "webmozart/assert",
            "version": "1.11.0"
        }
    ],
    "dependencies": [
        {
            "ref": "BomRef.63e4d9734534f6.38451246"
        },
        {
            "ref": "BomRef.63e4d9734535a9.32620257"
        },
        {
            "ref": "BomRef.63e4d9734535f1.45766001"
        },
        {
            "ref": "BomRef.63e4d973453657.79591835"
        },
        {
            "ref": "BomRef.63e4d9734536a1.53425918"
        },
        {
            "ref": "BomRef.63e4d9734536f5.01557534"
        },
        {
            "ref": "BomRef.63e4d973453749.60432189"
        },
        {
            "ref": "BomRef.63e4d973453793.01513239"
        },
        {
            "ref": "BomRef.63e4d9734537f3.95248878"
        },
        {
            "ref": "BomRef.63e4d973453844.80145505"
        },
        {
            "ref": "BomRef.63e4d973453893.65497216"
        },
        {
            "ref": "BomRef.63e4d9734538e5.83391063"
        },
        {
            "ref": "BomRef.63e4d973453943.58706484"
        },
        {
            "ref": "BomRef.63e4d973453999.05140837"
        },
        {
            "ref": "BomRef.63e4d9734539e6.55954756"
        },
        {
            "ref": "BomRef.63e4d973453a30.04146509"
        },
        {
            "ref": "BomRef.63e4d973453a93.12001829"
        },
        {
            "ref": "BomRef.63e4d973453ae7.40314373"
        },
        {
            "ref": "BomRef.63e4d973453b35.57954406"
        },
        {
            "ref": "BomRef.63e4d973453b84.91307449"
        },
        {
            "ref": "BomRef.63e4d973453bd9.85296233"
        },
        {
            "ref": "BomRef.63e4d973453c20.34079885"
        },
        {
            "ref": "BomRef.63e4d973453c80.84227468"
        },
        {
            "ref": "BomRef.63e4d973453cd2.53088170"
        },
        {
            "ref": "BomRef.63e4d973453d21.60672700"
        },
        {
            "ref": "BomRef.63e4d973453d76.20112253"
        },
        {
            "ref": "BomRef.63e4d973453dc8.14147066"
        },
        {
            "ref": "BomRef.63e4d973453e16.92947232"
        },
        {
            "ref": "BomRef.63e4d973453e76.88297640"
        },
        {
            "ref": "BomRef.63e4d973453ec2.07295699"
        },
        {
            "ref": "BomRef.63e4d973453f17.99014230"
        },
        {
            "ref": "BomRef.63e4d973453f67.86064717"
        },
        {
            "ref": "BomRef.63e4d973453fb4.10919146"
        },
        {
            "ref": "BomRef.63e4d973454015.51823671"
        },
        {
            "ref": "BomRef.63e4d973454063.32484167"
        },
        {
            "ref": "BomRef.63e4d9734540b4.97123813"
        },
        {
            "ref": "BomRef.63e4d973454105.15869587"
        },
        {
            "ref": "BomRef.63e4d973454155.62619226"
        },
        {
            "ref": "BomRef.63e4d9734541a6.08183031"
        },
        {
            "ref": "BomRef.63e4d973454205.28327426"
        },
        {
            "ref": "BomRef.63e4d973454251.29611770"
        },
        {
            "ref": "BomRef.63e4d9734542a2.89308850"
        },
        {
            "ref": "BomRef.63e4d9734542f6.01989774"
        },
        {
            "ref": "BomRef.63e4d973454342.28675285"
        },
        {
            "ref": "BomRef.63e4d973454391.75533651"
        },
        {
            "ref": "BomRef.63e4d9734543e6.61754380"
        },
        {
            "ref": "BomRef.63e4d973454446.81767806"
        },
        {
            "ref": "BomRef.63e4d973454492.30985668"
        },
        {
            "ref": "BomRef.63e4d9734544e5.23377575"
        },
        {
            "ref": "BomRef.63e4d973454538.15317547"
        },
        {
            "ref": "BomRef.63e4d973454588.49421534"
        },
        {
            "ref": "BomRef.63e4d9734545d6.10792906"
        },
        {
            "ref": "BomRef.63e4d973454627.86577271"
        },
        {
            "ref": "BomRef.63e4d973454688.53312552"
        },
        {
            "ref": "BomRef.63e4d9734546d6.66926150"
        },
        {
            "ref": "BomRef.63e4d973454722.78083635"
        },
        {
            "ref": "BomRef.63e4d973454771.20632414"
        },
        {
            "ref": "BomRef.63e4d9734547c2.51140716"
        },
        {
            "ref": "BomRef.63e4d973454816.67915846"
        },
        {
            "ref": "BomRef.63e4d973454869.33785473"
        },
        {
            "ref": "BomRef.63e4d9734548c4.95591137"
        }
    ]
}
? Dumping the Composer autoloader

... MORE ...

@llaville
Copy link
Contributor Author

llaville commented Feb 9, 2023

To validate contents of SBOM generated by CycloneDX, use the https://github.com/CycloneDX/cyclonedx-cli project.

With Docker version:

REPOSITORY                      TAG                IMAGE ID       CREATED         SIZE
cyclonedx/cyclonedx-cli         latest             9548cf5241e3   4 months ago    151MB

Run following command:

docker run --rm --user $(id -u):$(id -g) --mount type=bind,source=$PWD,target=/tmp -w /tmp cyclonedx/cyclonedx-cli validate --input-file sbom.xml

Change input file sbom.xml by sbom.json depending of format generated

And you will get expected result : BOM validated successfully.

@llaville
Copy link
Contributor Author

llaville commented Feb 9, 2023

@sebastianbergmann FYI : this purpose may interrest you even if I don't consider this as a PHPUnit issue. (I use actually the latest version 10.0.7)

The PHPUnit SBOM generation script => https://github.com/sebastianbergmann/phpunit/blob/10.0.7/build/scripts/phar-manifest.php#L54 use the CycloneDX solution (specification 1.4)

But it seems that the contents generated do not pass validation : at least with https://github.com/CycloneDX/cyclonedx-cli#validate-command (that support all specifications)

Here is my try :

With Docker image

REPOSITORY                TAG      DIGEST                                                                    IMAGE ID       CREATED         SIZE
cyclonedx/cyclonedx-cli   latest   sha256:c7d71852320da2d24fdc3f3dea8895b562e411cce43abb4c6817dc155bf54689   9548cf5241e3   4 months ago    151MB
phpunit-10.0.7.phar --sbom > phpunit-10.0.7-sbom.xml
Contents of `phpunit-10.0.7-sbom.xml` file
<?xml version="1.0"?>
<bom xmlns="https://cyclonedx.org/schema/bom/1.4">
 <components>
 <components>
  <component type="library">
   <group>phpunit</group>
   <name>phpunit</name>
   <version>10.0.7</version>
   <description>The PHP Unit Testing framework.</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phpunit/phpunit@10.0.7</purl>
  </component>
  <component type="library">
   <group>myclabs</group>
   <name>deep-copy</name>
   <version>1.11.0</version>
   <description>Create deep copies (clones) of your objects</description>
   <licenses>
    <license>
     <id>MIT</id>
    </license>
   </licenses>
   <purl>pkg:composer/myclabs/deep-copy@1.11.0</purl>
  </component>
  <component type="library">
   <group>nikic</group>
   <name>php-parser</name>
   <version>v4.15.3</version>
   <description>A PHP parser written in PHP</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/nikic/php-parser@v4.15.3</purl>
  </component>
  <component type="library">
   <group>phar-io</group>
   <name>manifest</name>
   <version>2.0.3</version>
   <description>Component for reading phar.io manifest information from a PHP Archive (PHAR)</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phar-io/manifest@2.0.3</purl>
  </component>
  <component type="library">
   <group>phar-io</group>
   <name>version</name>
   <version>3.2.1</version>
   <description>Library for handling version information and constraints</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phar-io/version@3.2.1</purl>
  </component>
  <component type="library">
   <group>phpunit</group>
   <name>php-code-coverage</name>
   <version>10.0.0</version>
   <description>Library that provides collection, processing, and rendering functionality for PHP code coverage information.</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phpunit/php-code-coverage@10.0.0</purl>
  </component>
  <component type="library">
   <group>phpunit</group>
   <name>php-file-iterator</name>
   <version>4.0.0</version>
   <description>FilterIterator implementation that filters files based on a list of suffixes.</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phpunit/php-file-iterator@4.0.0</purl>
  </component>
  <component type="library">
   <group>phpunit</group>
   <name>php-invoker</name>
   <version>4.0.0</version>
   <description>Invoke callables with a timeout</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phpunit/php-invoker@4.0.0</purl>
  </component>
  <component type="library">
   <group>phpunit</group>
   <name>php-text-template</name>
   <version>3.0.0</version>
   <description>Simple template engine.</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phpunit/php-text-template@3.0.0</purl>
  </component>
  <component type="library">
   <group>phpunit</group>
   <name>php-timer</name>
   <version>6.0.0</version>
   <description>Utility class for timing</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/phpunit/php-timer@6.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>cli-parser</name>
   <version>2.0.0</version>
   <description>Library for parsing CLI options</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/cli-parser@2.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>code-unit</name>
   <version>2.0.0</version>
   <description>Collection of value objects that represent the PHP code units</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/code-unit@2.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>code-unit-reverse-lookup</name>
   <version>3.0.0</version>
   <description>Looks up which function or method a line of code belongs to</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/code-unit-reverse-lookup@3.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>comparator</name>
   <version>5.0.0</version>
   <description>Provides the functionality to compare PHP values for equality</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/comparator@5.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>complexity</name>
   <version>3.0.0</version>
   <description>Library for calculating the complexity of PHP code units</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/complexity@3.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>diff</name>
   <version>5.0.0</version>
   <description>Diff implementation</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/diff@5.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>environment</name>
   <version>6.0.0</version>
   <description>Provides functionality to handle HHVM/PHP environments</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/environment@6.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>exporter</name>
   <version>5.0.0</version>
   <description>Provides the functionality to export PHP variables for visualization</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/exporter@5.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>global-state</name>
   <version>6.0.0</version>
   <description>Snapshotting of global state</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/global-state@6.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>lines-of-code</name>
   <version>2.0.0</version>
   <description>Library for counting the lines of code in PHP source code</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/lines-of-code@2.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>object-enumerator</name>
   <version>5.0.0</version>
   <description>Traverses array structures and object graphs to enumerate all referenced objects</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/object-enumerator@5.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>object-reflector</name>
   <version>3.0.0</version>
   <description>Allows reflection of object attributes, including inherited and non-public ones</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/object-reflector@3.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>recursion-context</name>
   <version>5.0.0</version>
   <description>Provides functionality to recursively process PHP variables</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/recursion-context@5.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>type</name>
   <version>4.0.0</version>
   <description>Collection of value objects that represent the types of the PHP type system</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/type@4.0.0</purl>
  </component>
  <component type="library">
   <group>sebastian</group>
   <name>version</name>
   <version>4.0.1</version>
   <description>Library that helps with managing the version number of Git-hosted PHP projects</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/sebastian/version@4.0.1</purl>
  </component>
  <component type="library">
   <group>theseer</group>
   <name>tokenizer</name>
   <version>1.2.1</version>
   <description>A small library for converting tokenized PHP source code into XML and potentially other formats</description>
   <licenses>
    <license>
     <id>BSD-3-Clause</id>
    </license>
   </licenses>
   <purl>pkg:composer/theseer/tokenizer@1.2.1</purl>
  </component>
 </components>
</bom>
docker run --rm --user $(id -u):$(id -g) --mount type=bind,source=$PWD,target=/tmp -w /tmp cyclonedx/cyclonedx-cli validate --input-file phpunit-10.0.7-sbom.xml

Prints

Unable to validate against any XML schemas.
BOM is not valid.

@sebastianbergmann
Copy link

sebastianbergmann commented Feb 9, 2023

This is not a useful and actionable error:

Unable to validate against any XML schemas.
BOM is not valid.

Trying to use xmllint to validate PHPUnit's SBOM against the XSD fails with this error:

$ xmllint --schema cyclonedx-1.4.xsd sbom.xml --noout
error : Unknown IO error
warning: failed to load external entity "http://cyclonedx.org/schema/spdx"
cyclonedx-1.4.xsd:27: element import: Schemas parser warning : Element '{http://www.w3.org/2001/XMLSchema}import': Failed to locate a schema at location 'http://cyclonedx.org/schema/spdx'. Skipping the import.
cyclonedx-1.4.xsd:444: element element: Schemas parser error : element decl. '{http://cyclonedx.org/schema/bom/1.4}id', attribute 'type': The QName value '{http://cyclonedx.org/schema/spdx}licenseId' does not resolve to a(n) type definition.
WXS schema cyclonedx-1.4.xsd failed to compile

Not sure what is going on here. It would be helful to know what is actually wrong. But this should not be discussed here. I have opened sebastianbergmann/phpunit#5186 for this. Thank you for bringing this to my attention.

@llaville
Copy link
Contributor Author

llaville commented Feb 9, 2023

@theofidry Code is now completed. Tell me if you think it's acceptable, or if you want more !

Chunk of box compile command output with "metadata": "Bartlett\\BoxManifest\\Composer\\ManifestFactory::toSbomJson1dot3" setting on Box-Manifest project itself

? Setting metadata
  - Using composer.json : /shared/backups/bartlett/box-manifest/composer.json
  - Using composer.lock : /shared/backups/bartlett/box-manifest/composer.lock
  - {
    "$schema": "http://cyclonedx.org/schema/bom-1.3.schema.json",
    "bomFormat": "CycloneDX",
    "specVersion": "1.3",
    "version": 1,
    "metadata": {
        "tools": [
            {
                "vendor": "box-project",
                "name": "box",
                "version": "4.2.0@afc3a47"
            }
        ],
        "component": {
            "bom-ref": "BomRef.63e56378e5b904.73643295",
            "type": "application",
            "name": "box-manifest",
            "version": "2.x-dev@781abd9",
            "group": "bartlett",
            "description": "Create a manifest to a PHP Archive (PHAR) for the BOX project (https://github.com/box-project/box)",
            "licenses": [
                {
                    "license": {
                        "id": "MIT"
                    }
                }
            ],
            "purl": "pkg:composer/bartlett/box-manifest@2.x-dev%40781abd9"
        }
    },
    "components": [
        {
            "bom-ref": "BomRef.63e56378e5a414.90121867",
            "type": "library",
            "name": "amp",
            "version": "v2.6.2",
            "group": "amphp",
            "purl": "pkg:composer/amphp/amp@v2.6.2"
        },

@theofidry
Copy link
Member

Caught up with it!

So ideally I would like the SBOM to be handled by Composer itself, but I don't see any plan for that now so I'm happy to integrate it in Box.

I think however I would prefer to see it as a regular file rather than metadata. If then wouldn't need the metadata change and also could just be a regular setting.

For sure the Info command would need to be enriched to check for it and show it, the same way I would like it to give more info regarding the requirement checker.

@llaville
Copy link
Contributor Author

@theofidry I think cdxgen of CylconeDX may require your attention, because it may be generate BOM 1.4 XML or JSON results of any PHP project, even if there are still some minor issues (I've already reported in CycloneDX/cdxgen#236)

@jkowalleck
Copy link

jkowalleck commented Mar 6, 2023

re: #841 (comment)

So ideally I would like the SBOM to be handled by Composer itself [...]

Have you tried the composer plugin cyclonedx/cyclonedx-php-composer? It utilizes composer itself to gather the evidences for creating CycloneDX.
Unlike cdxgen and others, it does not need NodeJS or python installed or some other binary downloaded.

@llaville
Copy link
Contributor Author

llaville commented Mar 6, 2023

Hello @jkowalleck
As you've perharps noticed, I've already created a solution (https://github.com/llaville/box-manifest/blob/sbom/src/Composer/Manifest/SbomManifestBuilder.php) based on the cyclonedx/cyclonedx-library.

Box-Manisfest was born for historical reason, and even if it's a fork/patched version of main BOX project, I'm happy of results produced.
I regret just that the cyclonedx php lib does not support spec 1.4 ;-)

@jkowalleck
Copy link

jkowalleck commented Mar 6, 2023

Was rereffing to #841 (comment)

the manifesto you came up with is better for the job here, since not all phars are composer-based.

What features of CycloneDX 1.4 do you actually need?
There are not that many changes from 1.3 to 1.4 - just externalReferences, releaseNotes, some annotation and the big block for vulnerability-disclosure/vulnerabilities.
@llaville , please let me know, or feature-request them for the upcoming cyclonedx/cyclonedx-library@v2

@llaville
Copy link
Contributor Author

llaville commented Mar 6, 2023

@jkowalleck I don't have any new feature requests for v2. Just waiting stable release :)
And when I'll have more free time, my manifest builder should be able to use either stable spec 1.3, and upcoming 1.4 with a bridge !

@llaville
Copy link
Contributor Author

llaville commented Mar 9, 2023

@theofidry I've just created a prototype of a new Manifest command that may be able to generate any manifest results as implementations available.

Related to my question theofidry/console#145, I don't know how to lazy load any new command (e.g in the contrib namespace) without to alter the https://github.com/box-project/box/blob/4.3.7/src/Console/Application.php#L78-L91

My new manifest command invocation will look like php -d phar.readonly=0 bin/manifest contrib:add-manifest to print result on standard output (by default), but may be also able to write directly to a file that can be include later when we try to bin/box compile any project.
PS: bin/manifest is same as bin/box just for testing purpose.

box-4 3_manifest

contrib:add-manifest command is able just right now to generate results in the same format as https://github.com/llaville/box-manifest did, including SBOM format (Spec 1.3) and soon (Spec 1.4)

We are closed to realize a dream to add finally the manifest feature in official Box project.
That will allow to me to let down maintaince of my bartlett/box-manifest project.

@llaville
Copy link
Contributor Author

llaville commented Mar 9, 2023

@theofidry Meanwhile your feedback, I'll release soon the last major release 3..0.0 of bartlett/box-manifest that will support this new command rather than patching the humbug/box like I did in past with help of cweagans/composer-patches

@llaville
Copy link
Contributor Author

Final major version 3.0 of bartlett/box-manifest is ready.

I just want to polish some details and perharps prepare a bridge for CycloneDX spec 1.4 with (upcoming cyclonedx/cyclonedx-library v2.0 still in development)

But code is fully operational with full documentation (available on branch 3.x)

The Dream became a reality :

  • a simple command application (bin/box-manifest) to generate a file manifest
  • the file manifest may be included as a standard file to PHAR contents or easily attached to the metadata field of the PHP Archive when invoking default bin/box compile command !

@llaville
Copy link
Contributor Author

And to conclude my implementation, an example of free format and how to build it !
See llaville/box-manifest@8984932

Preview, when BOX compile with its contents !

custom-manifest

@theofidry
Copy link
Member

Thank you @llaville, will check it out ASAP

@llaville
Copy link
Contributor Author

llaville commented Mar 13, 2023

In case of anybody want to use it as a bridge, here are with commit llaville/box-manifest@261d1ee an example script to follow !

And console logs to preview, if you don't have a chance or time to run it !

@llaville
Copy link
Contributor Author

With PR 925 my work on adding a manifest feature to official BOX project is now completed (for me).

Awaiting feedbacks

@theofidry
Copy link
Member

I think with the emergence of the BOM standard, it makes more sense to go towards that solution rather than arbitrary alternative manifest formats. I think PHPUnit was a good and interesting source of inspiration and I like the initial proposal of the manifest that you did, but unlike PHPUnit, we do not need a special format so picking the standard makes more sense.

So reviewing your work and the PR, my initial thoughts are:

  • the manifest setting 👍 , but then could be simply true|false (and default to true, instead of false)
  • I like the idea of displaying its content in the compile command, but it's likely a bit too verbose. So maybe it should be there in verbose mode only? But I'm wondering if it's really relevant in the compile output
  • the location: currently you are leaning towards the metadata which I think is not a bad choice. I however like how much easier it is to inspect a file rather than the metadata, e.g. for the requirements shipped in the PHAR (you just need to open .box/.requirements.php). So maybe it would make more sense to ship a sbom.xml file in the PHAR instead.
  • it should be easy to see this information, and for that I think the output (the nice table you rendered in the compile command), could instead be in the info command.
  • I am not too sure I understood why the stub was changed in Add new manifest option for configuration #925?
  • what does the contrib:add-manifest does exactly? I think it could be interesting to generate a manifest for a given composer based project. Maybe it would be easier to do so only for a Box project as it means mostly re-using code that is used elsewhere (the manifest generator & the rendered from the info command).

It's a bit late so might be a bit messy...

@llaville
Copy link
Contributor Author

To summarize the situation that have changed since last time.

  1. If I've well understood, you don't want to have multiple manifest format supported, but I'm opposite to this idea (sorry) !
    I want that the final users are free to choose the format that will match their needs: plain text, decorated text, SBOM (XML or JSON) and everything else.

    This is the reason why I'll keep the BOX-Manifest project opened (and will publish a major version 3.0)

  2. I've closed PR Add new manifest option for configuration #925 because we can solve it with default stub setting and a custom version (e.g: llaville/box-manifest@07f14a0)

Purpose of this stub version is to display one of the manifest file it could found into root of the PHP Archive
(choice are : first find on the priority list ['manifest.txt', 'manifest.xml', 'sbom.xml', 'sbom.json'], or a specific file identified)

Example runs:

command $ ./app-fixtures.phar --manifest man.txt
 output $ Manifest "man.txt" is not available in this PHP Archive.
command $ ./app-fixtures.phar --manifest
 output $ 
<?xml version="1.0" encoding="UTF-8"?>
<bom xmlns="http://cyclonedx.org/schema/bom/1.4" version="1">
  <metadata>
    <tools>
      <tool>
        <vendor><![CDATA[box-project]]></vendor>
        <name><![CDATA[box]]></name>
        <version><![CDATA[4.3.8@5534406]]></version>
      </tool>
    </tools>
  </metadata>
  <components>
    <component type="library" bom-ref="pkg:composer/psr/log@3.0.0">
      <group><![CDATA[psr]]></group>
      <name><![CDATA[log]]></name>
      <version><![CDATA[3.0.0]]></version>
      <purl><![CDATA[pkg:composer/psr/log@3.0.0]]></purl>
    </component>
  </components>
  <dependencies>
    <dependency ref="pkg:composer/psr/log@3.0.0"/>
  </dependencies>
</bom>
  1. BOX-Manifest 3.0 has code refactorized again since last time. The new manifest command in now a pure Symfony Command,
    to avoid all questions about fidry/console.

There are two binary commands :

Thanks to symfony/runtime that allow to make it so easy. BTW I've an enhanced version of your autoload_runtime.templateto support PHAR !

Sources :

@llaville
Copy link
Contributor Author

I've just finished to write a tutorial to learn about BOX-Manifest v3 features.
This feature request is no more necessary, because all behaviors (at least on my side) have now a solution.

  • how to display a manifest from a PHAR file (with a custom stub)
  • add and use one or more manifests (in different format) from a single file phar resource or from the PHAR metadata field

@theofidry
Copy link
Member

Would you be open to do a voice call over this topic? I do have several questions but feel like there would be a lot of back and forth (and we already had some)

@llaville
Copy link
Contributor Author

Time for contribution is now over !
Answers and solutions are available with https://github.com/llaville/box-manifest/releases/tag/3.0.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants