Metacello / metacello

Metacello is a package management system for Smalltalk
MIT License
88 stars 43 forks source link

Cannot copy project configuration with Cypress support enable #494

Closed jecisc closed 5 years ago

jecisc commented 6 years ago

I need to have a configuration with a dependency on a project. But some packages need to depend on the group "Minimal" of this project and others need to depend on the "Presentation" group.

I tried to use this code:

    spec
        baseline: 'MyProjectName'
        with: [ spec
                loads: 'Minimal';
                repository: 'gitlab://MyOrga/MyProjectName/src' ].
    spec project: 'MyProjectNamePresentation' copyFrom: 'MyProjectName' with: [ spec loads: 'Presentation' ]

If I use a classic project class for the baseline it works. But if I use the Metacello cypress support I get this error:

Error: The project spec 'MyProjectName' in project BaselineOfMyCurrentProject has incompatible specs. MetacelloMCBaselineOfProjectSpec and MetacelloCypressBaselineProjectSpec are not compatible.

MetacelloCypressBaselineProjectSpec(Object)>>error:
MetacelloCypressBaselineProjectSpec(MetacelloSpec)>>validateMergeForSpec:
MetacelloCypressBaselineProjectSpec(MetacelloSpec)>>mergeSpec:
MetacelloCypressBaselineProjectSpec(MetacelloGenericProjectSpec)>>mergeSpec:
MetacelloCypressBaselineProjectSpec(MetacelloMCBaselineOfProjectSpec)>>mergeSpec:
MetacelloProjectReferenceSpec>>mergeSpec:
MetacelloPackagesSpec(MetacelloMemberListSpec)>>mapCopy:into:
[ :memberSpec | self mapCopy: memberSpec into: map ] in [ :member | 
member
    applyAdd: [ :memberSpec | self mapAdd: memberSpec into: map ]
    copy: [ :memberSpec | self mapCopy: memberSpec into: map ]
    merge: [ :memberSpec | self mapMerge: memberSpec into: map ]
    remove: [ :memberSpec | self mapRemove: memberSpec into: map ] ] in MetacelloPackagesSpec(MetacelloMemberListSpec)>>map in Block: [ :memberSpec | self mapCopy: memberSpec into: map...etc...
MetacelloCopyMemberSpec>>applyAdd:copy:merge:remove:
[ :member | 
member
    applyAdd: [ :memberSpec | self mapAdd: memberSpec into: map ]
    copy: [ :memberSpec | self mapCopy: memberSpec into: map ]
    merge: [ :memberSpec | self mapMerge: memberSpec into: map ]
    remove: [ :memberSpec | self mapRemove: memberSpec into: map ] ] in MetacelloPackagesSpec(MetacelloMemberListSpec)>>map in Block: [ :member | ...
OrderedCollection>>do:
MetacelloPackagesSpec(MetacelloMemberListSpec)>>map
MetacelloPackagesSpec>>packageNamed:ifAbsent:
MetacelloMCVersionSpec(MetacelloVersionSpec)>>defaultPackageNames
MetacelloCypressBaselineProjectSpec(MetacelloProjectSpec)>>loadListForVersion:
MetacelloCypressBaselineProjectSpec(MetacelloMCProjectSpec)>>loadedPackageNames:
[ :prj | 
prj className ~~ nil
    ifTrue: [ | coll loaded |
        coll := projectMap
            at: prj className
            ifAbsent: [ coll := OrderedCollection new.
                projectMap at: prj className put: coll.
                coll ].
        (loaded := prj loadedPackageNames: aLoader) isEmpty
            ifFalse: [ coll add: prj -> (loaded -> prj loadPackageList) ] ] ] in MetacelloMCVersion>>packageAndProjectNamesToLoad:loader: in Block: [ :prj | ...
OrderedCollection>>do:
MetacelloMCVersion>>packageAndProjectNamesToLoad:loader:
MetacelloCypressBaselineProjectSpec(MetacelloMCProjectSpec)>>loadVersion:
MetacelloProjectSpecForLoad>>performLoad
MetacelloCypressBaselineProjectSpec(MetacelloGenericProjectSpec)>>load
MetacelloProjectReferenceSpec>>loadUsing:gofer:
[ :pkg | pkg loadUsing: self gofer: gofer ] in MetacelloFetchingMCSpecLoader(MetacelloCommonMCSpecLoader)>>linearLoadPackageSpecs:repositories: in Block: [ :pkg | pkg loadUsing: self gofer: gofer ]
OrderedCollection>>do:
MetacelloFetchingMCSpecLoader(MetacelloCommonMCSpecLoader)>>linearLoadPackageSpecs:repositories:
[ super
    linearLoadPackageSpecs: packageSpecs
    repositories: repositories ] in MetacelloFetchingMCSpecLoader>>linearLoadPackageSpecs:repositories: in Block: [ super...
BlockClosure>>ensure:
MetacelloLoaderPolicy>>pushLoadDirective:during:
MetacelloLoaderPolicy>>pushLinearLoadDirectivesDuring:for:
jecisc commented 6 years ago

To clarify, when I say "Use the cypress support", I mean implementing this method in the baseline:

projectClass
    ^ [ self class environment at: #MetacelloCypressBaselineProject ]
        on: NotFound
        do: [ super projectClass ]
gcotelli commented 5 years ago

@dalehenrich check out pharo-project/pharo#2173 . With this change at least we're able to use the copy project functionality with Cypress based projects.

dalehenrich commented 5 years ago

@jecisc does this patch resolve your problem?

jecisc commented 5 years ago

@dalehenrich Yes! I added back the support for a project and it's all right in P7 and broken in P6.1.

I got esteban approval to backport this fix in 6.1.

jecisc commented 5 years ago

It was the last thing I was missing to use this in all my project :) When it will be in 6.1 I'll also update the baseline guide I wrote to help new members of the community to includes it:

https://github.com/pharo-open-documentation/pharo-wiki/blob/master/General/Baselines.md

It's more pharo oriented but I guess it can also help people from other smalltalks. (And also git oriented. I do not cover configurations)

dalehenrich commented 5 years ago

@jecisc very good! ...