Do themes need to be in both the Modules and Themes directories?

Topics: Administration, Installing Orchard
Feb 5, 2013 at 5:06 AM
We use a source enlistment for our development and add custom themes to the source tree. We run the msbuild task and then deploy the contents of the build/Stage directory, as suggested in the "building and deploying" page.

When the msbuild package task is complete and we look in the output directory, we see that a copy of each custom theme appears in the Modules directory as well as in the Themes directory.

We also see that, although modules that appear in the Modules directory of the output have their bin directories stripped of files that already exist in the Orchard.Web\bin folder and have their obj directories removed, the themes that appear in the Themes directory of the output do not have these files removed.
  1. Are the copies of the themes that end up in the Modules directory extraneous?
  2. Are the copies of the themes that end up in the Themes directory supposed to have their extra bin files stripped and obj directory removed, the same way as modules in the Modules directory?
If the answer to the above are both yes, then there are probably bugs in the build script that are causing these extra files to show up. But I wanted to check what the expected behavior was before filing a bug. The extra files are not likely to be harmful but they do take extra disk space and time to deploy.
Coordinator
Feb 5, 2013 at 8:38 AM
No, that's an old bug in code generation I think.
Feb 6, 2013 at 8:07 AM
Thanks.

So I should be able to safely remove the extraneous copies of the themes that appear in the Modules directory, as well as strip the duplicate files in the bin directory as well as the obj directories from the themes in the Themes directory?

The msbuild still places them there as of the newest copy in the orchard code repo, so I'll try fixing it.
Coordinator
Feb 10, 2013 at 7:45 AM
Yup.
Dec 4, 2013 at 11:28 AM
Edited Dec 4, 2013 at 11:29 AM
I've made some changes to the Orchard.proj msbuild script which resolve both of the above mentioned problems (ensures themes are not output to the modules folder in the staging area, and also ensures the extra bin files are not output to each theme's bin folder).

I've used some commands that I believe are only support with msbuild v4 and later, but I suspect this is no longer a reason that would prevent these changes from being pushed back into the core product. The end result is a much cleaner staging area and clean precompiled output.

