shamblett/sbom

PathNotFoundException exception

Closed this issue · 13 comments

Context

Firs of all, thanks for developing this library. It is a necessity to have a unified and easy way to build a SBOM document.

Now, I installed the package globally using the command:

dart pub global activate sbom

I create an sbom.yaml file in the root of my project and execute the command sbom as the instructions say. That throw me the following output without a proper result:

SBOM generator for Dart packages
Parsing SBOM configuration file
Generating the SBOM
SBOM type is SPDX
Building SPDX sections
Building SPDX Document Creation section
Building SPDX Package section
WARN: File Support - license file not found - license information cannot be extracted
Unhandled exception:
PathNotFoundException: Directory listing failed, path = '/PATH/TO/MY/APP/FOLDER/lib/src/spdx/licences/' (OS Error: No such file or directory, errno = 2)
#0      _Directory._fillWithDirectoryListing (dart:io-patch/directory_patch.dart:42:24)
#1      _Directory.listSync (dart:io/directory_impl.dart:233:5)
#2      SbomSpdxLicense._licenseList (package:sbom/src/spdx/sbom_spdx_license.dart:85:30)
#3      new SbomSpdxLicense (package:sbom/src/spdx/sbom_spdx_license.dart:60:5)
#4      SbomSpdxOutputGenerator._buildPackage (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:121:9)
#5      SbomSpdxOutputGenerator.build (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:262:14)
#6      SbomGenerator.generate (package:sbom/src/generation/sbom_generator.dart:50:25)
#7      main (file:///Users/joaquinricci/.pub-cache/hosted/pub.dev/sbom-1.0.4/bin/sbom.dart:34:13)
#8      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:33)
#9      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)

It seems to me that it is wrongly using the sbom library PATH from the projects root folder to find its needed files (src/spdx/licences). What am I doing wrong?

Thanks in advance for the help.

Hi, I don't think you are doing anything wrong, I'll look at this, what platform are you on and is this a flutter project?

I am using a Mac with M3 chip. The project is actually a flutter project with dart 2.19.0.

I haven't got a Mac to test on however we could rule this out by trying to generate an SBOM for a Dart project.

If you have a Dart(not flutter) project you can use that otherwise just pull a Dart package repo from pub, do dart pub get and copy your sbom.yaml into it. Try and generate and SBOM for it.

Hi,
thanks for creating this library!
I've encountered the same issue when generating an SBOM for a Flutter project on my M2 Pro Macbook.

I did test it with a pure dart project as you suggested on blurhash-dart (picked randomly) and got the same error:

blurhash-dart % sbom                                      
SBOM generator for Dart packages
Parsing SBOM configuration file
Generating the SBOM
SBOM type is SPDX
Unhandled exception:
PathNotFoundException: Directory listing failed, path = '/PATH/TO/MY/FOLDER/blurhash-dart/lib/src/spdx/licences/' (OS Error: No such file or directory, errno = 2)
#0      _Directory._fillWithDirectoryListing (dart:io-patch/directory_patch.dart:42:24)
#1      _Directory.listSync (dart:io/directory_impl.dart:228:5)
#2      SbomSpdxLicense._licenseList (package:sbom/src/spdx/sbom_spdx_license.dart:85:30)
#3      new SbomSpdxLicense (package:sbom/src/spdx/sbom_spdx_license.dart:60:5)
#4      SbomSpdxOutputGenerator._buildPackage (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:121:9)
#5      SbomSpdxOutputGenerator.build (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:262:14)
#6      SbomGenerator.generate (package:sbom/src/generation/sbom_generator.dart:50:25)
#7      main (file:///Users/wojciechdawiskiba/.pub-cache/hosted/pub.dev/sbom-2.0.2/bin/sbom.dart:34:13)
#8      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:33)
#9      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Ok thanks, I'll look at this.

OK, could you please set this env var to the path to your pub cache, PUB_CACHE, this setting should take precedence over the package trying to work this out, which on a Mac will be -

${env['HOME']}/.pub-cache');

@shamblett I tried the following but got the same error

