NotADirectoryError when trying to build a snap with a part using local source

Hello,

I’m trying to build a snap that uses a local directory, but it fails with a NotADirectoryError.

I’m using Ubuntu 18.04, snapcraft 2.42.1 (1594) installed as a classic snap and lxd 3.4 (8297), as explained in the tutorial.

The snap/snapcraft.yaml is located in this local dir: /home/pierre/dev/checkbox-project/providers/checkbox-oem-qa

In the snapcraft.yaml file, I try to use the local source-type:

...
  oem-qa-checkbox:
    plugin: plainbox-provider
    source: /home/pierre/dev/checkbox-project/providers/oem-plainbox
    source-type: local
    ...

This part is indeed located in that directory:

$ ll /home/pierre/dev/checkbox-project/providers/oem-plainbox                                                                        master支
total 52K
drwxr-xr-x 11 pierre pierre 4.0K Nov  8  2017 .
drwxr-xr-x 15 pierre pierre 4.0K Aug  8 11:09 ..
drwxr-xr-x  2 pierre pierre 4.0K Dec 20  2017 bin
drwxr-xr-x  2 pierre pierre 4.0K Dec 20  2017 data
drwxr-xr-x  2 pierre pierre 4.0K Aug 17 15:55 debian
drwxr-xr-x  6 pierre pierre 4.0K Nov  8  2017 etc
...

But when I run snapcraft cleanbuild, I get the following error:

Pulling oem-qa-checkbox                                            
Sorry, Snapcraft ran into an error when trying to running through its                                                                                                                        
lifecycle that generated the following traceback:                                                                                                                                            
Traceback (most recent call last):                                                          
  File "/snap/snapcraft/1594/bin/snapcraft", line 11, in <module>                                                                                                                            
    load_entry_point('snapcraft==2.42.1', 'console_scripts', 'snapcraft')()
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/click/core.py", line 722, in __call__                                                                                               
    return self.main(*args, **kwargs)
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)                                           
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)                  
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/cli/lifecycle.py", line 135, in snap
    project_options, directory=directory, output=output)      
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/lifecycle/_packer.py", line 46, in snap
    execute('prime', project_options)                                                                                                                                                        
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/lifecycle/_runner.py", line 79, in execute
    _Executor(config, project_options).run(step, part_names)
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/lifecycle/_runner.py", line 191, in run
    self._run_step(step, part, part_names)
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/lifecycle/_runner.py", line 236, in _run_step
    getattr(part, step)()
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/pluginhandler/__init__.py", line 350, in pull
    self._runner.pull()
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/pluginhandler/_runner.py", line 81, in pull
    self._sourcedir)
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/pluginhandler/_runner.py", line 160, in _run_scriptlet
    scriptlet_name, function_call.strip())))
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/pluginhandler/_runner.py", line 208, in _handle_builtin_function
    function(**function_args)
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/pluginhandler/__init__.py", line 356, in _do_pull
    self.source_handler.pull()
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/internal/sources/_local.py", line 45, in pull
    source_abspath, self.source_dir, ignore=ignore)
  File "/snap/snapcraft/1594/lib/python3.5/site-packages/snapcraft/file_utils.py", line 176, in link_or_copy_tree
    raise NotADirectoryError('{!r} is not a directory'.format(source_tree))
NotADirectoryError: '/home/pierre/dev/checkbox-project/providers/oem-plainbox' is not a directory

You will run into this same issue if you ever use a build system.
Since I only have a partial view of your project, I will ask why don’t you co-locate the snapcraft.yaml with those sources for the part?

cleanbuild will only successfully work (or any other build system), for the cases where the project sources are in tree or point to an network accessible location.

Work to get a snap was started by a colleague of mine who put his work in a different repository.

I moved my colleague’s changes (snapcraft.yaml + additional required scripts) to the main repository and changed source: /home/pierre/.../oem-plainbox to source: . and the build succeeded! Thanks for your feedback.

I recently created a pull request to add local to the doc. Should I add a mention saying that it cannot use a different directory?