The changes are all with the Package-Stage and Package-Precompiled targets. The modified versions of those targets (from the Orchard.proj file) are below. Please review and let me know if this is worthwhile submitting a patch request for...
  <Target Name="Package-Stage" DependsOnTargets="Compile">
    <CallTarget Targets="CompileMsBuildTasks"/>
    <CallTarget Targets="ValidateProjectFiles"/>

    <ItemGroup>
      <SqlCe-Native-Binaries-x86 Include="$(SqlCeFolder)\x86\**\*"/>
      <SqlCe-Native-Binaries-amd64 Include="$(SqlCeFolder)\amd64\**\*"/>
      <Stage-Orchard-Web-Bins Include="$(WebSitesFolder)\Orchard.Web\bin\*"/>
      <Stage-Bin-Exclude Include="$(WebSitesFolder)\**\bin\**\*" />
      <Stage-Web Include="$(WebSitesFolder)\Orchard.Web\**\*;$(SrcFolder)\Orchard.Web\*.csproj;" Exclude="$(SrcFolder)\Orchard.Web\Orchard.Web.csproj;$(SrcFolder)\Orchard.Web\**\*.Release.config;$(SrcFolder)\Orchard.Web\**\*.Debug.config"/>
      <Stage-Web-Config Include="$(SrcFolder)\Orchard.Web\**\*.config" Exclude="$(SrcFolder)\Orchard.Web\**\*.Release.config;$(SrcFolder)\Orchard.Web\**\*.Debug.config"/>
      <Stage-Media Include="$(SrcFolder)\Orchard.Web\Media\OrchardLogo.png" />
      <Stage-PoFiles Include="$(SrcFolder)\Orchard.Web\**\*.po" />
      <Stage-Core Include="$(WebSitesFolder)\Orchard.Core\**\*" Exclude="$(WebSitesFolder)\Orchard.Core\**\bin\**\*" />
     
      <!-- Get list of module names from the module definition files within ModulesSrcFolder -->
      <Stage-Modules-Definitions Include="$(ModulesSrcFolder)\**\Module.txt" />
      <Stage-Modules-Directories Include="@(Stage-Modules-Definitions->DirectoryName())"  />
      <Stage-Modules-Names Include="@(Stage-Modules-Directories->'%(Filename)%(Extension)')"  />
     
      <!-- Get list of theme names from the theme definition files within ThemesSrcFolder -->
      <Stage-Themes-Definitions Include="$(ThemesSrcFolder)\**\Theme.txt" />
      <Stage-Themes-Directories Include="@(Stage-Themes-Definitions->DirectoryName())"  />
      <Stage-Themes-Names Include="@(Stage-Themes-Directories->'%(Filename)%(Extension)')"  />
         
      <Stage-License Include="$(MSBuildProjectDirectory)\*.txt" />
      <Stage-Build Include="$(MSBuildProjectDirectory)\*.proj;$(MSBuildProjectDirectory)\*.cmd" />
    </ItemGroup>
    
    <ItemGroup>
      <!-- Note. We could add recursion (\..\) before the module/theme name thus avoiding the need for custom metadata
           and simplifing the copy tasks further below. However this can result in folders being incorrectly copied if 
           a module or theme contains a subfolder with the same name as another module or theme. -->
      <Stage-Modules Include="$(WebSitesFolder)\%(Stage-Modules-Names.Identity)\**\*" Exclude="@(Stage-Bin-Exclude)">
        <ModuleName>%(Stage-Modules-Names.Identity)</ModuleName>      
      </Stage-Modules>
      <Stage-Modules-Binaries Include="$(WebSitesFolder)\%(Stage-Modules-Names.Identity)\**\bin\**\*">
        <ModuleName>%(Stage-Modules-Names.Identity)</ModuleName>      
      </Stage-Modules-Binaries>
      <Stage-Modules-Sources Include="$(ModulesSrcFolder)\**\*.csproj;$(ModulesSrcFolder)\**\*.cs"/>
      <Stage-Themes-Default Include="$(WebSitesFolder)\Themes\%(Stage-Themes-Names.Identity)\**\*">
        <ThemeName>%(Stage-Themes-Names.Identity)</ThemeName>
      </Stage-Themes-Default>
      <Stage-Themes-Custom Include="$(WebSitesFolder)\%(Stage-Themes-Names.Identity)\**\*" Exclude="@(Stage-Bin-Exclude)">
        <ThemeName>%(Stage-Themes-Names.Identity)</ThemeName>
      </Stage-Themes-Custom>
      <!-- Note. Binaries are not copied for themes in the default Themes project. -->
      <Stage-Themes-Binaries Include="$(WebSitesFolder)\%(Stage-Themes-Names.Identity)\**\bin\**\*">
        <ThemeName>%(Stage-Themes-Names.Identity)</ThemeName>
      </Stage-Themes-Binaries>
      <Stage-Themes-Sources Include="$(ThemesSrcFolder)\**\*.csproj;$(ThemesSrcFolder)\**\*.cs" Exclude="$(ThemesSrcFolder)\*.*"/>
    </ItemGroup>

    <!-- Copying module binaries is somewhat tricky: From a module "bin" directory, we
         only want to include the files that are _not_ already present in 
         the "Orchard.Web\Bin" folder. -->
    <FilterModuleBinaries
      ModulesBinaries="@(Stage-Modules-Binaries)"
      OrchardWebBinaries="@(Stage-Orchard-Web-Bins)">
      <Output TaskParameter="ExcludedBinaries" ItemName="FilterModuleBinaries-ExcludedBinaries"/>
    </FilterModuleBinaries>
    <FilterModuleBinaries
      ModulesBinaries="@(Stage-Themes-Binaries)"
      OrchardWebBinaries="@(Stage-Orchard-Web-Bins)">
      <Output TaskParameter="ExcludedBinaries" ItemName="FilterThemeBinaries-ExcludedBinariesFromThemes"/>
    </FilterModuleBinaries>

    <ItemGroup>
      <Stage-Modules-Binaries-Unique Include="@(Stage-Modules-Binaries)"  Exclude="@(FilterModuleBinaries-ExcludedBinaries)"/>
      <Stage-Themes-Binaries-Unique Include="@(Stage-Themes-Binaries)"  Exclude="@(FilterThemeBinaries-ExcludedBinariesFromThemes)"/>
    </ItemGroup>

    <Copy SourceFiles="@(Stage-Web);@(Stage-Web-Config);@(Stage-License)" DestinationFolder="$(StageFolder)\%(RecursiveDir)"/>
    <Copy SourceFiles="@(Stage-Media)" DestinationFolder="$(StageFolder)\Media"/>
    <Copy SourceFiles="@(Stage-PoFiles)" DestinationFolder="$(StageFolder)\%(RecursiveDir)"/>
    <Copy SourceFiles="@(SqlCe-Native-Binaries-x86)" DestinationFolder="$(StageFolder)\bin\x86\%(RecursiveDir)"/>
    <Copy SourceFiles="@(SqlCe-Native-Binaries-amd64)" DestinationFolder="$(StageFolder)\bin\amd64\%(RecursiveDir)"/>
    <Copy SourceFiles="@(Stage-Core)" DestinationFolder="$(StageFolder)\Core\%(RecursiveDir)"/>
    <Copy SourceFiles="@(Stage-Modules)" DestinationFiles="@(Stage-Modules->'$(StageFolder)\Modules\%(ModuleName)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    <Copy SourceFiles="@(Stage-Modules-Binaries-Unique)" DestinationFiles="@(Stage-Modules-Binaries-Unique->'$(StageFolder)\Modules\%(ModuleName)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    <Copy SourceFiles="@(Stage-Modules-Sources)" DestinationFolder="$(StageFolder)\Modules\%(RecursiveDir)"/>
    <Copy SourceFiles="@(Stage-Themes-Default)" DestinationFiles="@(Stage-Themes-Default->'$(StageFolder)\Themes\%(ThemeName)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    <Copy SourceFiles="@(Stage-Themes-Custom)" DestinationFiles="@(Stage-Themes-Custom->'$(StageFolder)\Themes\%(ThemeName)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    <Copy SourceFiles="@(Stage-Themes-Binaries-Unique)" DestinationFiles="@(Stage-Themes-Binaries-Unique->'$(StageFolder)\Themes\%(ThemeName)\%(RecursiveDir)%(Filename)%(Extension)')"/>
    <Copy SourceFiles="@(Stage-Themes-Sources)" DestinationFolder="$(StageFolder)\Themes\%(RecursiveDir)"/>
    
    <MakeDir Directories="$(StageFolder)\App_Data"/>
    <WriteLinesToFile File="$(StageFolder)\App_Data\_marker.txt" Lines="some_text" Overwrite="true"/>

    <!-- extra processing of the staged config files -->
    <TransformXml 
      Source="$(StageFolder)\Web.Config"
      Transform="$(SrcFolder)\Orchard.Web\Web.Release.Config"
      Destination="$(StageFolder)\Web.Config"
    />

    <TransformXml 
      Source="$(StageFolder)\Config\HostComponents.Config"
      Transform="$(SrcFolder)\Orchard.Web\Config\HostComponents.Release.Config"
      Destination="$(StageFolder)\Config\HostComponents.Config"
    />

    <TransformXml 
      Source="$(StageFolder)\Config\log4net.Config"
      Transform="$(SrcFolder)\Orchard.Web\Config\log4net.Release.Config"
      Destination="$(StageFolder)\Config\log4net.Config"
    />
    
    <!-- move over extra non-content files the csproj referenced -->
    <Copy SourceFiles="@(StageProjectAlteration-ExtraFiles->'$(SrcFolder)\Orchard.Web\%(Identity)')"
        DestinationFolder="$(StageFolder)\%(RecursiveDir)"/>

  </Target>
  <Target Name="Package-Precompiled">
    <ItemGroup>
      <Precompiled-Exclude-Source Include="$(StageFolder)\**\*.cs;$(StageFolder)\**\*.csproj;$(StageFolder)\**\*.csproj.user" />
      <Precompiled-Folder-Input Include="$(StageFolder)\**\*" Exclude="$(StageFolder)\**\bin\**\*.xml;$(StageFolder)\Modules\**\Tests\**;$(StageFolder)\Modules\**\Specs\**;$(StageFolder)\**\obj\**\*;@(Precompiled-Exclude-Source)" />
    </ItemGroup>

    <Copy SourceFiles="@(Precompiled-Folder-Input)"
        DestinationFolder="$(PrecompiledFolder)\%(RecursiveDir)"/>

    <MakeDir Directories="$(PrecompiledFolder)\bin\HostRestart"/>
  </Target>
Dec 24, 2013 at 4:54 AM
I've created the following issue for this: https://orchard.codeplex.com/workitem/20379
Dec 24, 2013 at 5:10 AM