Search code examples
visual-studiosvnmsbuildtagsprojects-and-solutions

Structure a Visual Studio solution in Subversion and preserve project references


Having structured a Visual Studio solution this way (after seeing SO question 15621) :

sln/
    dll/
        trunk/dll.vbproj        
    exe/
        trunk/exe.vbproj

Here, exe.vbproj has a reference to dll.vbproj. Everything should be fine if I build each project with MSBuild.

Now I want to tag both dll and exe projects:

sln/
    dll/
        tags/1.0.0/dll.vbproj
        trunk/dll.vbproj       
    exe/
        tags/1.0.0/exe.vbproj
        trunk/exe.vbproj

I added a depth of one more directory. Hence, I won't be able to build exe/tags/1.0.0/exe.vbproj unless I fix the reference to dll/tags/1.0.0/dll.vbproj path manually.

Did I do something wrong? Is there no way to avoid manually editing?


Solution

  • Usually when we add a project reference to dll in one exe project by right-clicking project add project reference, the modify in the exe.xxproj should be like:

      <ItemGroup>
        <ProjectReference Include="..\..\DllName\trunk\DllName.vbproj">
          <Project>{1fe037b8-5561-4aa0-895d-8bad9eadad20}</Project>
          <Name>DllName</Name>
        </ProjectReference>
      </ItemGroup>
    

    So I think you can try changing it to content below, when loading the project file, if the project is in a trunk folder, it will add ref to the .dll under trunk folder. When .exe in tags folder, it will search the tags folder to add ref.

      <!--When in a trunk folder-->
      <ItemGroup Condition="'$(ProjectDir)'=='$(SolutionDir)$(AssemblyName)\trunk\'">
        <ProjectReference Include="..\..\dll\trunk\dll.vbproj">
          <Project>{1fe037b8-5561-4aa0-895d-8bad9eadad20}</Project>
          <Name>dll</Name>
        </ProjectReference>
      </ItemGroup>
    
      <!--Not in a trunk folder-->
      <ItemGroup Condition="'$(ProjectDir)'!='$(SolutionDir)$(AssemblyName)\trunk\'">
        <ProjectReference Include="$(SolutionDir)dll\tags\$(VersionNumber)\dll.vbproj">
          <Project>{1fe037b8-5561-4aa0-895d-8bad9eadad20}</Project>
          <Name>dll</Name>
        </ProjectReference>
      </ItemGroup>
    

    And for this script, when it's in a tags folder. We use path: $(SolutionDir)dll\tags\$(VersionNumber)\dll.vbproj to do the searching.But the value of $(VersionNumber) is unknown for us.($(SolutionDir),$(ProjectDir) is predefined ones)

    So the value of it depends:

    1.If every time when you have an update version for the project you will delete or move the older versios.

    I mean for fileversion 1.0.0.0, there has a 1.0.0.0 folder under tags fodler, when you update it to 2.0.0.0, there only exists one 2.0.0.0 folder instead of both 1.0.0.0 and 2.0.0.0 folders under tags folder. For this situation: The path can be something like :$(SolutionDir)dll\tags\$(VersionNumber)\dll.vbproj

    2.If you've predefined the $(VersionNumber) property in the .xxproj file, the path can be:$(SolutionDir)dll\tags\$(VersionNumber)\dll.vbproj

    (Not sure how you structure them, if you structure them by .xxproj file, you might have the predefined VersionNumber, if you do it manually and don't define it in .vbproj, we can't easily use the path in this way)

    3.Now all we need to do is to get the value of AssemblyFileVersion property during build process. For your situation, you need to get the AssemblyFileVersion number before the build, please check the First Direction in this thread for more details.

    For patterns: Change from <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern> to <Pattern>\[assembly: AssemblyFileVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern> if you structure them by file version.

    The $(VersionNumber) should be like:

    <PropertyGroup>
        <VersionNumber>$(FirstNum).$(SecondNum).$(ThirdNum).$(FourthNum)</VersionNumber>
    </PropertyGroup>
    

    So beck to your original post:

    Did I do something wrong? Is there no way to avoid manually editing?

    Everything you did is for your specific situation, nothing wrong. There is some way to avoid manually editing, but I'm not sure if the way satisfies your needs.Because sometimes when we want to avoid some manually editing, we need much more work to achieve the approach. Hope all above helps:)