Skip to content

Customize how packages are added to views#7152

Merged
tgamblin merged 73 commits intospack:developfrom
scheibelp:features/per-pkg-projection
Jun 26, 2018
Merged

Customize how packages are added to views#7152
tgamblin merged 73 commits intospack:developfrom
scheibelp:features/per-pkg-projection

Conversation

@scheibelp
Copy link
Copy Markdown
Member

@scheibelp scheibelp commented Jan 31, 2018

Functional updates:

  • python now creates a copy of the python binaries when it is added to a view
  • Python extensions (packages which subclass PythonPackage) rewrite their shebang lines to refer to python in the view
  • Python packages in the same namespace will not generate conflicts if both have ...lib/site-packages/namespace-example/__init__.py
    • These __init__ files will also remain when removing any package in the namespace until the last package in the namespace is removed

Generally (Updated 2/16):

  • Any package can define add_files_to_view to customize how it is added to a view (and at the moment custom definitions are included for python and PythonPackage)
    • Likewise any package can define remove_files_from_view to customize which files are removed (e.g. you don't always want to remove the namespace __init__)
  • Any package can define view_file_conflicts to customize what it considers a merge conflict
  • Global activations are handled like views (where the view root is the spec prefix of the extendee)
    • Benefit: filesystem-management aspects of activating extensions are now placed in views (e.g. now one can hardlink a global activation)
    • Benefit: overriding Package.activate is more straightforward (see Python.activate)
    • Complication: extension packages which have special-purpose logic only when activated outside of the extendee prefix must check for this in their add_files_to_view method (see PythonPackage)
  • LinkTree is refactored to have separate methods for copying a directory structure and for copying files (since it was found that generally packages may want to alter how files are copied but still wanted to copy directories in the same way)

TODOs (updated 2/20):

  • additional testing (there is some unit testing added at this point but more would be useful)
  • refactor or reorganize LinkTree methods: currently there is a separate set of methods for replicating just the directory structure without the files, and a set for replicating everything
  • Right now external views (i.e. those not used for global activations) call view.add_extension, but global activations do not to avoid some extra work that goes into maintaining external views. I'm not sure if addressing that needs to be done here but I'd like to clarify it in the comments (UPDATE: for now I have added a TODO and in my opinion this can be merged now and the refactor handled later)
  • Several method descriptions (e.g. for Package.activate) are out of date and reference a distinction between global activations and views, they need to be updated
  • Update aspell package activations

…icting __init__ files for packages in the same namespace (still need to update remove_from_view)
…re the root is the extendee installation prefix
… are only ever managed for views now). add special-case code for extensions layout to detect if it is managing extensions within a package prefix (i.e. global extensions from before)
…mplicates the tests but removes boilerplate code from subclass implementations
…alled add_files_to_view) for Package and subclasses
…nt) to rewrite shebang line for scripts when they are added to views
…) dont attempt to link a file when the destination already exists (if this is a problem, then view_file_conflicts should have complained)
@scheibelp scheibelp added the WIP label Jan 31, 2018
@scheibelp
Copy link
Copy Markdown
Member Author

@tgamblin the following updates have been made to address the review:

  • There is a new PackageViewMixin class in package.py which aggregates all view-based logic. This eliminates all hasattr calls in filesystem_view.py
  • New tests are added for the spack deactivate command. This was not tested before and part of the reason for the gap in the diff coverage
  • A new test was added for legacy global views (in test/views.py) - this wasn't requested but after looking through test_activations module it seemed useful
  • Improved prefix check in extension_file_path (no more x in y-style prefix checking)
  • Remove spack.util import from link_tree the MergeConflictError now derives from Exception

@scheibelp
Copy link
Copy Markdown
Member Author

@scheibelp
Copy link
Copy Markdown
Member Author

scheibelp commented Jun 22, 2018

@tgamblin in addition to #7152 (comment), the documentation is now updated and generally attempts to emphasize views over global activations.

EDIT: there are also a couple of functions added to the filesystem module which compare paths and check whether a path has a specified subdirectory.

@scheibelp scheibelp mentioned this pull request Jun 22, 2018
8 tasks
@tgamblin tgamblin assigned tgamblin and unassigned tgamblin Jun 22, 2018
@scheibelp scheibelp mentioned this pull request Jun 26, 2018
15 tasks
Copy link
Copy Markdown
Member

@tgamblin tgamblin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scheibelp: this looks great to me!

I think a follow up PR can reduce the complexity of overriding the various methods in PackageViewMixin. We should look at how packages are using those methods and try to make the specification of special files more declarative, but this is good for now.

The docs look great, as well.

@haampie
Copy link
Copy Markdown
Member

haampie commented Mar 14, 2022

Is this py_namespace stuff still relevant? There are 3 packages that use it. It refers to a PEP that's been rejected. Because of those 3 packages, we now have the whole complexity of packages resolving merge conflicts that's not used anywhere else.

@tgamblin
Copy link
Copy Markdown
Member

It's just saying we shouldn't consider an __init__.py to be a conflict if two packages offer parts the same python namespace. I suspect there is a simpler way to get those semantics, or you could just ignore that conflict because the __init__.py files are likely empty.

@haampie
Copy link
Copy Markdown
Member

haampie commented Mar 14, 2022

They are not empty, also don't have the exact same contents :( I read it's required for Python <= 3.2. In Python 3.3+ you can just delete the file post install, and Python should locate things in the namespace.

@tgamblin
Copy link
Copy Markdown
Member

We do still care about the 2.7 stack in Spack... so I think we do care about it.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants