fsprojects / Paket

A dependency manager for .NET with support for NuGet packages and Git repositories.
https://fsprojects.github.io/Paket/
MIT License
2.02k stars 525 forks source link

Configure output folder of assemblies for Unity #3026

Open IvanRibakov opened 6 years ago

IvanRibakov commented 6 years ago

Description

One of the examples when this is needed is when using Paket with Unity3D projects. Unity is picky about where dlls can be located (they have to be anywhere inside Assets/ folder in the project root as far as I understand) and as such there is no automated way to place them where they should be.

There is Paket.Unity3D (https://github.com/wooga/Paket.Unity3D), which attempts to solve the problem but it doesn't seem to be actively maintained (judging by commit history and build status) and besides, running it results in dlls being stored in 2 places (as can be seen on http://wooga.github.io/Paket.Unity3D/tutorial.html under "Installing the dependency" section).

Any chance above mentioned use case will make you reconsider your opinion on the subject?

IvanRibakov commented 6 years ago

Any thoughts on the subject? @forki ? Anyone?

enricosada commented 6 years ago

Hi @IvanRibakov

A question, what is doing Paket.Unity3D more than standard paket atm? because based on that there are multiple way to extend paket itself

some ideas:

use an msbuild target to xcopy Reference

You just need these directory in Assets folder? You can probably add a post build step like (doesnt work, but will be similar)

<Target Name="BeforeBuild">
    <!-- filter just paket ref -->
    <ItemGroup>
        <PacketAssetsToCopy Include="%(Reference.HintPath)" Condition=" '%(Reference.Paket)' == 'True' " />
    <ItemGroup>
    <!-- copy to dir -->
    <Copy  
            SourceFiles="@(PacketAssetsToCopy)"  
            DestinationFolder="Assets\Lib"  
       />  
</Target>

if is enogh polished, can be added to Paket.target too, so can be automatically done for unityproj

Or the <Reference HintPath need to be corret in Assets too for unity to work?

change packages folder name

maybe is too raw

Searching the code, i see the custumization of package folder name is half-done (ref https://github.com/fsprojects/Paket/blob/e51e399af9574b99a2bedd25afa512a9e8df3ca1/src/Paket.Core/Common/Utils.fs#L888 ) but not yet done ( https://github.com/fsprojects/Paket/blob/41e51f8a1ef1511ba6df93248211994fb66a9cb4/src/Paket.Core/PaketConfigFiles/LockFile.fs#L43 and https://github.com/fsprojects/Paket/blob/41e51f8a1ef1511ba6df93248211994fb66a9cb4/src/Paket.Core/Versioning/Requirements.fs#L884 )

Is changing the name of packages folder to Assets/packages enough? because unzip packages in Assets/packages dir may need additional work on your side to filters after to exclude unneeded files contained in packages.

add a strategy to paket.references

Another way i see, is to add a strategy in paket.references to copy dll.

IvanRibakov commented 6 years ago

Hi @enricosada, thanks for taking your time to look into my question.

Regarding your question:

what is doing Paket.Unity3D more than standard paket atm

as far as I understand, author's idea was to copy contents of packages folder inside Assets/. Which, in principle, is ok with me, if only Paket.Unity3D actually worked. Perhaps it does more, but I came across it being mentioned mainly in that context.

Regarding your ideas:

use an msbuild target to xcopy Reference

I'm fairly new to C# so I apologise if I misunderstood what you meant, but if you are suggesting to add pre-build step inside .csproj file, then it won't work because Unity recreates it from scratch on every build. See https://docs.unity3d.com/Manual/VisualStudioIntegration.html section "A few things to watch out for", last bullet point.

change packages folder name

That would be a start, though if I was going to later write add to build process a batch job to remove unwanted files I might as well have one that copies DLLs only from packages to begin with.

add a strategy to paket.references

that's a kind of thing I was looking for - a simple configuration to tell Paket where to dump DLLs upon adding new dependency or restoring them all form a .lock file.

enricosada commented 6 years ago

to add pre-build step inside .csproj file, then it won't work because Unity recreates it from scratch on every build

@IvanRibakov so unity3d just import all .dll found inside Assets directory at build step? this is important because usually paket update the files,

Is this the relevant doc? https://docs.unity3d.com/Manual/UsingDLL.html

So refining that, maybe:

add an options from command line to print all the installed references

Use a command to print all path to assemblies, and copy with an external script

atm already exists show-installed-packages, but show using format {Group} {Package} - {Version}

> paket show-installed-packages --all  -s
Main MyLib - 3.8

so adding a --format arg like

> paket show-installed-packages --all  -s --format "p"
c:\path\to\packages\MyLib\MyLib.dll

and use that list to copy these files in any dir with a .bat/.sh

Or calling it in the build pipeline of unity https://docs.unity3d.com/Manual/BuildPlayerPipeline.html (and if i read it correctly, will show in the menu too)

add an option in paket.references

add a new strategy to paket.references is another possiibility you will have anyway a packages folder (but doesnt need to be committed in the repo, as usual), and something like

copy_lib_to Assets/MyPackages

MyLib
IvanRibakov commented 6 years ago

so unity3d just import all .dll found inside Assets directory at build step

Correct.

this is important because usually paket update the files

You mean paket updates .csproj file? I wonder what will happen if paket will get executed in CI environment with Unity project where no .csproj file exists (it is common to .gitignore .sln and .csproj files for Unity projects since Unity recreates them anyway).

Use a command to print all path to assemblies, and copy with an external script

Thanks, I wasn't aware of that feature! Should simplify the script. Though solution is still a bit awkward for the "add new package" use case (during the development), where after calling paket add <package ID> all installed dependencies would have to be copied (again) inside to Assets/ folder. Unless there is a way to leverage paket show-installed-packages for a single package, then it would be a matter of another script for "add new package" use case.