blurhash-dart % export PATH="$PATH":"$HOME/.pub-cache/"
blurhash-dart % sbom
SBOM generator for Dart packages
Parsing SBOM configuration file
Generating the SBOM
SBOM type is SPDX
Unhandled exception:
PathNotFoundException: Directory listing failed, path = '/(redacted_path)r/blurhash-dart/lib/src/spdx/licences/' (OS Error: No such file or directory, errno = 2)
#0      _Directory._fillWithDirectoryListing (dart:io-patch/directory_patch.dart:42:24)
#1      _Directory.listSync (dart:io/directory_impl.dart:228:5)
#2      SbomSpdxLicense._licenseList (package:sbom/src/spdx/sbom_spdx_license.dart:85:30)
#3      new SbomSpdxLicense (package:sbom/src/spdx/sbom_spdx_license.dart:60:5)
#4      SbomSpdxOutputGenerator._buildPackage (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:121:9)
#5      SbomSpdxOutputGenerator.build (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:262:14)
#6      SbomGenerator.generate (package:sbom/src/generation/sbom_generator.dart:50:25)
#7      main (file:///Users/wojciechdawiskiba/.pub-cache/hosted/pub.dev/sbom-2.0.2/bin/sbom.dart:34:13)
#8      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:33)
#9      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Thanks, sorry I may have confused you with my comment above, could you try -
'''
export PUB_CACHE = "$HOME/.pub-cache/"

is what I meant.


Sorry, I must have confused it along the way.
I'm still getting the same issue

blurhash-dart % export PUB_CACHE="$HOME/.pub-cache/"
blurhash-dart % sbom                                 
SBOM generator for Dart packages
Parsing SBOM configuration file
Generating the SBOM
SBOM type is SPDX
Unhandled exception:
PathNotFoundException: Directory listing failed, path = '/Users/wojciechdawiskiba/Desktop/Flutter/blurhash-dart/lib/src/spdx/licences/' (OS Error: No such file or directory, errno = 2)
#0      _Directory._fillWithDirectoryListing (dart:io-patch/directory_patch.dart:42:24)
#1      _Directory.listSync (dart:io/directory_impl.dart:228:5)
#2      SbomSpdxLicense._licenseList (package:sbom/src/spdx/sbom_spdx_license.dart:85:30)
#3      new SbomSpdxLicense (package:sbom/src/spdx/sbom_spdx_license.dart:60:5)
#4      SbomSpdxOutputGenerator._buildPackage (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:121:9)
#5      SbomSpdxOutputGenerator.build (package:sbom/src/spdx/generation/sbom_spdx_output_generator.dart:262:14)
#6      SbomGenerator.generate (package:sbom/src/generation/sbom_generator.dart:50:25)
#7      main (file:///Users/wojciechdawiskiba/.pub-cache/hosted/pub.dev/sbom-2.0.2/bin/sbom.dart:34:13)
#8      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:295:33)
#9      _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

Hi! I ran into this problem too and tried to figure it out if I can solve it on my own. Is the code trying to access the license files from the package directory? I can see that you're using the pub_cache package to do this which has been discontinued. I think a more reliable way to do this at the moment is to use Isolate.resolvePackageUriSync or Isolate.resolvePackageUri. Like in the following:

  final licenseUri = Isolate.resolvePackageUriSync(
    Uri.parse('package:sbom/src/spdx/licences'),
  );
  if (licenseUri == null) {
    throw Exception('Unable to resolve package path. Script will not work.');
  }
  final licenseDirectoryPath = licenseUri.path;

If it's helpful, I pushed some sort of fix on my fork which you can use as a starting point.

Yes I spotted that the pub_cache package has been discontinued and decided to fix this also. The google guys seem to suggest to use the command 'dart pub cache list' to get a list of packages in the pub cache, this gives versions and absolute paths as a json structure. Your solution above seems a bit more elegant though I'll have a look at it, presumably resolvePackageUriSync returns the path to the latest version.

Either way we need to get rid of pub_cache and implement a generic solution that works across all platforms.

Using this code snippet -

import 'dart:io';
import 'dart:isolate';

void main() {
  final licenseUri = Isolate.resolvePackageUriSync(
    Uri.parse('package:sbom/src/spdx/licences'),
  );
  if (licenseUri == null) {
    print('License Uri is null...');
  } else {
    print('Licence path is  ${licenseUri.path}');
  }
  
}

If I run this from the home directory say it prints 'License Uri is null...' even though sbom is definitely installed on this machine, running 'sbom' from the same location gives -

SBOM generator for Dart packages
Parsing SBOM configuration file
ERROR: Cannot read SBOM configuration file, path is /home/steve/Development/google/dart/sbom.yaml,  cannot continue
ERROR: Cannot read package pubspec file, path is /home/steve/Development/google/dart/pubspec.yaml,  cannot continue

If I run the code snippet from the top level of a package(which has a full .dart_tools directory and pubspec.yaml etc) it does the same i.e. prints the licence Uri is null.

It does work if I update the sbom code to use it however, i.e. when its inside the sbom package.

So I'm not sure this will do the trick, in all cases .I think I'll fall back to my less elegant but maybe more robust solution

The only sane way to do this is to generate a complete list of all the SPDX files into one json file and convert this into a Dart list. This should now work anywhere, see PR #15.

Package re published at version 2.0.3