Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d230a7b01 | |||
| 18c5348bdf | |||
| c50fea9794 |
@@ -1,10 +0,0 @@
|
||||
root=true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{cs,cshtml,csx,vb,vbx,vbhtml,fs,fsx,txt,ps1,sql}]
|
||||
indent_size = 4
|
||||
+10
-8
@@ -46,7 +46,13 @@ src/Umbraco.Web.UI/Web.*.config.transformed
|
||||
|
||||
umbraco/presentation/umbraco/plugins/uComponents/uComponentsInstaller.ascx
|
||||
umbraco/presentation/packages/uComponents/MultiNodePicker/CustomTreeService.asmx
|
||||
_BuildOutput/*
|
||||
*.ncrunchsolution
|
||||
build/UmbracoCms.AllBinaries*zip
|
||||
build/UmbracoCms.WebPI*zip
|
||||
build/UmbracoCms*zip
|
||||
build/UmbracoExamine.PDF*zip
|
||||
build/*.nupkg
|
||||
src/Umbraco.Tests/config/applications.config
|
||||
src/Umbraco.Tests/config/trees.config
|
||||
src/Umbraco.Web.UI/web.config
|
||||
@@ -62,9 +68,9 @@ src/packages/repositories.config
|
||||
|
||||
src/Umbraco.Web.UI/[Ww]eb.config
|
||||
*.transformed
|
||||
webpihash.txt
|
||||
|
||||
node_modules
|
||||
lib-bower
|
||||
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Ll]ib/*
|
||||
src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/umbraco.*
|
||||
@@ -89,6 +95,7 @@ src/Umbraco.Web.UI/[Uu]mbraco/[Aa]ssets/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/*
|
||||
src/Umbraco.Web.UI.Client/[Bb]uild/[Bb]elle/
|
||||
src/Umbraco.Web.UI/[Uu]ser[Cc]ontrols/
|
||||
build/_BuildOutput/
|
||||
src/Umbraco.Web.UI.Client/src/[Ll]ess/*.css
|
||||
tools/NDepend/
|
||||
|
||||
@@ -123,6 +130,7 @@ src/*.boltdata/
|
||||
/src/Umbraco.Web.UI/Umbraco/Js/canvasdesigner.config.js
|
||||
/src/Umbraco.Web.UI/Umbraco/Js/canvasdesigner.front.js
|
||||
src/umbraco.sln.ide/*
|
||||
build/UmbracoCms.*/
|
||||
src/.vs/
|
||||
src/Umbraco.Web.UI/umbraco/js/install.loader.js
|
||||
src/Umbraco.Tests/media
|
||||
@@ -132,11 +140,5 @@ apidocs/api/*
|
||||
build/docs.zip
|
||||
build/ui-docs.zip
|
||||
build/csharp-docs.zip
|
||||
build/msbuild.log
|
||||
.vs/
|
||||
src/packages/
|
||||
src/PrecompiledWeb/*
|
||||
|
||||
|
||||
build.out/
|
||||
build.tmp/
|
||||
build/Modules/*/temp/
|
||||
@@ -1,149 +0,0 @@
|
||||
Umbraco Cms Build
|
||||
--
|
||||
----
|
||||
|
||||
# Quick!
|
||||
|
||||
To build Umbraco, fire PowerShell and move to Umbraco's repository root (the directory that contains `src`, `build`, `README.md`...). There, trigger the build with the following command:
|
||||
|
||||
build\build.ps1
|
||||
|
||||
By default, this builds the current version. It is possible to specify a different version as a parameter to the build script:
|
||||
|
||||
build\build.ps1 7.6.44
|
||||
|
||||
Valid version strings are defined in the `Set-UmbracoVersion` documentation below.
|
||||
|
||||
## Notes
|
||||
|
||||
Git might have issues dealing with long file paths during build. You may want/need to enable `core.longpaths` support (see [this page](https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path) for details).
|
||||
|
||||
# Build
|
||||
|
||||
The Umbraco Build solution relies on a PowerShell module. The module needs to be imported into PowerShell. From within Umbraco's repository root:
|
||||
|
||||
build\build.ps1 -ModuleOnly
|
||||
|
||||
Or the abbreviated form:
|
||||
|
||||
build\build.ps1 -mo
|
||||
|
||||
Once the module has been imported, a set of commands are added to PowerShell.
|
||||
|
||||
## Get-UmbracoBuildEnv
|
||||
|
||||
Gets the Umbraco build environment ie NuGet, Semver, Visual Studio, etc. Downloads things that can be downloaded such as NuGet. Examples:
|
||||
|
||||
$uenv = Get-UmbracoBuildEnv
|
||||
Write-Host $uenv.SolutionRoot
|
||||
&$uenv.NuGet help
|
||||
|
||||
The object exposes the following properties:
|
||||
|
||||
* `SolutionRoot`: the absolute path to the solution root
|
||||
* `VisualStudio`: a Visual Studio object (see below)
|
||||
* `NuGet`: the absolute path to the NuGet executable
|
||||
* `Zip`: the absolute path to the 7Zip executable
|
||||
* `VsWhere`: the absolute path to the VsWhere executable
|
||||
* `NodePath`: the absolute path to the Node install
|
||||
* `NpmPath`: the absolute path to the Npm install
|
||||
|
||||
The Visual Studio object is `null` when Visual Studio has not been detected (eg on VSTS). When not null, the object exposes the following properties:
|
||||
|
||||
* `Path`: Visual Studio installation path (eg some place under `Program Files`)
|
||||
* `Major`: Visual Studio major version (eg `15` for VS 2017)
|
||||
* `Minor`: Visual Studio minor version
|
||||
* `MsBUild`: the absolute path to the MsBuild executable
|
||||
|
||||
## Get-UmbracoVersion
|
||||
|
||||
Gets an object representing the current Umbraco version. Example:
|
||||
|
||||
$v = Get-UmbracoVersion
|
||||
Write-Host $v.Semver
|
||||
|
||||
The object exposes the following properties:
|
||||
|
||||
* `Semver`: the semver object representing the version
|
||||
* `Release`: the main part of the version (eg `7.6.33`)
|
||||
* `Comment`: the pre release part of the version (eg `alpha02`)
|
||||
* `Build`: the build number part of the version (eg `1234`)
|
||||
|
||||
## Set-UmbracoVersion
|
||||
|
||||
Modifies Umbraco files with the new version.
|
||||
|
||||
>This entirely replaces the legacy `UmbracoVersion.txt` file.
|
||||
|
||||
The version must be a valid semver version. It can include a *pre release* part (eg `alpha02`) and/or a *build number* (eg `1234`). Examples:
|
||||
|
||||
Set-UmbracoVersion 7.6.33
|
||||
Set-UmbracoVersion 7.6.33-alpha02
|
||||
Set-UmbracoVersion 7.6.33+1234
|
||||
Set-UmbracoVersion 7.6.33-beta05+5678
|
||||
|
||||
Note that `Set-UmbracoVersion` enforces a slightly more restrictive naming scheme than what semver would tolerate. The pre release part can only be composed of a-z and 0-9, therefore `alpha033` is considered valid but not `alpha.033` nor `alpha033-preview` nor `RC2` (would need to be lowercased `rc2`).
|
||||
|
||||
>It is considered best to add trailing zeroes to pre releases, else NuGet gets the order of versions wrong. So if you plan to have more than 10, but no more that 100 alpha versions, number the versions `alpha00`, `alpha01`, etc.
|
||||
|
||||
## Build-Umbraco
|
||||
|
||||
Builds Umbraco. Temporary files are generated in `build.tmp` while the actual artifacts (zip files, NuGet packages...) are produced in `build.out`. Example:
|
||||
|
||||
Build-Umbraco
|
||||
|
||||
Some log files, such as MsBuild logs, are produced in `build.tmp` too. The `build` directory should remain clean during a build.
|
||||
|
||||
### web.config
|
||||
|
||||
Building Umbraco requires a clean `web.config` file in the `Umbraco.Web.UI` project. If a `web.config` file already exists, the `pre-build` task (see below) will save it as `web.config.temp-build` and replace it with a clean copy of `web.Template.config`. The original file is replaced once it is safe to do so, by the `pre-packages` task.
|
||||
|
||||
## Build-UmbracoDocs
|
||||
|
||||
Builds umbraco documentation. Temporary files are generated in `build.tmp` while the actual artifacts (docs...) are produced in `build.out`. Example:
|
||||
|
||||
Build-UmbracoDocs
|
||||
|
||||
Some log files, such as MsBuild logs, are produced in `build.tmp` too. The `build` directory should remain clean during a build.
|
||||
|
||||
## Verify-NuGet
|
||||
|
||||
Verifies that projects all require the same version of their dependencies, and that NuSpec files require versions that are consistent with projects. Example:
|
||||
|
||||
Verify-NuGet
|
||||
|
||||
# VSTS
|
||||
|
||||
Continuous integration, nightly builds and release builds run on VSTS.
|
||||
|
||||
VSTS uses the `Build-Umbraco` command several times, each time passing a different *target* parameter. The supported targets are:
|
||||
|
||||
* `pre-build`: prepares the build
|
||||
* `compile-belle`: compiles Belle
|
||||
* `compile-umbraco`: compiles Umbraco
|
||||
* `pre-tests`: prepares the tests
|
||||
* `compile-tests`: compiles the tests
|
||||
* `pre-packages`: prepares the packages
|
||||
* `pkg-zip`: creates the zip files
|
||||
* `pre-nuget`: prepares NuGet packages
|
||||
* `pkg-nuget`: creates NuGet packages
|
||||
|
||||
All these targets are executed when `Build-Umbraco` is invoked without a parameter (or with the `all` parameter). On VSTS, compilations (of Umbraco and tests) are performed by dedicated VSTS tasks. Similarly, creating the NuGet packages is also performed by dedicated VSTS tasks.
|
||||
|
||||
Finally, the produced artifacts are published in two containers that can be downloaded from VSTS: `zips` contains the zip files while `nuget` contains the NuGet packages.
|
||||
|
||||
>During a VSTS build, some environment `UMBRACO_*` variables are exported by the `pre-build` target and can be reused in other targets *and* in VSTS tasks. The `UMBRACO_TMP` environment variable is used in `Umbraco.Tests` to disable some tests that have issues with VSTS at the moment.
|
||||
|
||||
# Notes
|
||||
|
||||
*This part needs to be cleaned up*
|
||||
|
||||
Nightlies should use some sort of build number.
|
||||
|
||||
We should increment versions as soon as a version is released. Ie, as soon as `7.6.33` is released, we should `Set-UmbracoVersion 7.6.34-alpha` and push.
|
||||
|
||||
NuGet / NuSpec consistency checks are performed in tests. We should move it so it is done as part of the PowerShell script even before we try to compile and run the tests.
|
||||
|
||||
There are still a few commands in `build` (to build docs, install Git or cleanup the install) that will need to be migrated to PowerShell.
|
||||
|
||||
/eof
|
||||
@@ -1,5 +1,3 @@
|
||||
[](https://ci.appveyor.com/project/Umbraco/umbraco-cms-hs8dx/branch/dev-v7)
|
||||
|
||||
Umbraco CMS
|
||||
===========
|
||||
The friendliest, most flexible and fastest growing ASP.NET CMS used by more than 390,000 websites worldwide: [https://umbraco.com](https://umbraco.com)
|
||||
@@ -12,7 +10,9 @@ Umbraco is a free open source Content Management System built on the ASP.NET pla
|
||||
|
||||
## Building Umbraco from source ##
|
||||
|
||||
The easiest way to get started is to run `build/build.bat` which will build both the backoffice (also known as "Belle") and the Umbraco core. You can then easily start debugging from Visual Studio, or if you need to debug Belle you can run `gulp dev` in `src\Umbraco.Web.UI.Client`.
|
||||
The easiest way to get started is to run `build/build.bat` which will build both the backoffice (also known as "Belle") and the Umbraco core. You can then easily start debugging from Visual Studio, or if you need to debug Belle you can run `grunt vs` in `src\Umbraco.Web.UI.Client`.
|
||||
|
||||
If you're interested in making changes to Belle without running Visual Studio make sure to read the [Belle ReadMe file](src/Umbraco.Web.UI.Client/README.md).
|
||||
|
||||
Note that you can always [download a nightly build](http://nightly.umbraco.org/?container=umbraco-750) so you don't have to build the code yourself.
|
||||
|
||||
|
||||
+14
-19
@@ -1,28 +1,22 @@
|
||||
version: '{build}'
|
||||
shallow_clone: true
|
||||
|
||||
init:
|
||||
- ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
|
||||
|
||||
build_script:
|
||||
- cmd: >-
|
||||
SET SLN=%CD%
|
||||
|
||||
SET SRC=%SLN%\src
|
||||
|
||||
SET PACKAGES=%SRC%\packages
|
||||
|
||||
CD build
|
||||
cd build
|
||||
|
||||
SET "release="
|
||||
|
||||
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i"
|
||||
|
||||
ECHO "Restoring NuGet into %PACKAGES%"
|
||||
|
||||
%SRC%\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
|
||||
|
||||
%SRC%\.nuget\NuGet.exe restore %SRC%\umbraco.sln -Verbosity Quiet -NonInteractive -PackagesDirectory %PACKAGES%
|
||||
SET nuGetFolder=C:\Users\appveyor\.nuget\packages
|
||||
|
||||
..\src\.nuget\NuGet.exe sources Add -Name MyGetUmbracoCore -Source https://www.myget.org/F/umbracocore/api/v2/ >NUL
|
||||
|
||||
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Web.UI\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
|
||||
|
||||
IF EXIST ..\src\umbraco.businesslogic\packages.config ..\src\.nuget\NuGet.exe install ..\src\umbraco.businesslogic\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
|
||||
|
||||
..\src\.nuget\NuGet.exe install ..\src\Umbraco.Core\packages.config -OutputDirectory %nuGetFolder% -Verbosity quiet
|
||||
|
||||
ECHO Building Release %release% build%APPVEYOR_BUILD_NUMBER%
|
||||
|
||||
@@ -30,12 +24,13 @@ build_script:
|
||||
|
||||
SET MSBUILD="C:\Program Files (x86)\MSBuild\14.0\Bin\MsBuild.exe"
|
||||
|
||||
XCOPY "%SRC%\Umbraco.Tests\unit-test-log4net.CI.config" "%SRC%\Umbraco.Tests\unit-test-log4net.config" /Y
|
||||
XCOPY "..\src\Umbraco.Tests\unit-test-log4net.CI.config" "..\src\Umbraco.Tests\unit-test-log4net.config" /Y
|
||||
|
||||
%MSBUILD% "%SLN%/src/Umbraco.Tests/Umbraco.Tests.csproj" /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly /p:NugetPackagesDirectory=%PACKAGES%
|
||||
%MSBUILD% "..\src\Umbraco.Tests\Umbraco.Tests.csproj" /consoleloggerparameters:Summary;ErrorsOnly
|
||||
|
||||
build.bat -integration -release:%release% -comment:build%APPVEYOR_BUILD_NUMBER% -nugetfolder:%PACKAGES%
|
||||
build.bat nopause %release% build%APPVEYOR_BUILD_NUMBER%
|
||||
|
||||
ECHO %PATH%
|
||||
test:
|
||||
assemblies: src\Umbraco.Tests\bin\Debug\Umbraco.Tests.dll
|
||||
artifacts:
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
@ECHO OFF
|
||||
powershell .\build\build.ps1
|
||||
|
||||
IF ERRORLEVEL 1 (
|
||||
GOTO :error
|
||||
) ELSE (
|
||||
GOTO :EOF
|
||||
)
|
||||
|
||||
:error
|
||||
ECHO.
|
||||
ECHO Can not run build\build.ps1.
|
||||
ECHO If this is due to a SecurityError then make sure to run the following command from an administrator command prompt:
|
||||
ECHO.
|
||||
ECHO powershell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
|
||||
@@ -0,0 +1,95 @@
|
||||
@ECHO OFF
|
||||
IF NOT EXIST UmbracoVersion.txt (
|
||||
ECHO UmbracoVersion.txt missing!
|
||||
GOTO :showerror
|
||||
)
|
||||
|
||||
REM Get the version and comment from UmbracoVersion.txt lines 2 and 3
|
||||
SET "release="
|
||||
SET "comment="
|
||||
FOR /F "skip=1 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED release SET "release=%%i"
|
||||
FOR /F "skip=2 delims=" %%i IN (UmbracoVersion.txt) DO IF NOT DEFINED comment SET "comment=%%i"
|
||||
|
||||
REM If there's arguments on the command line overrule UmbracoVersion.txt and use that as the version
|
||||
IF [%2] NEQ [] (SET release=%2)
|
||||
IF [%3] NEQ [] (SET comment=%3) ELSE (IF [%2] NEQ [] (SET "comment="))
|
||||
|
||||
REM Get the "is continuous integration" from the parameters
|
||||
SET "isci=0"
|
||||
IF [%1] NEQ [] (SET isci=1)
|
||||
|
||||
SET version=%release%
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
ECHO.
|
||||
ECHO Building Umbraco %version%
|
||||
ECHO.
|
||||
|
||||
ReplaceIISExpressPortNumber.exe ..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj %release%
|
||||
|
||||
ECHO.
|
||||
ECHO Removing the belle build folder and bower_components folder to make sure everything is clean as a whistle
|
||||
RD ..\src\Umbraco.Web.UI.Client\build /Q /S
|
||||
RD ..\src\Umbraco.Web.UI.Client\bower_components /Q /S
|
||||
|
||||
ECHO.
|
||||
ECHO Removing existing built files to make sure everything is clean as a whistle
|
||||
RMDIR /Q /S _BuildOutput
|
||||
DEL /F /Q UmbracoCms.*.zip
|
||||
DEL /F /Q UmbracoExamine.*.zip
|
||||
DEL /F /Q UmbracoCms.*.nupkg
|
||||
DEL /F /Q webpihash.txt
|
||||
|
||||
ECHO.
|
||||
ECHO Making sure Git is in the path so that the build can succeed
|
||||
CALL InstallGit.cmd
|
||||
|
||||
REM Adding the default Git path so that if it's installed it can actually be found
|
||||
REM This is necessary because SETLOCAL is on in InstallGit.cmd so that one might find Git,
|
||||
REM but the path setting is lost due to SETLOCAL
|
||||
path=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH%
|
||||
|
||||
ECHO.
|
||||
ECHO Making sure we have a web.config
|
||||
IF NOT EXIST %CD%\..\src\Umbraco.Web.UI\web.config COPY %CD%\..\src\Umbraco.Web.UI\web.Template.config %CD%\..\src\Umbraco.Web.UI\web.config
|
||||
|
||||
ECHO.
|
||||
ECHO.
|
||||
ECHO Performing MSBuild and producing Umbraco binaries zip files
|
||||
ECHO This takes a few minutes and logging is set to report warnings
|
||||
ECHO and errors only so it might seems like nothing is happening for a while.
|
||||
ECHO You can check the msbuild.log file for progress.
|
||||
ECHO.
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "Build.proj" /p:BUILD_RELEASE=%release% /p:BUILD_COMMENT=%comment% /p:NugetPackagesDirectory=%nuGetFolder% /consoleloggerparameters:Summary;ErrorsOnly;WarningsOnly /fileLogger
|
||||
IF ERRORLEVEL 1 GOTO :error
|
||||
|
||||
ECHO.
|
||||
ECHO Setting node_modules folder to hidden to prevent VS13 from crashing on it while loading the websites project
|
||||
attrib +h ..\src\Umbraco.Web.UI.Client\node_modules
|
||||
|
||||
ECHO.
|
||||
ECHO Adding Web.config transform files to the NuGet package
|
||||
REN .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
|
||||
REN .\_BuildOutput\WebApp\Xslt\Web.config Web.config.transform
|
||||
|
||||
ECHO.
|
||||
ECHO Packing the NuGet release files
|
||||
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.Core.nuspec -Version %version% -Symbols -Verbosity quiet
|
||||
..\src\.nuget\NuGet.exe Pack NuSpecs\UmbracoCms.nuspec -Version %version% -Verbosity quiet
|
||||
IF ERRORLEVEL 1 GOTO :error
|
||||
|
||||
:success
|
||||
ECHO.
|
||||
ECHO No errors were detected!
|
||||
ECHO There may still be some in the output, which you would need to investigate.
|
||||
ECHO Warnings are usually normal.
|
||||
GOTO :EOF
|
||||
|
||||
:error
|
||||
|
||||
ECHO.
|
||||
ECHO Errors were detected!
|
||||
|
||||
REM don't pause if continuous integration else the build server waits forever
|
||||
REM before cancelling the build (and, there is noone to read the output anyways)
|
||||
IF isci NEQ 1 PAUSE
|
||||
@@ -0,0 +1,347 @@
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<!--
|
||||
****************************************************
|
||||
INCLUDES
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<PropertyGroup>
|
||||
<MSBuildCommunityTasksPath>..\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
|
||||
<UmbracoMSBuildTasksPath>..\UmbracoMSBuildTasks</UmbracoMSBuildTasksPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
|
||||
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
|
||||
|
||||
<UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<InputFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
|
||||
<OutputFile ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Using Namespace="System.IO" />
|
||||
<Using Namespace="System.Linq" />
|
||||
<Using Namespace="System.Security.Cryptography" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
foreach (var item in InputFiles)
|
||||
{
|
||||
string path = item.ItemSpec;
|
||||
|
||||
using (FileStream stream = new FileStream(path, FileMode.Open))
|
||||
{
|
||||
using (var cryptoProvider = new SHA1CryptoServiceProvider())
|
||||
{
|
||||
|
||||
var fileHash = cryptoProvider.ComputeHash(stream);
|
||||
|
||||
using (TextWriter w = new StreamWriter(OutputFile, false))
|
||||
{
|
||||
w.WriteLine(string.Join("", fileHash.Select(b => b.ToString("x2"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
|
||||
|
||||
<!--
|
||||
****************************************************
|
||||
VARIABLES
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<!-- NB: BUILD_NUMBER is passed in by the build server -->
|
||||
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_NIGHTLY)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_NIGHTLY)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!='' AND '$(BUILD_NIGHTLY)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)-$(BUILD_NIGHTLY)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildConfiguration>Release</BuildConfiguration>
|
||||
<BuildFolder>_BuildOutput\</BuildFolder>
|
||||
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
|
||||
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
|
||||
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
|
||||
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
|
||||
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
|
||||
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
|
||||
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
|
||||
<ConfigsFolder>$(BuildFolder)Configs\</ConfigsFolder>
|
||||
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
|
||||
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
|
||||
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
|
||||
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
|
||||
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
|
||||
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data" />
|
||||
<SystemFolders Include="$(WebAppFolder)Media" />
|
||||
<SystemFolders Include="$(WebAppFolder)Views" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
****************************************************
|
||||
TARGETS
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
|
||||
<Message Text="Build finished" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
|
||||
<ItemGroup>
|
||||
<WebPiFile Include="$(BuildZipFileNameWebPi)" />
|
||||
</ItemGroup>
|
||||
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
|
||||
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
|
||||
<Message Text="Deleting $(BuildFolder)" Importance="high" />
|
||||
<RemoveDir Directories="$(BuildFolder)" />
|
||||
<Message Text="Finished deleting $(BuildFolder)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebPiApp" DependsOnTargets="ZipWebApp" >
|
||||
<!-- Clean folders -->
|
||||
<RemoveDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)umbraco" />
|
||||
|
||||
<!-- Copy fresh built umbraco files -->
|
||||
<Exec Command="xcopy %22$(WebAppFolderAbsolutePath)*%22 %22$(WebPiFolderAbsolutePath)umbraco%22 /S /E /Y /I" />
|
||||
|
||||
<!-- Copy Web Pi template files -->
|
||||
<ItemGroup>
|
||||
<WebPiFiles Include="..\src\WebPi\**\*.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(WebPiFiles)"
|
||||
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
|
||||
<!-- Zip the files -->
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22 -x!dotLess.Core.dll -x![Content_Types].xml >NUL" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
|
||||
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22 -x!dotLess.Core.dll >NUL" />
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileName)%22 %22$(WebAppFolderAbsolutePath)*%22 -x!dotLess.Core.dll -x![Content_Types].xml >NUL" />
|
||||
|
||||
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CreateSystemFolders" DependsOnTargets="CopyBelleBuild" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
|
||||
<MakeDir Directories="@(SystemFolders)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyBelleBuild" DependsOnTargets="CopyLibraries" >
|
||||
<ItemGroup>
|
||||
<BelleFiles Include="..\src\Umbraco.Web.UI.Client\build\belle\**\*.*" Exclude="..\src\Umbraco.Web.UI.Client\build\belle\index.html" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(BelleFiles)"
|
||||
DestinationFiles="@(BelleFiles->'$(WebAppFolder)umbraco\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
|
||||
<!-- Copy SQL CE -->
|
||||
<ItemGroup>
|
||||
<SQLCE4Files
|
||||
Include="..\src\packages\SqlServerCE.4.0.0.1\**\*.*"
|
||||
Exclude="..\src\packages\SqlServerCE.4.0.0.1\lib\**\*;..\src\packages\SqlServerCE.4.0.0.1\**\*.nu*"
|
||||
/>
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(SolutionBinFolder)%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
</Target>
|
||||
|
||||
<!-- Offset the modified timestamps on all umbraco dlls, as WebResources break if date is in the future, which, due to timezone offsets can happen. -->
|
||||
<Target Name="OffsetTimestamps" DependsOnTargets="CopyTransformedWebConfig">
|
||||
<CreateItem Include="$(BuildFolder)**\umbraco.*.dll">
|
||||
<Output TaskParameter="Include" ItemName="FilesToOffsetTimestamp" />
|
||||
</CreateItem>
|
||||
<Message Text="Starting to offset timestamps" Importance="high" />
|
||||
<Umbraco.MSBuild.Tasks.TimestampOffset Files="@(FilesToOffsetTimestamp)" Offset="-11" />
|
||||
<Message Text="Finished offsetting timestamps" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the transformed web.config file to the root -->
|
||||
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyTransformedConfig">
|
||||
<ItemGroup>
|
||||
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(WebConfigFile)"
|
||||
DestinationFiles="$(WebAppFolder)Web.config"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the config files and rename them to *.config.transform -->
|
||||
<Target Name="CopyTransformedConfig" DependsOnTargets="CopyXmlDocumentation">
|
||||
<ItemGroup>
|
||||
<ConfigFiles Include="$(WebAppFolder)config\*.config;$(WebAppFolder)config\*.js" />
|
||||
<CustomLanguageFiles Include="$(WebAppFolder)config\lang\*.xml" />
|
||||
<WebConfigTransformFile Include="$(WebAppFolder)Web.config" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(ConfigFiles)"
|
||||
DestinationFiles="@(ConfigFiles->'$(ConfigsFolder)\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<Copy SourceFiles="@(CustomLanguageFiles)"
|
||||
DestinationFiles="@(CustomLanguageFiles->'$(ConfigsFolder)Lang\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<Copy SourceFiles="@(WebConfigTransformFile)"
|
||||
DestinationFiles="$(ConfigsFolder)Web.config.transform"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the xml documentation to the bin folder -->
|
||||
<Target Name="CopyXmlDocumentation" DependsOnTargets="CleanupPresentation">
|
||||
<ItemGroup>
|
||||
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(XmlDocumentationFiles)"
|
||||
DestinationFiles="@(XmlDocumentationFiles->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Message Text="CopyXmlDocumentation" />
|
||||
</Target>
|
||||
|
||||
<!-- Unlike 2010, the VS2012 build targets file doesn't clean up the umbraco.presentation dir, do it manually -->
|
||||
<Target Name="CleanupPresentation" DependsOnTargets="CompileProjects">
|
||||
<ItemGroup>
|
||||
<PresentationFolderToDelete Include="$(WebAppFolder)umbraco.presentation" />
|
||||
</ItemGroup>
|
||||
<RemoveDir Directories="@(PresentationFolderToDelete)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects" DependsOnTargets="SetVersionNumber">
|
||||
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
|
||||
<!-- Build the Umbraco.Web.UI project -->
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath);Verbosity=minimal" Targets="Clean;Rebuild;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
|
||||
<!-- DONE -->
|
||||
<Message Text="Finished compiling projects" Importance="high" />
|
||||
</Target>
|
||||
|
||||
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<PropertyGroup>
|
||||
<NewVersion>$(BUILD_RELEASE)</NewVersion>
|
||||
<NewVersion Condition="'$(BUILD_COMMENT)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)</NewVersion>
|
||||
<NewVersion Condition="'$(BUILD_NIGHTLY)'!=''">$(BUILD_RELEASE)-$(BUILD_NIGHTLY)</NewVersion>
|
||||
<NewVersion Condition="'$(BUILD_COMMENT)'!='' And '$(BUILD_NIGHTLY)'!=''">$(BUILD_RELEASE)-$(BUILD_COMMENT)-$(BUILD_NIGHTLY)</NewVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta and +nightly (if they're there) -->
|
||||
<FileUpdate
|
||||
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
|
||||
ReplacementText="$(BUILD_RELEASE)"/>
|
||||
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="CurrentComment { get { return "(.+)?""
|
||||
ReplacementText="CurrentComment { get { return "$(BUILD_COMMENT)""/>
|
||||
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Condition="'$(BUILD_NIGHTLY)'!=''"
|
||||
Regex="CurrentComment { get { return "(.+)?""
|
||||
ReplacementText="CurrentComment { get { return "$(BUILD_NIGHTLY)""/>
|
||||
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Condition="'$(BUILD_COMMENT)'!='' AND '$(BUILD_NIGHTLY)'!=''"
|
||||
Regex="CurrentComment { get { return "(.+)?""
|
||||
ReplacementText="CurrentComment { get { return "$(BUILD_COMMENT)-$(BUILD_NIGHTLY)""/>
|
||||
|
||||
<!--This updates the AssemblyFileVersion for the solution to the umbraco version-->
|
||||
<FileUpdate
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyFileVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyFileVersion("$(BUILD_RELEASE)")"/>
|
||||
|
||||
<!--This updates the AssemblyInformationalVersion for the solution to the umbraco version and comment-->
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_COMMENT)'!=''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyInformationalVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyInformationalVersion("$(BUILD_RELEASE)-$(BUILD_COMMENT)")"/>
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_COMMENT)'==''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyInformationalVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyInformationalVersion("$(BUILD_RELEASE)")"/>
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_NIGHTLY)'!=''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyInformationalVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyInformationalVersion("$(BUILD_RELEASE)-$(BUILD_NIGHTLY)")"/>
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_COMMENT)'!='' AND '$(BUILD_NIGHTLY)'!=''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyInformationalVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyInformationalVersion("$(BUILD_RELEASE)-$(BUILD_COMMENT)-$(BUILD_NIGHTLY)")"/>
|
||||
<FileUpdate
|
||||
Condition="'$(BUILD_COMMENT)'=='' AND '$(BUILD_NIGHTLY)'==''"
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyInformationalVersion\("(.+)?"\)"
|
||||
ReplacementText="AssemblyInformationalVersion("$(BUILD_RELEASE)")"/>
|
||||
|
||||
<!--This updates the copyright year-->
|
||||
<FileUpdate
|
||||
Files="..\src\SolutionInfo.cs"
|
||||
Regex="AssemblyCopyright\("Copyright © Umbraco (\d{4})"\)"
|
||||
ReplacementText="AssemblyCopyright("Copyright © Umbraco $([System.DateTime]::Now.ToString(`yyyy`))")"/>
|
||||
|
||||
<XmlPoke XmlInputPath=".\NuSpecs\build\UmbracoCms.props"
|
||||
Namespaces="<Namespace Prefix='x' Uri='http://schemas.microsoft.com/developer/msbuild/2003' />"
|
||||
Query="//x:UmbracoVersion"
|
||||
Value="$(NewVersion)" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,33 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL
|
||||
|
||||
SET release=%1
|
||||
ECHO Installing Npm NuGet Package
|
||||
|
||||
SET nuGetFolder=%CD%\..\src\packages\
|
||||
ECHO Configured packages folder: %nuGetFolder%
|
||||
ECHO Current folder: %CD%
|
||||
|
||||
%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet
|
||||
|
||||
for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\"
|
||||
for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\"
|
||||
|
||||
ECHO Adding Npm and Node to path
|
||||
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
|
||||
PATH=%npmPath%;%nodePath%;%PATH%
|
||||
|
||||
SET buildFolder=%CD%
|
||||
|
||||
ECHO Change directory to %CD%\..\src\Umbraco.Web.UI.Client\
|
||||
CD %CD%\..\src\Umbraco.Web.UI.Client\
|
||||
|
||||
ECHO Do npm install and the grunt build of Belle
|
||||
call npm cache clean --quiet
|
||||
call npm install --quiet
|
||||
call npm install -g grunt-cli --quiet
|
||||
call npm install -g bower --quiet
|
||||
call grunt build --buildversion=%release%
|
||||
|
||||
ECHO Move back to the build folder
|
||||
CD %buildFolder%
|
||||
@@ -0,0 +1,20 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL
|
||||
|
||||
SET release=%1
|
||||
ECHO Installing Npm NuGet Package
|
||||
|
||||
SET nuGetFolder=%CD%\..\src\packages\
|
||||
ECHO Configured packages folder: %nuGetFolder%
|
||||
ECHO Current folder: %CD%
|
||||
|
||||
%CD%\..\src\.nuget\NuGet.exe install Npm.js -OutputDirectory %nuGetFolder% -Verbosity quiet
|
||||
|
||||
for /f "delims=" %%A in ('dir %nuGetFolder%node.js.* /b') do set "nodePath=%nuGetFolder%%%A\"
|
||||
for /f "delims=" %%A in ('dir %nuGetFolder%npm.js.* /b') do set "npmPath=%nuGetFolder%%%A\tools\"
|
||||
|
||||
ECHO Adding Npm and Node to path
|
||||
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
|
||||
PATH=%npmPath%;%nodePath%;%PATH%
|
||||
|
||||
Powershell.exe -ExecutionPolicy Unrestricted -File .\BuildDocs.ps1
|
||||
@@ -0,0 +1,100 @@
|
||||
$PSScriptFilePath = (Get-Item $MyInvocation.MyCommand.Path);
|
||||
$RepoRoot = (get-item $PSScriptFilePath).Directory.Parent.FullName;
|
||||
$SolutionRoot = Join-Path -Path $RepoRoot "src";
|
||||
$ToolsRoot = Join-Path -Path $RepoRoot "tools";
|
||||
$DocFx = Join-Path -Path $ToolsRoot "docfx\docfx.exe"
|
||||
$DocFxFolder = (Join-Path -Path $ToolsRoot "docfx")
|
||||
$DocFxJson = Join-Path -Path $RepoRoot "apidocs\docfx.json"
|
||||
$7Zip = Join-Path -Path $ToolsRoot "7zip\7za.exe"
|
||||
$DocFxSiteOutput = Join-Path -Path $RepoRoot "apidocs\_site\*.*"
|
||||
$NgDocsSiteOutput = Join-Path -Path $RepoRoot "src\Umbraco.Web.UI.Client\docs\api\*.*"
|
||||
$ProgFiles86 = [Environment]::GetEnvironmentVariable("ProgramFiles(x86)");
|
||||
$MSBuild = "$ProgFiles86\MSBuild\14.0\Bin\MSBuild.exe"
|
||||
|
||||
|
||||
################ Do the UI docs
|
||||
|
||||
"Changing to Umbraco.Web.UI.Client folder"
|
||||
cd ..
|
||||
cd src\Umbraco.Web.UI.Client
|
||||
Write-Host $(Get-Location)
|
||||
|
||||
"Creating build folder so MSBuild doesn't run the whole grunt build"
|
||||
if (-Not (Test-Path "build")) {
|
||||
md "build"
|
||||
}
|
||||
|
||||
"Installing node"
|
||||
# Check if Install-Product exists, should only exist on the build server
|
||||
if (Get-Command Install-Product -errorAction SilentlyContinue)
|
||||
{
|
||||
Install-Product node ''
|
||||
}
|
||||
|
||||
"Installing node modules"
|
||||
& npm install
|
||||
|
||||
"Installing grunt"
|
||||
& npm install -g grunt-cli
|
||||
|
||||
"Moving back to build folder"
|
||||
cd ..
|
||||
cd ..
|
||||
cd build
|
||||
Write-Host $(Get-Location)
|
||||
|
||||
& grunt --gruntfile ../src/umbraco.web.ui.client/gruntfile.js docs
|
||||
|
||||
# change baseUrl
|
||||
$BaseUrl = "https://our.umbraco.org/apidocs/ui/"
|
||||
$IndexPath = "../src/umbraco.web.ui.client/docs/api/index.html"
|
||||
(Get-Content $IndexPath).replace('location.href.replace(rUrl, indexFile)', "`'" + $BaseUrl + "`'") | Set-Content $IndexPath
|
||||
# zip it
|
||||
|
||||
& $7Zip a -tzip ui-docs.zip $NgDocsSiteOutput -r
|
||||
|
||||
################ Do the c# docs
|
||||
|
||||
# Build the solution in debug mode
|
||||
$SolutionPath = Join-Path -Path $SolutionRoot -ChildPath "umbraco.sln"
|
||||
& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount /t:Clean
|
||||
if (-not $?)
|
||||
{
|
||||
throw "The MSBuild process returned an error code."
|
||||
}
|
||||
& $MSBuild "$SolutionPath" /p:Configuration=Debug /maxcpucount
|
||||
if (-not $?)
|
||||
{
|
||||
throw "The MSBuild process returned an error code."
|
||||
}
|
||||
|
||||
# Go get docfx if we don't hae it
|
||||
$FileExists = Test-Path $DocFx
|
||||
If ($FileExists -eq $False) {
|
||||
|
||||
If(!(Test-Path $DocFxFolder))
|
||||
{
|
||||
New-Item $DocFxFolder -type directory
|
||||
}
|
||||
|
||||
$DocFxZip = Join-Path -Path $ToolsRoot "docfx\docfx.zip"
|
||||
$DocFxSource = "https://github.com/dotnet/docfx/releases/download/v1.9.4/docfx.zip"
|
||||
Invoke-WebRequest $DocFxSource -OutFile $DocFxZip
|
||||
|
||||
#unzip it
|
||||
& $7Zip e $DocFxZip "-o$DocFxFolder"
|
||||
}
|
||||
|
||||
#clear site
|
||||
If(Test-Path(Join-Path -Path $RepoRoot "apidocs\_site"))
|
||||
{
|
||||
Remove-Item $DocFxSiteOutput -recurse
|
||||
}
|
||||
|
||||
# run it!
|
||||
& $DocFx metadata $DocFxJson
|
||||
& $DocFx build $DocFxJson
|
||||
|
||||
# zip it
|
||||
|
||||
& $7Zip a -tzip csharp-docs.zip $DocFxSiteOutput -r
|
||||
@@ -1,18 +1,18 @@
|
||||
@ECHO OFF
|
||||
SETLOCAL
|
||||
REM SETLOCAL is on, so changes to the path not persist to the actual user's path
|
||||
:: SETLOCAL is on, so changes to the path not persist to the actual user's path
|
||||
|
||||
git.exe --version
|
||||
IF %ERRORLEVEL%==9009 GOTO :trydefaultpath
|
||||
REM OK, DONE
|
||||
GOTO :EOF
|
||||
:: Git is installed, no need to to anything else
|
||||
|
||||
:trydefaultpath
|
||||
PATH=C:\Program Files (x86)\Git\cmd;C:\Program Files\Git\cmd;%PATH%
|
||||
git.exe --version
|
||||
IF %ERRORLEVEL%==9009 GOTO :showerror
|
||||
REM OK, DONE
|
||||
GOTO :EOF
|
||||
:: Git is installed, no need to to anything else
|
||||
|
||||
:showerror
|
||||
ECHO Git is not in your path and could not be found in C:\Program Files (x86)\Git\cmd nor in C:\Program Files\Git\cmd
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#
|
||||
|
||||
function Build-UmbracoDocs
|
||||
{
|
||||
$uenv = Get-UmbracoBuildEnv
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$out = "$($uenv.SolutionRoot)\build.out"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
|
||||
$buildTemp = "$PSScriptRoot\temp"
|
||||
$cache = 2
|
||||
|
||||
Prepare-Build -keep $uenv
|
||||
|
||||
################ Do the UI docs
|
||||
# get a temp clean node env (will restore)
|
||||
Sandbox-Node $uenv
|
||||
|
||||
Write-Host "Executing gulp docs"
|
||||
|
||||
push-location "$($uenv.SolutionRoot)\src\Umbraco.Web.UI.Client"
|
||||
write "node version is:" > $tmp\belle-docs.log
|
||||
&node -v >> $tmp\belle-docs.log 2>&1
|
||||
write "npm version is:" >> $tmp\belle-docs.log 2>&1
|
||||
&npm -v >> $tmp\belle-docs.log 2>&1
|
||||
write "executing npm install" >> $tmp\belle-docs.log 2>&1
|
||||
&npm install >> $tmp\belle-docs.log 2>&1
|
||||
write "executing bower install" >> $tmp\belle-docs.log 2>&1
|
||||
&npm install -g bower >> $tmp\belle-docs.log 2>&1
|
||||
write "installing gulp" >> $tmp\belle-docs.log 2>&1
|
||||
&npm install -g gulp >> $tmp\belle-docs.log 2>&1
|
||||
write "installing gulp-cli" >> $tmp\belle-docs.log 2>&1
|
||||
&npm install -g gulp-cli --quiet >> $tmp\belle-docs.log 2>&1
|
||||
write "building docs using gulp" >> $tmp\belle-docs.log 2>&1
|
||||
&gulp docs >> $tmp\belle-docs.log 2>&1
|
||||
pop-location
|
||||
|
||||
Write-Host "Completed gulp docs build"
|
||||
|
||||
# fixme - should we filter the log to find errors?
|
||||
#get-content .\build.tmp\belle-docs.log | %{ if ($_ -match "build") { write $_}}
|
||||
|
||||
# change baseUrl
|
||||
$baseUrl = "https://our.umbraco.org/apidocs/ui/"
|
||||
$indexPath = "$src/Umbraco.Web.UI.Client/docs/api/index.html"
|
||||
(Get-Content $indexPath).Replace("location.href.replace(rUrl, indexFile)", "'$baseUrl'") `
|
||||
| Set-Content $indexPath
|
||||
|
||||
# restore
|
||||
Restore-Node
|
||||
|
||||
# zip
|
||||
&$uenv.Zip a -tzip -r "$out\ui-docs.zip" "$src\Umbraco.Web.UI.Client\docs\api\*.*" `
|
||||
> $null
|
||||
|
||||
################ Do the c# docs
|
||||
|
||||
Write-Host "Build C# documentation"
|
||||
|
||||
# Build the solution in debug mode
|
||||
# FIXME no only a simple compilation should be enough!
|
||||
# FIXME we MUST handle msbuild & co error codes!
|
||||
# FIXME deal with weird things in gitconfig?
|
||||
#Build-Umbraco -Configuration Debug
|
||||
Restore-NuGet $uenv
|
||||
Compile-Umbraco $uenv "Debug" # FIXME different log file!
|
||||
Restore-WebConfig "$src\Umbraco.Web.UI"
|
||||
|
||||
# ensure we have docfx
|
||||
Get-DocFx $uenv $buildTemp
|
||||
|
||||
# clear
|
||||
$docFxOutput = "$($uenv.SolutionRoot)\apidocs\_site"
|
||||
if (test-path($docFxOutput))
|
||||
{
|
||||
Remove-Directory $docFxOutput
|
||||
}
|
||||
|
||||
# run
|
||||
$docFxJson = "$($uenv.SolutionRoot)\apidocs\docfx.json"
|
||||
push-location "$($uenv.SolutionRoot)\build" # silly docfx.json wants this
|
||||
|
||||
Write-Host "Run DocFx metadata"
|
||||
Write-Host "Logging to $tmp\docfx.metadata.log"
|
||||
&$uenv.DocFx metadata $docFxJson > "$tmp\docfx.metadata.log"
|
||||
Write-Host "Run DocFx build"
|
||||
Write-Host "Logging to $tmp\docfx.build.log"
|
||||
&$uenv.DocFx build $docFxJson > "$tmp\docfx.build.log"
|
||||
|
||||
pop-location
|
||||
|
||||
# zip
|
||||
&$uenv.Zip a -tzip -r "$out\csharp-docs.zip" "$docFxOutput\*.*" `
|
||||
> $null
|
||||
}
|
||||
|
||||
function Get-DocFx($uenv, $buildTemp)
|
||||
{
|
||||
$docFx = "$buildTemp\docfx"
|
||||
if (-not (test-path $docFx))
|
||||
{
|
||||
Write-Host "Download DocFx..."
|
||||
$source = "https://github.com/dotnet/docfx/releases/download/v2.19.2/docfx.zip"
|
||||
Invoke-WebRequest $source -OutFile "$buildTemp\docfx.zip"
|
||||
|
||||
&$uenv.Zip x "$buildTemp\docfx.zip" -o"$buildTemp\docfx" -aos > $nul
|
||||
Remove-File "$buildTemp\docfx.zip"
|
||||
}
|
||||
$uenv | add-member -memberType NoteProperty -name DocFx -value "$docFx\docfx.exe"
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
#
|
||||
# Get-UmbracoBuildEnv
|
||||
# Gets the Umbraco build environment
|
||||
# Downloads tools if necessary
|
||||
#
|
||||
function Get-UmbracoBuildEnv
|
||||
{
|
||||
# store tools in the module's directory
|
||||
# and cache them for two days
|
||||
$path = "$PSScriptRoot\temp"
|
||||
$cache = 2
|
||||
|
||||
if (-not (test-path $path))
|
||||
{
|
||||
mkdir $path > $null
|
||||
}
|
||||
|
||||
# ensure we have NuGet
|
||||
$nuget = "$path\nuget.exe"
|
||||
$source = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
|
||||
if ((test-path $nuget) -and ((ls $nuget).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
|
||||
{
|
||||
Remove-File $nuget
|
||||
}
|
||||
if (-not (test-path $nuget))
|
||||
{
|
||||
Write-Host "Download NuGet..."
|
||||
Invoke-WebRequest $source -OutFile $nuget
|
||||
}
|
||||
|
||||
# ensure we have 7-Zip
|
||||
$sevenZip = "$path\7za.exe"
|
||||
if ((test-path $sevenZip) -and ((ls $sevenZip).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
|
||||
{
|
||||
Remove-File $sevenZip
|
||||
}
|
||||
if (-not (test-path $sevenZip))
|
||||
{
|
||||
Write-Host "Download 7-Zip..."
|
||||
&$nuget install 7-Zip.CommandLine -OutputDirectory $path -Verbosity quiet
|
||||
$dir = ls "$path\7-Zip.CommandLine.*" | sort -property Name -descending | select -first 1
|
||||
$file = ls -path "$dir" -name 7za.exe -recurse
|
||||
$file = ls -path "$dir" -name 7za.exe -recurse | select -first 1 #A select is because there is tools\7za.exe & tools\x64\7za.exe
|
||||
mv "$dir\$file" $sevenZip
|
||||
Remove-Directory $dir
|
||||
}
|
||||
|
||||
# ensure we have vswhere
|
||||
$vswhere = "$path\vswhere.exe"
|
||||
if ((test-path $vswhere) -and ((ls $vswhere).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
|
||||
{
|
||||
Remove-File $vswhere
|
||||
}
|
||||
if (-not (test-path $vswhere))
|
||||
{
|
||||
Write-Host "Download VsWhere..."
|
||||
&$nuget install vswhere -OutputDirectory $path -Verbosity quiet
|
||||
$dir = ls "$path\vswhere.*" | sort -property Name -descending | select -first 1
|
||||
$file = ls -path "$dir" -name vswhere.exe -recurse
|
||||
mv "$dir\$file" $vswhere
|
||||
Remove-Directory $dir
|
||||
}
|
||||
|
||||
# ensure we have semver
|
||||
$semver = "$path\Semver.dll"
|
||||
if ((test-path $semver) -and ((ls $semver).CreationTime -lt [DateTime]::Now.AddDays(-$cache)))
|
||||
{
|
||||
Remove-File $semver
|
||||
}
|
||||
if (-not (test-path $semver))
|
||||
{
|
||||
Write-Host "Download Semver..."
|
||||
&$nuget install semver -OutputDirectory $path -Verbosity quiet
|
||||
$dir = ls "$path\semver.*" | sort -property Name -descending | select -first 1
|
||||
$file = "$dir\lib\net452\Semver.dll"
|
||||
if (-not (test-path $file))
|
||||
{
|
||||
Write-Error "Failed to file $file"
|
||||
return
|
||||
}
|
||||
mv "$file" $semver
|
||||
Remove-Directory $dir
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
[Reflection.Assembly]::LoadFile($semver) > $null
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error -Exception $_.Exception -Message "Failed to load $semver"
|
||||
break
|
||||
}
|
||||
|
||||
# ensure we have node
|
||||
$node = "$path\node-v6.9.1-win-x86"
|
||||
$source = "http://nodejs.org/dist/v6.9.1/node-v6.9.1-win-x86.7z"
|
||||
if (-not (test-path $node))
|
||||
{
|
||||
Write-Host "Download Node..."
|
||||
Invoke-WebRequest $source -OutFile "$path\node-v6.9.1-win-x86.7z"
|
||||
&$sevenZip x "$path\node-v6.9.1-win-x86.7z" -o"$path" -aos > $nul
|
||||
Remove-File "$path\node-v6.9.1-win-x86.7z"
|
||||
}
|
||||
|
||||
# note: why? node already brings everything we need!
|
||||
## ensure we have npm
|
||||
#$npm = "$path\npm.*"
|
||||
#$getNpm = $true
|
||||
#if (test-path $npm)
|
||||
#{
|
||||
# $getNpm = $false
|
||||
# $tmpNpm = ls "$path\npm.*" | sort -property Name -descending | select -first 1
|
||||
# if ($tmpNpm.CreationTime -lt [DateTime]::Now.AddDays(-$cache))
|
||||
# {
|
||||
# $getNpm = $true
|
||||
# }
|
||||
# else
|
||||
# {
|
||||
# $npm = $tmpNpm.ToString()
|
||||
# }
|
||||
#}
|
||||
#if ($getNpm)
|
||||
#{
|
||||
# Write-Host "Download Npm..."
|
||||
# &$nuget install npm -OutputDirectory $path -Verbosity quiet
|
||||
# $npm = ls "$path\npm.*" | sort -property Name -descending | select -first 1
|
||||
# $npm.CreationTime = [DateTime]::Now
|
||||
# $npm = $npm.ToString()
|
||||
#}
|
||||
|
||||
# find visual studio
|
||||
# will not work on VSO but VSO does not need it
|
||||
$vsPath = ""
|
||||
$vsVer = ""
|
||||
$msBuild = $null
|
||||
&$vswhere | foreach {
|
||||
if ($_.StartsWith("installationPath:")) { $vsPath = $_.SubString("installationPath:".Length).Trim() }
|
||||
if ($_.StartsWith("installationVersion:")) { $vsVer = $_.SubString("installationVersion:".Length).Trim() }
|
||||
}
|
||||
if ($vsPath -ne "")
|
||||
{
|
||||
$vsVerParts = $vsVer.Split('.')
|
||||
$vsMajor = [int]::Parse($vsVerParts[0])
|
||||
$vsMinor = [int]::Parse($vsVerParts[1])
|
||||
if ($vsMajor -eq 15) {
|
||||
$msBuild = "$vsPath\MSBuild\$vsMajor.0\Bin"
|
||||
}
|
||||
elseif ($vsMajor -eq 14) {
|
||||
$msBuild = "c:\Program Files (x86)\MSBuild\$vsMajor\Bin"
|
||||
}
|
||||
else
|
||||
{
|
||||
$msBuild = $null
|
||||
}
|
||||
}
|
||||
|
||||
$vs = $null
|
||||
if ($msBuild)
|
||||
{
|
||||
$vs = new-object -typeName PsObject
|
||||
$vs | add-member -memberType NoteProperty -name Path -value $vsPath
|
||||
$vs | add-member -memberType NoteProperty -name Major -value $vsMajor
|
||||
$vs | add-member -memberType NoteProperty -name Minor -value $vsMinor
|
||||
$vs | add-member -memberType NoteProperty -name MsBuild -value "$msBuild\MsBuild.exe"
|
||||
}
|
||||
|
||||
$solutionRoot = Get-FullPath "$PSScriptRoot\..\..\.."
|
||||
|
||||
$uenv = new-object -typeName PsObject
|
||||
$uenv | add-member -memberType NoteProperty -name SolutionRoot -value $solutionRoot
|
||||
$uenv | add-member -memberType NoteProperty -name VisualStudio -value $vs
|
||||
$uenv | add-member -memberType NoteProperty -name NuGet -value $nuget
|
||||
$uenv | add-member -memberType NoteProperty -name Zip -value $sevenZip
|
||||
$uenv | add-member -memberType NoteProperty -name VsWhere -value $vswhere
|
||||
$uenv | add-member -memberType NoteProperty -name Semver -value $semver
|
||||
$uenv | add-member -memberType NoteProperty -name NodePath -value $node
|
||||
#$uenv | add-member -memberType NoteProperty -name NpmPath -value $npm
|
||||
|
||||
return $uenv
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
#
|
||||
# Get-UmbracoVersion
|
||||
# Gets the Umbraco version
|
||||
#
|
||||
function Get-UmbracoVersion
|
||||
{
|
||||
$uenv = Get-UmbracoBuildEnv
|
||||
|
||||
# parse SolutionInfo and retrieve the version string
|
||||
$filepath = "$($uenv.SolutionRoot)\src\SolutionInfo.cs"
|
||||
$text = [System.IO.File]::ReadAllText($filepath)
|
||||
$match = [System.Text.RegularExpressions.Regex]::Matches($text, "AssemblyInformationalVersion\(`"(.+)?`"\)")
|
||||
$version = $match.Groups[1]
|
||||
|
||||
# semver-parse the version string
|
||||
$semver = [SemVer.SemVersion]::Parse($version)
|
||||
$release = "" + $semver.Major + "." + $semver.Minor + "." + $semver.Patch
|
||||
|
||||
$versions = new-object -typeName PsObject
|
||||
$versions | add-member -memberType NoteProperty -name Semver -value $semver
|
||||
$versions | add-member -memberType NoteProperty -name Release -value $release
|
||||
$versions | add-member -memberType NoteProperty -name Comment -value $semver.PreRelease
|
||||
$versions | add-member -memberType NoteProperty -name Build -value $semver.Build
|
||||
|
||||
return $versions
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
# finds msbuild
|
||||
function Get-VisualStudio($vswhere)
|
||||
{
|
||||
$vsPath = ""
|
||||
$vsVer = ""
|
||||
&$vswhere | foreach {
|
||||
if ($_.StartsWith("installationPath:")) { $vsPath = $_.SubString("installationPath:".Length).Trim() }
|
||||
if ($_.StartsWith("installationVersion:")) { $vsVer = $_.SubString("installationVersion:".Length).Trim() }
|
||||
}
|
||||
if ($vsPath -eq "") { return $null }
|
||||
|
||||
$vsVerParts = $vsVer.Split('.')
|
||||
$vsMajor = [int]::Parse($vsVerParts[0])
|
||||
$vsMinor = [int]::Parse($vsVerParts[1])
|
||||
if ($vsMajor -eq 15) {
|
||||
$msBuild = "$vsPath\MSBuild\$vsMajor.$vsMinor\Bin"
|
||||
}
|
||||
elseif ($vsMajor -eq 14) {
|
||||
$msBuild = "c:\Program Files (x86)\MSBuild\$vsMajor\Bin"
|
||||
}
|
||||
else { return $null }
|
||||
$msBuild = "$msBuild\MsBuild.exe"
|
||||
|
||||
$vs = new-object -typeName PsObject
|
||||
$vs | add-member -memberType NoteProperty -name Path -value $vsPath
|
||||
$vs | add-member -memberType NoteProperty -name Major -value $vsMajor
|
||||
$vs | add-member -memberType NoteProperty -name Minor -value $vsMinor
|
||||
$vs | add-member -memberType NoteProperty -name MsBuild -value $msBuild
|
||||
return $vs
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
#
|
||||
# Set-UmbracoContinuousVersion
|
||||
# Sets the Umbraco version for continuous integration
|
||||
#
|
||||
# -Version <version>
|
||||
# where <version> is a Semver valid version
|
||||
# eg 1.2.3, 1.2.3-alpha, 1.2.3-alpha+456
|
||||
#
|
||||
# -BuildNumber <buildNumber>
|
||||
# where <buildNumber> is a string coming from the build server
|
||||
# eg 34, 126, 1
|
||||
#
|
||||
function Set-UmbracoContinuousVersion
|
||||
{
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$version,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$buildNumber
|
||||
)
|
||||
|
||||
Write-Host "Version is currently set to $version"
|
||||
|
||||
$umbracoVersion = "$($version.Trim())-alpha$($buildNumber)"
|
||||
Write-Host "Setting Umbraco Version to $umbracoVersion"
|
||||
|
||||
Set-UmbracoVersion $umbracoVersion
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
#
|
||||
# Set-UmbracoVersion
|
||||
# Sets the Umbraco version
|
||||
#
|
||||
# -Version <version>
|
||||
# where <version> is a Semver valid version
|
||||
# eg 1.2.3, 1.2.3-alpha, 1.2.3-alpha+456
|
||||
#
|
||||
function Set-UmbracoVersion
|
||||
{
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$version
|
||||
)
|
||||
|
||||
$uenv = Get-UmbracoBuildEnv
|
||||
|
||||
try
|
||||
{
|
||||
[Reflection.Assembly]::LoadFile($uenv.Semver) > $null
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error "Failed to load $uenv.Semver"
|
||||
break
|
||||
}
|
||||
|
||||
# validate input
|
||||
$ok = [Regex]::Match($version, "^[0-9]+\.[0-9]+\.[0-9]+(\-[a-z0-9]+)?(\+[0-9]+)?$")
|
||||
if (-not $ok.Success)
|
||||
{
|
||||
Write-Error "Invalid version $version"
|
||||
break
|
||||
}
|
||||
|
||||
# parse input
|
||||
try
|
||||
{
|
||||
$semver = [SemVer.SemVersion]::Parse($version)
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error "Invalid version $version"
|
||||
break
|
||||
}
|
||||
|
||||
#
|
||||
$release = "" + $semver.Major + "." + $semver.Minor + "." + $semver.Patch
|
||||
|
||||
# edit files and set the proper versions and dates
|
||||
Write-Host "Update UmbracoVersion.cs"
|
||||
Replace-FileText "$($uenv.SolutionRoot)\src\Umbraco.Core\Configuration\UmbracoVersion.cs" `
|
||||
"(\d+)\.(\d+)\.(\d+)(.(\d+))?" `
|
||||
"$release"
|
||||
Replace-FileText "$($uenv.SolutionRoot)\src\Umbraco.Core\Configuration\UmbracoVersion.cs" `
|
||||
"CurrentComment { get { return `"(.+)`"" `
|
||||
"CurrentComment { get { return `"$($semver.PreRelease)`""
|
||||
Write-Host "Update SolutionInfo.cs"
|
||||
Replace-FileText "$($uenv.SolutionRoot)\src\SolutionInfo.cs" `
|
||||
"AssemblyFileVersion\(`"(.+)?`"\)" `
|
||||
"AssemblyFileVersion(`"$release`")"
|
||||
Replace-FileText "$($uenv.SolutionRoot)\src\SolutionInfo.cs" `
|
||||
"AssemblyInformationalVersion\(`"(.+)?`"\)" `
|
||||
"AssemblyInformationalVersion(`"$semver`")"
|
||||
$year = [System.DateTime]::Now.ToString("yyyy")
|
||||
Replace-FileText "$($uenv.SolutionRoot)\src\SolutionInfo.cs" `
|
||||
"AssemblyCopyright\(`"Copyright © Umbraco (\d{4})`"\)" `
|
||||
"AssemblyCopyright(`"Copyright © Umbraco $year`")"
|
||||
|
||||
# edit csproj and set IIS Express port number
|
||||
# this is a raw copy of ReplaceIISExpressPortNumber.exe
|
||||
# it probably can be achieved in a much nicer way - l8tr
|
||||
$source = @"
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Umbraco
|
||||
{
|
||||
public static class PortUpdater
|
||||
{
|
||||
public static void Update(string path, string release)
|
||||
{
|
||||
XmlDocument xmlDocument = new XmlDocument();
|
||||
string fullPath = Path.GetFullPath(path);
|
||||
xmlDocument.Load(fullPath);
|
||||
int result = 1;
|
||||
int.TryParse(release.Replace(`".`", `"`"), out result);
|
||||
while (result < 1024)
|
||||
result *= 10;
|
||||
XmlNode xmlNode1 = xmlDocument.GetElementsByTagName(`"IISUrl`").Item(0);
|
||||
if (xmlNode1 != null)
|
||||
xmlNode1.InnerText = `"http://localhost:`" + (object) result;
|
||||
XmlNode xmlNode2 = xmlDocument.GetElementsByTagName(`"DevelopmentServerPort`").Item(0);
|
||||
if (xmlNode2 != null)
|
||||
xmlNode2.InnerText = result.ToString((IFormatProvider) CultureInfo.InvariantCulture);
|
||||
xmlDocument.Save(fullPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
"@
|
||||
|
||||
$assem = (
|
||||
"System.Xml",
|
||||
"System.IO",
|
||||
"System.Globalization"
|
||||
)
|
||||
|
||||
Write-Host "Update Umbraco.Web.UI.csproj"
|
||||
add-type -referencedAssemblies $assem -typeDefinition $source -language CSharp
|
||||
$csproj = "$($uenv.SolutionRoot)\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj"
|
||||
[Umbraco.PortUpdater]::Update($csproj, $release)
|
||||
|
||||
return $semver
|
||||
}
|
||||
@@ -1,611 +0,0 @@
|
||||
|
||||
# Umbraco.Build.psm1
|
||||
#
|
||||
# $env:PSModulePath = "$pwd\build\Modules\;$env:PSModulePath"
|
||||
# Import-Module Umbraco.Build -Force -DisableNameChecking
|
||||
#
|
||||
# PowerShell Modules:
|
||||
# https://msdn.microsoft.com/en-us/library/dd878324%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
|
||||
#
|
||||
# PowerShell Module Manifest:
|
||||
# https://msdn.microsoft.com/en-us/library/dd878337%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
|
||||
#
|
||||
# See also
|
||||
# http://www.powershellmagazine.com/2014/08/15/pstip-taking-control-of-verbose-and-debug-output-part-5/
|
||||
|
||||
|
||||
. "$PSScriptRoot\Utilities.ps1"
|
||||
. "$PSScriptRoot\Get-VisualStudio.ps1"
|
||||
|
||||
. "$PSScriptRoot\Get-UmbracoBuildEnv.ps1"
|
||||
. "$PSScriptRoot\Set-UmbracoVersion.ps1"
|
||||
. "$PSScriptRoot\Set-UmbracoContinuousVersion.ps1"
|
||||
. "$PSScriptRoot\Get-UmbracoVersion.ps1"
|
||||
. "$PSScriptRoot\Verify-NuGet.ps1"
|
||||
|
||||
. "$PSScriptRoot\Build-UmbracoDocs.ps1"
|
||||
|
||||
#
|
||||
# Prepares the build
|
||||
#
|
||||
function Prepare-Build
|
||||
{
|
||||
param (
|
||||
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
|
||||
[Alias("k")]
|
||||
[switch]
|
||||
$keep = $false
|
||||
)
|
||||
|
||||
Write-Host ">> Prepare Build"
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$out = "$($uenv.SolutionRoot)\build.out"
|
||||
|
||||
# clear
|
||||
Write-Host "Clear folders and files"
|
||||
|
||||
Remove-Directory "$src\Umbraco.Web.UI.Client\bower_components"
|
||||
|
||||
if (-not $keep)
|
||||
{
|
||||
Remove-Directory "$tmp"
|
||||
Remove-Directory "$out"
|
||||
}
|
||||
|
||||
if (-not (Test-Path "$tmp"))
|
||||
{
|
||||
mkdir "$tmp" > $null
|
||||
}
|
||||
if (-not (Test-Path "$out"))
|
||||
{
|
||||
mkdir "$out" > $null
|
||||
}
|
||||
|
||||
# ensure proper web.config
|
||||
$webUi = "$src\Umbraco.Web.UI"
|
||||
Store-WebConfig $webUi
|
||||
Write-Host "Create clean web.config"
|
||||
Copy-File "$webUi\web.Template.config" "$webUi\web.config"
|
||||
}
|
||||
|
||||
function Clear-EnvVar($var)
|
||||
{
|
||||
$value = [Environment]::GetEnvironmentVariable($var)
|
||||
if (test-path "env:$var") { rm "env:$var" }
|
||||
return $value
|
||||
}
|
||||
|
||||
function Set-EnvVar($var, $value)
|
||||
{
|
||||
if ($value)
|
||||
{
|
||||
[Environment]::SetEnvironmentVariable($var, $value)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (test-path "env:$var") { rm "env:$var" }
|
||||
}
|
||||
}
|
||||
|
||||
function Sandbox-Node
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
$global:node_path = $env:path
|
||||
$nodePath = $uenv.NodePath
|
||||
$gitExe = (get-command git).Source
|
||||
$gitPath = [System.IO.Path]::GetDirectoryName($gitExe)
|
||||
$env:path = "$nodePath;$gitPath"
|
||||
|
||||
$global:node_nodepath = Clear-EnvVar "NODEPATH"
|
||||
$global:node_npmcache = Clear-EnvVar "NPM_CONFIG_CACHE"
|
||||
$global:node_npmprefix = Clear-EnvVar "NPM_CONFIG_PREFIX"
|
||||
}
|
||||
|
||||
function Restore-Node
|
||||
{
|
||||
$env:path = $node_path
|
||||
|
||||
Set-EnvVar "NODEPATH" $node_nodepath
|
||||
Set-EnvVar "NPM_CONFIG_CACHE" $node_npmcache
|
||||
Set-EnvVar "NPM_CONFIG_PREFIX" $node_npmprefix
|
||||
}
|
||||
|
||||
#
|
||||
# Builds the Belle UI project
|
||||
#
|
||||
function Compile-Belle
|
||||
{
|
||||
param (
|
||||
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
$version # an Umbraco version object (see Get-UmbracoVersion)
|
||||
)
|
||||
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
|
||||
Write-Host ">> Compile Belle"
|
||||
Write-Host "Logging to $tmp\belle.log"
|
||||
|
||||
# get a temp clean node env (will restore)
|
||||
Sandbox-Node $uenv
|
||||
|
||||
push-location "$($uenv.SolutionRoot)\src\Umbraco.Web.UI.Client"
|
||||
write "node version is:" > $tmp\belle.log
|
||||
&node -v >> $tmp\belle.log 2>&1
|
||||
write "npm version is:" >> $tmp\belle.log 2>&1
|
||||
&npm -v >> $tmp\belle.log 2>&1
|
||||
write "cleaning npm cache" >> $tmp\belle.log 2>&1
|
||||
&npm cache clean >> $tmp\belle.log 2>&1
|
||||
write "installing bower" >> $tmp\belle.log 2>&1
|
||||
&npm install -g bower >> $tmp\belle.log 2>&1
|
||||
write "installing gulp" >> $tmp\belle.log 2>&1
|
||||
&npm install -g gulp >> $tmp\belle.log 2>&1
|
||||
write "installing gulp-cli" >> $tmp\belle.log 2>&1
|
||||
&npm install -g gulp-cli --quiet >> $tmp\belle.log 2>&1
|
||||
write "executing npm install" >> $tmp\belle.log 2>&1
|
||||
&npm install >> $tmp\belle.log 2>&1
|
||||
write "executing gulp build for version $version" >> $tmp\belle.log 2>&1
|
||||
&gulp build --buildversion=$version.Release >> $tmp\belle.log 2>&1
|
||||
pop-location
|
||||
|
||||
# fixme - should we filter the log to find errors?
|
||||
#get-content .\build.tmp\belle.log | %{ if ($_ -match "build") { write $_}}
|
||||
|
||||
# restore
|
||||
Restore-Node
|
||||
|
||||
# setting node_modules folder to hidden
|
||||
# used to prevent VS13 from crashing on it while loading the websites project
|
||||
# also makes sure aspnet compiler does not try to handle rogue files and chokes
|
||||
# in VSO with Microsoft.VisualC.CppCodeProvider -related errors
|
||||
# use get-item -force 'cos it might be hidden already
|
||||
write "Set hidden attribute on node_modules"
|
||||
$dir = get-item -force "$src\Umbraco.Web.UI.Client\node_modules"
|
||||
$dir.Attributes = $dir.Attributes -bor ([System.IO.FileAttributes]::Hidden)
|
||||
}
|
||||
|
||||
#
|
||||
# Compiles Umbraco
|
||||
#
|
||||
function Compile-Umbraco
|
||||
{
|
||||
param (
|
||||
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
[string] $buildConfiguration = "Release"
|
||||
)
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$out = "$($uenv.SolutionRoot)\build.out"
|
||||
|
||||
if ($uenv.VisualStudio -eq $null)
|
||||
{
|
||||
Write-Error "Build environment does not provide VisualStudio."
|
||||
break
|
||||
}
|
||||
|
||||
$toolsVersion = "4.0"
|
||||
if ($uenv.VisualStudio.Major -eq 15)
|
||||
{
|
||||
$toolsVersion = "15.0"
|
||||
}
|
||||
|
||||
Write-Host ">> Compile Umbraco"
|
||||
Write-Host "Logging to $tmp\msbuild.umbraco.log"
|
||||
|
||||
# beware of the weird double \\ at the end of paths
|
||||
# see http://edgylogic.com/blog/powershell-and-external-commands-done-right/
|
||||
&$uenv.VisualStudio.MsBuild "$src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" `
|
||||
/p:WarningLevel=0 `
|
||||
/p:Configuration=$buildConfiguration `
|
||||
/p:Platform=AnyCPU `
|
||||
/p:UseWPP_CopyWebApplication=True `
|
||||
/p:PipelineDependsOnBuild=False `
|
||||
/p:OutDir=$tmp\bin\\ `
|
||||
/p:WebProjectOutputDir=$tmp\WebApp\\ `
|
||||
/p:Verbosity=minimal `
|
||||
/t:Clean`;Rebuild `
|
||||
/tv:$toolsVersion `
|
||||
/p:UmbracoBuild=True `
|
||||
> $tmp\msbuild.umbraco.log
|
||||
|
||||
# /p:UmbracoBuild tells the csproj that we are building from PS
|
||||
}
|
||||
|
||||
#
|
||||
# Prepare Tests
|
||||
#
|
||||
function Prepare-Tests
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
|
||||
Write-Host ">> Prepare Tests"
|
||||
|
||||
# fixme - idea is to avoid rebuilding everything for tests
|
||||
# but because of our weird assembly versioning (with .* stuff)
|
||||
# everything gets rebuilt all the time...
|
||||
#Copy-Files "$tmp\bin" "." "$tmp\tests"
|
||||
|
||||
# data
|
||||
Write-Host "Copy data files"
|
||||
if( -Not (Test-Path -Path "$tmp\tests\Packaging" ) )
|
||||
{
|
||||
Write-Host "Create packaging directory"
|
||||
New-Item -ItemType directory -Path "$tmp\tests\Packaging"
|
||||
}
|
||||
Copy-Files "$src\Umbraco.Tests\Packaging\Packages" "*" "$tmp\tests\Packaging\Packages"
|
||||
|
||||
# required for package install tests
|
||||
if( -Not (Test-Path -Path "$tmp\tests\bin" ) )
|
||||
{
|
||||
Write-Host "Create bin directory"
|
||||
New-Item -ItemType directory -Path "$tmp\tests\bin"
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Compiles Tests
|
||||
#
|
||||
function Compile-Tests
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$out = "$tmp\tests"
|
||||
|
||||
$buildConfiguration = "Release"
|
||||
|
||||
if ($uenv.VisualStudio -eq $null)
|
||||
{
|
||||
Write-Error "Build environment does not provide VisualStudio."
|
||||
break
|
||||
}
|
||||
|
||||
$toolsVersion = "4.0"
|
||||
if ($uenv.VisualStudio.Major -eq 15)
|
||||
{
|
||||
$toolsVersion = "15.0"
|
||||
}
|
||||
|
||||
Write-Host ">> Compile Tests"
|
||||
Write-Host "Logging to $tmp\msbuild.tests.log"
|
||||
|
||||
# beware of the weird double \\ at the end of paths
|
||||
# see http://edgylogic.com/blog/powershell-and-external-commands-done-right/
|
||||
&$uenv.VisualStudio.MsBuild "$src\Umbraco.Tests\Umbraco.Tests.csproj" `
|
||||
/p:WarningLevel=0 `
|
||||
/p:Configuration=$buildConfiguration `
|
||||
/p:Platform=AnyCPU `
|
||||
/p:UseWPP_CopyWebApplication=True `
|
||||
/p:PipelineDependsOnBuild=False `
|
||||
/p:OutDir=$out\\ `
|
||||
/p:Verbosity=minimal `
|
||||
/t:Build `
|
||||
/tv:$toolsVersion `
|
||||
/p:UmbracoBuild=True `
|
||||
/p:NugetPackages=$src\packages `
|
||||
> $tmp\msbuild.tests.log
|
||||
|
||||
# /p:UmbracoBuild tells the csproj that we are building from PS
|
||||
}
|
||||
|
||||
#
|
||||
# Cleans things up and prepare files after compilation
|
||||
#
|
||||
function Prepare-Packages
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
Write-Host ">> Prepare Packages"
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$out = "$($uenv.SolutionRoot)\build.out"
|
||||
|
||||
$buildConfiguration = "Release"
|
||||
|
||||
# restore web.config
|
||||
Restore-WebConfig "$src\Umbraco.Web.UI"
|
||||
|
||||
# cleanup build
|
||||
Write-Host "Clean build"
|
||||
Remove-File "$tmp\bin\*.dll.config"
|
||||
Remove-File "$tmp\WebApp\bin\*.dll.config"
|
||||
|
||||
# cleanup presentation
|
||||
Write-Host "Cleanup presentation"
|
||||
Remove-Directory "$tmp\WebApp\umbraco.presentation"
|
||||
|
||||
# create directories
|
||||
Write-Host "Create directories"
|
||||
mkdir "$tmp\Configs" > $null
|
||||
mkdir "$tmp\Configs\Lang" > $null
|
||||
mkdir "$tmp\WebApp\App_Data" > $null
|
||||
#mkdir "$tmp\WebApp\Media" > $null
|
||||
#mkdir "$tmp\WebApp\Views" > $null
|
||||
|
||||
# copy various files
|
||||
Write-Host "Copy xml documentation"
|
||||
cp -force "$tmp\bin\*.xml" "$tmp\WebApp\bin"
|
||||
|
||||
Write-Host "Copy transformed configs and langs"
|
||||
# note: exclude imageprocessor/*.config as imageprocessor pkg installs them
|
||||
Copy-Files "$tmp\WebApp\config" "*.config" "$tmp\Configs" `
|
||||
{ -not $_.RelativeName.StartsWith("imageprocessor") }
|
||||
Copy-Files "$tmp\WebApp\config" "*.js" "$tmp\Configs"
|
||||
Copy-Files "$tmp\WebApp\config\lang" "*.xml" "$tmp\Configs\Lang"
|
||||
Copy-File "$tmp\WebApp\web.config" "$tmp\Configs\web.config.transform"
|
||||
|
||||
Write-Host "Copy transformed web.config"
|
||||
Copy-File "$src\Umbraco.Web.UI\web.$buildConfiguration.Config.transformed" "$tmp\WebApp\web.config"
|
||||
|
||||
# offset the modified timestamps on all umbraco dlls, as WebResources
|
||||
# break if date is in the future, which, due to timezone offsets can happen.
|
||||
Write-Host "Offset dlls timestamps"
|
||||
ls -r "$tmp\*.dll" | foreach {
|
||||
$_.CreationTime = $_.CreationTime.AddHours(-11)
|
||||
$_.LastWriteTime = $_.LastWriteTime.AddHours(-11)
|
||||
}
|
||||
|
||||
# copy libs
|
||||
Write-Host "Copy SqlCE libraries"
|
||||
Copy-Files "$src\packages\SqlServerCE.4.0.0.1" "*.*" "$tmp\bin" `
|
||||
{ -not $_.Extension.StartsWith(".nu") -and -not $_.RelativeName.StartsWith("lib\") }
|
||||
Copy-Files "$src\packages\SqlServerCE.4.0.0.1" "*.*" "$tmp\WebApp\bin" `
|
||||
{ -not $_.Extension.StartsWith(".nu") -and -not $_.RelativeName.StartsWith("lib\") }
|
||||
|
||||
# copy Belle
|
||||
Write-Host "Copy Belle"
|
||||
Copy-Files "$src\Umbraco.Web.UI\umbraco\assets" "*" "$tmp\WebApp\umbraco\assets"
|
||||
Copy-Files "$src\Umbraco.Web.UI\umbraco\js" "*" "$tmp\WebApp\umbraco\js"
|
||||
Copy-Files "$src\Umbraco.Web.UI\umbraco\lib" "*" "$tmp\WebApp\umbraco\lib"
|
||||
Copy-Files "$src\Umbraco.Web.UI\umbraco\views" "*" "$tmp\WebApp\umbraco\views"
|
||||
Copy-Files "$src\Umbraco.Web.UI\umbraco\preview" "*" "$tmp\WebApp\umbraco\preview"
|
||||
|
||||
# prepare WebPI
|
||||
Write-Host "Prepare WebPI"
|
||||
Remove-Directory "$tmp\WebPi"
|
||||
mkdir "$tmp\WebPi" > $null
|
||||
mkdir "$tmp\WebPi\umbraco" > $null
|
||||
Copy-Files "$tmp\WebApp" "*" "$tmp\WebPi\umbraco"
|
||||
Copy-Files "$src\WebPi" "*" "$tmp\WebPi"
|
||||
}
|
||||
|
||||
#
|
||||
# Creates the Zip packages
|
||||
#
|
||||
function Package-Zip
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
Write-Host ">> Create Zip packages"
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$out = "$($uenv.SolutionRoot)\build.out"
|
||||
|
||||
Write-Host "Zip all binaries"
|
||||
&$uenv.Zip a -r "$out\UmbracoCms.AllBinaries.$($version.Semver).zip" `
|
||||
"$tmp\bin\*" `
|
||||
"-x!dotless.Core.*" `
|
||||
> $null
|
||||
|
||||
Write-Host "Zip cms"
|
||||
&$uenv.Zip a -r "$out\UmbracoCms.$($version.Semver).zip" `
|
||||
"$tmp\WebApp\*" `
|
||||
"-x!dotless.Core.*" "-x!Content_Types.xml" "-x!*.pdb"`
|
||||
> $null
|
||||
|
||||
Write-Host "Zip WebPI"
|
||||
&$uenv.Zip a -r "$out\UmbracoCms.WebPI.$($version.Semver).zip" "-x!*.pdb"`
|
||||
"$tmp\WebPi\*" `
|
||||
"-x!dotless.Core.*" `
|
||||
> $null
|
||||
|
||||
# hash the webpi file
|
||||
Write-Host "Hash WebPI"
|
||||
$hash = Get-FileHash "$out\UmbracoCms.WebPI.$($version.Semver).zip"
|
||||
Write $hash | out-file "$out\webpihash.txt" -encoding ascii
|
||||
}
|
||||
|
||||
#
|
||||
# Prepares NuGet
|
||||
#
|
||||
function Prepare-NuGet
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
Write-Host ">> Prepare NuGet"
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$out = "$($uenv.SolutionRoot)\build.out"
|
||||
|
||||
# add Web.config transform files to the NuGet package
|
||||
Write-Host "Add web.config transforms to NuGet package"
|
||||
mv "$tmp\WebApp\Views\Web.config" "$tmp\WebApp\Views\Web.config.transform"
|
||||
|
||||
# fixme - that one does not exist in .bat build either?
|
||||
#mv "$tmp\WebApp\Xslt\Web.config" "$tmp\WebApp\Xslt\Web.config.transform"
|
||||
}
|
||||
|
||||
#
|
||||
# Restores NuGet
|
||||
#
|
||||
function Restore-NuGet
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
|
||||
Write-Host ">> Restore NuGet"
|
||||
Write-Host "Logging to $tmp\nuget.restore.log"
|
||||
|
||||
&$uenv.NuGet restore "$src\Umbraco.sln" > "$tmp\nuget.restore.log"
|
||||
}
|
||||
|
||||
#
|
||||
# Creates the NuGet packages
|
||||
#
|
||||
function Package-NuGet
|
||||
{
|
||||
param (
|
||||
$uenv, # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
$version # an Umbraco version object (see Get-UmbracoVersion)
|
||||
)
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$tmp = "$($uenv.SolutionRoot)\build.tmp"
|
||||
$out = "$($uenv.SolutionRoot)\build.out"
|
||||
$nuspecs = "$($uenv.SolutionRoot)\build\NuSpecs"
|
||||
|
||||
Write-Host ">> Create NuGet packages"
|
||||
|
||||
# see https://docs.microsoft.com/en-us/nuget/schema/nuspec
|
||||
# note - warnings about SqlCE native libs being outside of 'lib' folder,
|
||||
# nothing much we can do about it as it's intentional yet there does not
|
||||
# seem to be a way to disable the warning
|
||||
|
||||
&$uenv.NuGet Pack "$nuspecs\UmbracoCms.Core.nuspec" `
|
||||
-Properties BuildTmp="$tmp" `
|
||||
-Version $version.Semver.ToString() `
|
||||
-Symbols -Verbosity quiet -outputDirectory $out
|
||||
|
||||
&$uenv.NuGet Pack "$nuspecs\UmbracoCms.nuspec" `
|
||||
-Properties BuildTmp="$tmp" `
|
||||
-Version $version.Semver.ToString() `
|
||||
-Verbosity quiet -outputDirectory $out
|
||||
}
|
||||
|
||||
#
|
||||
# Builds Umbraco
|
||||
#
|
||||
function Build-Umbraco
|
||||
{
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
[string]
|
||||
$target = "all",
|
||||
[string]
|
||||
$buildConfiguration = "Release"
|
||||
)
|
||||
|
||||
$target = $target.ToLowerInvariant()
|
||||
Write-Host ">> Build-Umbraco <$target> <$buildConfiguration>"
|
||||
|
||||
Write-Host "Get Build Environment"
|
||||
$uenv = Get-UmbracoBuildEnv
|
||||
|
||||
Write-Host "Get Version"
|
||||
$version = Get-UmbracoVersion
|
||||
Write-Host "Version $($version.Semver)"
|
||||
|
||||
if ($target -eq "pre-build")
|
||||
{
|
||||
Prepare-Build $uenv
|
||||
#Compile-Belle $uenv $version
|
||||
|
||||
# set environment variables
|
||||
$env:UMBRACO_VERSION=$version.Semver.ToString()
|
||||
$env:UMBRACO_RELEASE=$version.Release
|
||||
$env:UMBRACO_COMMENT=$version.Comment
|
||||
$env:UMBRACO_BUILD=$version.Build
|
||||
|
||||
# set environment variable for VSO
|
||||
# https://github.com/Microsoft/vsts-tasks/issues/375
|
||||
# https://github.com/Microsoft/vsts-tasks/blob/master/docs/authoring/commands.md
|
||||
Write-Host ("##vso[task.setvariable variable=UMBRACO_VERSION;]$($version.Semver.ToString())")
|
||||
Write-Host ("##vso[task.setvariable variable=UMBRACO_RELEASE;]$($version.Release)")
|
||||
Write-Host ("##vso[task.setvariable variable=UMBRACO_COMMENT;]$($version.Comment)")
|
||||
Write-Host ("##vso[task.setvariable variable=UMBRACO_BUILD;]$($version.Build)")
|
||||
|
||||
Write-Host ("##vso[task.setvariable variable=UMBRACO_TMP;]$($uenv.SolutionRoot)\build.tmp")
|
||||
}
|
||||
elseif ($target -eq "pre-tests")
|
||||
{
|
||||
Prepare-Tests $uenv
|
||||
}
|
||||
elseif ($target -eq "compile-tests")
|
||||
{
|
||||
Compile-Tests $uenv
|
||||
}
|
||||
elseif ($target -eq "compile-umbraco")
|
||||
{
|
||||
Compile-Umbraco $uenv $buildConfiguration
|
||||
}
|
||||
elseif ($target -eq "pre-packages")
|
||||
{
|
||||
Prepare-Packages $uenv
|
||||
}
|
||||
elseif ($target -eq "pre-nuget")
|
||||
{
|
||||
Prepare-NuGet $uenv
|
||||
}
|
||||
elseif ($target -eq "restore-nuget")
|
||||
{
|
||||
Restore-NuGet $uenv
|
||||
}
|
||||
elseif ($target -eq "pkg-zip")
|
||||
{
|
||||
Package-Zip $uenv
|
||||
}
|
||||
elseif ($target -eq "compile-belle")
|
||||
{
|
||||
Compile-Belle $uenv $version
|
||||
}
|
||||
elseif ($target -eq "all")
|
||||
{
|
||||
Prepare-Build $uenv
|
||||
Restore-NuGet $uenv
|
||||
Compile-Belle $uenv $version
|
||||
Compile-Umbraco $uenv $buildConfiguration
|
||||
Prepare-Tests $uenv
|
||||
Compile-Tests $uenv
|
||||
# not running tests...
|
||||
Prepare-Packages $uenv
|
||||
Package-Zip $uenv
|
||||
Verify-NuGet $uenv
|
||||
Prepare-NuGet $uenv
|
||||
Package-NuGet $uenv $version
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Error "Unsupported target `"$target`"."
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# export functions
|
||||
#
|
||||
Export-ModuleMember -function Get-UmbracoBuildEnv
|
||||
Export-ModuleMember -function Set-UmbracoVersion
|
||||
Export-ModuleMember -function Set-UmbracoContinuousVersion
|
||||
Export-ModuleMember -function Get-UmbracoVersion
|
||||
Export-ModuleMember -function Build-Umbraco
|
||||
Export-ModuleMember -function Build-UmbracoDocs
|
||||
Export-ModuleMember -function Verify-NuGet
|
||||
|
||||
#eof
|
||||
@@ -1,120 +0,0 @@
|
||||
# returns a string containing the hash of $file
|
||||
function Get-FileHash($file)
|
||||
{
|
||||
try
|
||||
{
|
||||
$crypto = new-object System.Security.Cryptography.SHA1CryptoServiceProvider
|
||||
$stream = [System.IO.File]::OpenRead($file)
|
||||
$hash = $crypto.ComputeHash($stream)
|
||||
$text = ""
|
||||
$hash | foreach `
|
||||
{
|
||||
$text = $text + $_.ToString("x2")
|
||||
}
|
||||
return $text
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($stream)
|
||||
{
|
||||
$stream.Dispose()
|
||||
}
|
||||
$crypto.Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
# returns the full path if $file is relative to $pwd
|
||||
function Get-FullPath($file)
|
||||
{
|
||||
$path = [System.IO.Path]::Combine($pwd, $file)
|
||||
$path = [System.IO.Path]::GetFullPath($path)
|
||||
return $path
|
||||
}
|
||||
|
||||
# removes a directory, doesn't complain if it does not exist
|
||||
function Remove-Directory($dir)
|
||||
{
|
||||
remove-item $dir -force -recurse -errorAction SilentlyContinue > $null
|
||||
}
|
||||
|
||||
# removes a file, doesn't complain if it does not exist
|
||||
function Remove-File($file)
|
||||
{
|
||||
remove-item $file -force -errorAction SilentlyContinue > $null
|
||||
}
|
||||
|
||||
# copies a file, creates target dir if needed
|
||||
function Copy-File($source, $target)
|
||||
{
|
||||
$ignore = new-item -itemType file -path $target -force
|
||||
cp -force $source $target
|
||||
}
|
||||
|
||||
# copies files to a directory
|
||||
function Copy-Files($source, $select, $target, $filter)
|
||||
{
|
||||
$files = ls -r "$source\$select"
|
||||
$files | foreach {
|
||||
$relative = $_.FullName.SubString($source.Length+1)
|
||||
$_ | add-member -memberType NoteProperty -name RelativeName -value $relative
|
||||
}
|
||||
if ($filter -ne $null) {
|
||||
$files = $files | where $filter
|
||||
}
|
||||
$files |
|
||||
foreach {
|
||||
if ($_.PsIsContainer) {
|
||||
$ignore = new-item -itemType directory -path "$target\$($_.RelativeName)" -force
|
||||
}
|
||||
else {
|
||||
Copy-File $_.FullName "$target\$($_.RelativeName)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# regex-replaces content in a file
|
||||
function Replace-FileText($filename, $source, $replacement)
|
||||
{
|
||||
$filepath = Get-FullPath $filename
|
||||
$text = [System.IO.File]::ReadAllText($filepath)
|
||||
$text = [System.Text.RegularExpressions.Regex]::Replace($text, $source, $replacement)
|
||||
$utf8bom = New-Object System.Text.UTF8Encoding $true
|
||||
[System.IO.File]::WriteAllText($filepath, $text, $utf8bom)
|
||||
}
|
||||
|
||||
# store web.config
|
||||
function Store-WebConfig($webUi)
|
||||
{
|
||||
if (test-path "$webUi\web.config")
|
||||
{
|
||||
if (test-path "$webUi\web.config.temp-build")
|
||||
{
|
||||
Write-Host "Found existing web.config.temp-build"
|
||||
$i = 0
|
||||
while (test-path "$webUi\web.config.temp-build.$i")
|
||||
{
|
||||
$i = $i + 1
|
||||
}
|
||||
Write-Host "Save existing web.config as web.config.temp-build.$i"
|
||||
Write-Host "(WARN: the original web.config.temp-build will be restored during post-build)"
|
||||
mv "$webUi\web.config" "$webUi\web.config.temp-build.$i"
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "Save existing web.config as web.config.temp-build"
|
||||
Write-Host "(will be restored during post-build)"
|
||||
mv "$webUi\web.config" "$webUi\web.config.temp-build"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# restore web.config
|
||||
function Restore-WebConfig($webUi)
|
||||
{
|
||||
if (test-path "$webUi\web.config.temp-build")
|
||||
{
|
||||
Write-Host "Restoring existing web.config"
|
||||
Remove-File "$webUi\web.config"
|
||||
mv "$webUi\web.config.temp-build" "$webUi\web.config"
|
||||
}
|
||||
}
|
||||
@@ -1,444 +0,0 @@
|
||||
#
|
||||
# Verify-NuGet
|
||||
#
|
||||
|
||||
function Format-Dependency
|
||||
{
|
||||
param ( $d )
|
||||
|
||||
$m = $d.Id + " "
|
||||
if ($d.MinInclude) { $m = $m + "[" }
|
||||
else { $m = $m + "(" }
|
||||
$m = $m + $d.MinVersion
|
||||
if ($d.MaxVersion -ne $d.MinVersion) { $m = $m + "," + $d.MaxVersion }
|
||||
if ($d.MaxInclude) { $m = $m + "]" }
|
||||
else { $m = $m + ")" }
|
||||
|
||||
return $m
|
||||
}
|
||||
|
||||
function Write-NuSpec
|
||||
{
|
||||
param ( $name, $deps )
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "$name NuSpec dependencies:"
|
||||
|
||||
foreach ($d in $deps)
|
||||
{
|
||||
$m = Format-Dependency $d
|
||||
Write-Host " $m"
|
||||
}
|
||||
}
|
||||
|
||||
function Write-Package
|
||||
{
|
||||
param ( $name, $pkgs )
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "$name packages:"
|
||||
|
||||
foreach ($p in $pkgs)
|
||||
{
|
||||
Write-Host " $($p.Id) $($p.Version)"
|
||||
}
|
||||
}
|
||||
|
||||
function Verify-NuGet
|
||||
{
|
||||
param (
|
||||
$uenv # an Umbraco build environment (see Get-UmbracoBuildEnv)
|
||||
)
|
||||
|
||||
if ($uenv -eq $null)
|
||||
{
|
||||
$uenv = Get-UmbracoBuildEnv
|
||||
}
|
||||
|
||||
$source = @"
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using Semver;
|
||||
|
||||
namespace Umbraco.Build
|
||||
{
|
||||
public class NuGet
|
||||
{
|
||||
public static Dependency[] GetNuSpecDependencies(string filename)
|
||||
{
|
||||
NuSpec nuspec;
|
||||
var serializer = new XmlSerializer(typeof(NuSpec));
|
||||
using (var reader = new StreamReader(filename))
|
||||
{
|
||||
nuspec = (NuSpec) serializer.Deserialize(reader);
|
||||
}
|
||||
var nudeps = nuspec.Metadata.Dependencies;
|
||||
var deps = new List<Dependency>();
|
||||
foreach (var nudep in nudeps)
|
||||
{
|
||||
var dep = new Dependency();
|
||||
dep.Id = nudep.Id;
|
||||
|
||||
var parts = nudep.Version.Split(',');
|
||||
if (parts.Length == 1)
|
||||
{
|
||||
dep.MinInclude = parts[0].StartsWith("[");
|
||||
dep.MaxInclude = parts[0].EndsWith("]");
|
||||
|
||||
SemVersion version;
|
||||
if (!SemVersion.TryParse(parts[0].Substring(1, parts[0].Length-2).Trim(), out version)) continue;
|
||||
dep.MinVersion = dep.MaxVersion = version; //parts[0].Substring(1, parts[0].Length-2).Trim();
|
||||
}
|
||||
else
|
||||
{
|
||||
SemVersion version;
|
||||
if (!SemVersion.TryParse(parts[0].Substring(1).Trim(), out version)) continue;
|
||||
dep.MinVersion = version; //parts[0].Substring(1).Trim();
|
||||
if (!SemVersion.TryParse(parts[1].Substring(0, parts[1].Length-1).Trim(), out version)) continue;
|
||||
dep.MaxVersion = version; //parts[1].Substring(0, parts[1].Length-1).Trim();
|
||||
dep.MinInclude = parts[0].StartsWith("[");
|
||||
dep.MaxInclude = parts[1].EndsWith("]");
|
||||
}
|
||||
|
||||
deps.Add(dep);
|
||||
}
|
||||
return deps.ToArray();
|
||||
}
|
||||
|
||||
public static IEnumerable<TSource> DistinctBy<TSource, TKey>(/*this*/ IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
|
||||
{
|
||||
HashSet<TKey> knownKeys = new HashSet<TKey>();
|
||||
foreach (TSource element in source)
|
||||
{
|
||||
if (knownKeys.Add(keySelector(element)))
|
||||
{
|
||||
yield return element;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Package[] GetProjectsPackages(string src, string[] projects)
|
||||
{
|
||||
var l = new List<Package>();
|
||||
foreach (var project in projects)
|
||||
{
|
||||
var path = Path.Combine(src, project);
|
||||
var packageConfig = Path.Combine(path, "packages.config");
|
||||
if (File.Exists(packageConfig))
|
||||
ReadPackagesConfig(packageConfig, l);
|
||||
var csprojs = Directory.GetFiles(path, "*.csproj");
|
||||
foreach (var csproj in csprojs)
|
||||
{
|
||||
ReadCsProj(csproj, l);
|
||||
}
|
||||
}
|
||||
IEnumerable<Package> p = l.OrderBy(x => x.Id);
|
||||
p = DistinctBy(p, x => x.Id + ":::" + x.Version);
|
||||
return p.ToArray();
|
||||
}
|
||||
|
||||
public static object[] GetPackageErrors(Package[] pkgs)
|
||||
{
|
||||
return pkgs
|
||||
.GroupBy(x => x.Id)
|
||||
.Where(x => x.Count() > 1)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public static object[] GetNuSpecErrors(Package[] pkgs, Dependency[] deps)
|
||||
{
|
||||
var d = pkgs.ToDictionary(x => x.Id, x => x.Version);
|
||||
return deps
|
||||
.Select(x =>
|
||||
{
|
||||
SemVersion v;
|
||||
if (!d.TryGetValue(x.Id, out v)) return null;
|
||||
|
||||
var ok = true;
|
||||
|
||||
/*
|
||||
if (x.MinInclude)
|
||||
{
|
||||
if (v < x.MinVersion) ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v <= x.MinVersion) ok = false;
|
||||
}
|
||||
|
||||
if (x.MaxInclude)
|
||||
{
|
||||
if (v > x.MaxVersion) ok = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v >= x.MaxVersion) ok = false;
|
||||
}
|
||||
*/
|
||||
|
||||
if (!x.MinInclude || v != x.MinVersion) ok = false;
|
||||
|
||||
return ok ? null : new { Dependency = x, Version = v };
|
||||
})
|
||||
.Where(x => x != null)
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
/*
|
||||
public static Package[] GetProjectPackages(string path)
|
||||
{
|
||||
var l = new List<Package>();
|
||||
var packageConfig = Path.Combine(path, "packages.config");
|
||||
if (File.Exists(packageConfig))
|
||||
ReadPackagesConfig(packageConfig, l);
|
||||
var csprojs = Directory.GetFiles(path, "*.csproj");
|
||||
foreach (var csproj in csprojs)
|
||||
{
|
||||
ReadCsProj(csproj, l);
|
||||
}
|
||||
return l.ToArray();
|
||||
}
|
||||
*/
|
||||
|
||||
public static string GetDirectoryName(string filename)
|
||||
{
|
||||
return Path.GetFileName(Path.GetDirectoryName(filename));
|
||||
}
|
||||
|
||||
public static void ReadPackagesConfig(string filename, List<Package> packages)
|
||||
{
|
||||
//Console.WriteLine("read " + filename);
|
||||
|
||||
PackagesConfigPackages pkgs;
|
||||
var serializer = new XmlSerializer(typeof(PackagesConfigPackages));
|
||||
using (var reader = new StreamReader(filename))
|
||||
{
|
||||
pkgs = (PackagesConfigPackages) serializer.Deserialize(reader);
|
||||
}
|
||||
foreach (var p in pkgs.Packages)
|
||||
{
|
||||
SemVersion version;
|
||||
if (!SemVersion.TryParse(p.Version, out version)) continue;
|
||||
packages.Add(new Package { Id = p.Id, Version = version, Project = GetDirectoryName(filename) });
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReadCsProj(string filename, List<Package> packages)
|
||||
{
|
||||
//Console.WriteLine("read " + filename);
|
||||
|
||||
// if xmlns then it's not a VS2017 with PackageReference
|
||||
var text = File.ReadAllLines(filename);
|
||||
var line = text.FirstOrDefault(x => x.Contains("<Project"));
|
||||
if (line == null) return;
|
||||
if (line.Contains("xmlns")) return;
|
||||
|
||||
CsProjProject proj;
|
||||
var serializer = new XmlSerializer(typeof(CsProjProject));
|
||||
using (var reader = new StreamReader(filename))
|
||||
{
|
||||
proj = (CsProjProject) serializer.Deserialize(reader);
|
||||
}
|
||||
foreach (var p in proj.ItemGroups.Where(x => x.Packages != null).SelectMany(x => x.Packages))
|
||||
{
|
||||
var sversion = p.VersionE ?? p.VersionA;
|
||||
SemVersion version;
|
||||
if (!SemVersion.TryParse(sversion, out version)) continue;
|
||||
packages.Add(new Package { Id = p.Id, Version = version, Project = GetDirectoryName(filename) });
|
||||
}
|
||||
}
|
||||
|
||||
public class Dependency
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public SemVersion MinVersion { get; set; }
|
||||
public SemVersion MaxVersion { get; set; }
|
||||
public bool MinInclude { get; set; }
|
||||
public bool MaxInclude { get; set; }
|
||||
}
|
||||
|
||||
public class Package
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public SemVersion Version { get; set; }
|
||||
public string Project { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true, Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd")]
|
||||
[XmlRoot(Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd", IsNullable = false, ElementName = "package")]
|
||||
public class NuSpec
|
||||
{
|
||||
[XmlElement("metadata")]
|
||||
public NuSpecMetadata Metadata { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true, Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd", TypeName = "metadata")]
|
||||
public class NuSpecMetadata
|
||||
{
|
||||
[XmlArray("dependencies")]
|
||||
[XmlArrayItem("dependency", IsNullable = false)]
|
||||
public NuSpecDependency[] Dependencies { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true, Namespace = "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd", TypeName = "dependencies")]
|
||||
public class NuSpecDependency
|
||||
{
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "version")]
|
||||
public string Version { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true)]
|
||||
[XmlRoot(Namespace = "", IsNullable = false, ElementName = "packages")]
|
||||
public class PackagesConfigPackages
|
||||
{
|
||||
[XmlElement("package")]
|
||||
public PackagesConfigPackage[] Packages { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true, TypeName = "package")]
|
||||
public class PackagesConfigPackage
|
||||
{
|
||||
[XmlAttribute(AttributeName = "id")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "version")]
|
||||
public string Version { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true)]
|
||||
[XmlRoot(Namespace = "", IsNullable = false, ElementName = "Project")]
|
||||
public class CsProjProject
|
||||
{
|
||||
[XmlElement("ItemGroup")]
|
||||
public CsProjItemGroup[] ItemGroups { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true, TypeName = "ItemGroup")]
|
||||
public class CsProjItemGroup
|
||||
{
|
||||
[XmlElement("PackageReference")]
|
||||
public CsProjPackageReference[] Packages { get; set; }
|
||||
}
|
||||
|
||||
[XmlType(AnonymousType = true, TypeName = "PackageReference")]
|
||||
public class CsProjPackageReference
|
||||
{
|
||||
[XmlAttribute(AttributeName = "Include")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[XmlAttribute(AttributeName = "Version")]
|
||||
public string VersionA { get; set; }
|
||||
|
||||
[XmlElement("Version")]
|
||||
public string VersionE { get; set;}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"@
|
||||
|
||||
Write-Host ">> Verify NuGet consistency"
|
||||
|
||||
$assem = (
|
||||
"System.Xml",
|
||||
"System.Core", # "System.Collections.Generic"
|
||||
"System.Linq",
|
||||
"System.Xml.Serialization",
|
||||
"System.IO",
|
||||
"System.Globalization",
|
||||
$uenv.Semver
|
||||
)
|
||||
|
||||
try
|
||||
{
|
||||
# as long as the code hasn't changed it's fine to re-add, but if the code
|
||||
# has changed this will throw - better warn the dev that we have an issue
|
||||
add-type -referencedAssemblies $assem -typeDefinition $source -language CSharp
|
||||
}
|
||||
catch
|
||||
{
|
||||
if ($_.FullyQualifiedErrorId.StartsWith("TYPE_ALREADY_EXISTS,"))
|
||||
{ Write-Error "Failed to add type, did you change the code?" }
|
||||
else
|
||||
{ Write-Error $_ }
|
||||
}
|
||||
if (-not $?) { break }
|
||||
|
||||
$nuspecs = (
|
||||
"UmbracoCms",
|
||||
"UmbracoCms.Core"
|
||||
)
|
||||
|
||||
$projects = (
|
||||
"Umbraco.Core",
|
||||
"Umbraco.Web",
|
||||
"Umbraco.Web.UI",
|
||||
"UmbracoExamine"#,
|
||||
#"Umbraco.Tests",
|
||||
#"Umbraco.Tests.Benchmarks"
|
||||
)
|
||||
|
||||
$src = "$($uenv.SolutionRoot)\src"
|
||||
$pkgs = [Umbraco.Build.NuGet]::GetProjectsPackages($src, $projects)
|
||||
if (-not $?) { break }
|
||||
#Write-Package "All" $pkgs
|
||||
|
||||
$errs = [Umbraco.Build.NuGet]::GetPackageErrors($pkgs)
|
||||
if (-not $?) { break }
|
||||
|
||||
if ($errs.Length -gt 0)
|
||||
{
|
||||
Write-Host ""
|
||||
}
|
||||
foreach ($err in $errs)
|
||||
{
|
||||
Write-Host $err.Key
|
||||
foreach ($e in $err)
|
||||
{
|
||||
Write-Host " $($e.Version) required by $($e.Project)"
|
||||
}
|
||||
}
|
||||
if ($errs.Length -gt 0)
|
||||
{
|
||||
Write-Error "Found non-consolidated package dependencies"
|
||||
break
|
||||
}
|
||||
|
||||
$nuerr = $false
|
||||
$nupath = "$($uenv.SolutionRoot)\build\NuSpecs"
|
||||
foreach ($nuspec in $nuspecs)
|
||||
{
|
||||
$deps = [Umbraco.Build.NuGet]::GetNuSpecDependencies("$nupath\$nuspec.nuspec")
|
||||
if (-not $?) { break }
|
||||
#Write-NuSpec $nuspec $deps
|
||||
|
||||
$errs = [Umbraco.Build.NuGet]::GetNuSpecErrors($pkgs, $deps)
|
||||
if (-not $?) { break }
|
||||
|
||||
if ($errs.Length -gt 0)
|
||||
{
|
||||
Write-Host ""
|
||||
Write-Host "$nuspec requires:"
|
||||
$nuerr = $true
|
||||
}
|
||||
foreach ($err in $errs)
|
||||
{
|
||||
$m = Format-Dependency $err.Dependency
|
||||
Write-Host " $m but projects require $($err.Version)"
|
||||
}
|
||||
}
|
||||
|
||||
if ($nuerr)
|
||||
{
|
||||
Write-Error "Found inconsistent NuGet dependencies"
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata>
|
||||
<id>UmbracoCms.Core</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms Core Binaries</title>
|
||||
@@ -14,95 +14,93 @@
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="log4net" version="[2.0.8,3.0.0)" />
|
||||
<dependency id="Log4Net.Async" version="[2.0.4,3.0.0)" />
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[5.2.3,6.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="[5.2.3,6.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.Identity.Owin" version="[2.2.1, 3.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.1, 3.0.0)" />
|
||||
<dependency id="Microsoft.Owin.Security.Cookies" version="[3.0.1, 4.0.0)" />
|
||||
<dependency id="Microsoft.Owin.Security.OAuth" version="[3.0.1, 4.0.0)" />
|
||||
<dependency id="Microsoft.Owin.Host.SystemWeb" version="[3.0.1, 4.0.0)" />
|
||||
<dependency id="MiniProfiler" version="[2.1.0, 3.0.0)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.4.9.5, 2.0.0)" />
|
||||
<dependency id="HtmlAgilityPack" version="[1.4.9, 2.0.0)" />
|
||||
<dependency id="Lucene.Net" version="[2.9.4.1, 3.0.0.0)" />
|
||||
<dependency id="SharpZipLib" version="[0.86.0, 1.0.0)" />
|
||||
<dependency id="MySql.Data" version="[6.9.9, 7.0.0)" />
|
||||
<dependency id="MySql.Data" version="[6.9.8, 7.0.0)" />
|
||||
<dependency id="xmlrpcnet" version="[2.5.0, 3.0.0)" />
|
||||
<dependency id="ClientDependency" version="[1.9.2, 2.0.0)" />
|
||||
<dependency id="ClientDependency-Mvc5" version="[1.8.0.0, 2.0.0)" />
|
||||
<dependency id="ClientDependency-Mvc5" version="[1.8.0, 2.0.0)" />
|
||||
<!-- AutoMapper can not be updated due to: https://github.com/AutoMapper/AutoMapper/issues/373#issuecomment-127644405 -->
|
||||
<dependency id="AutoMapper" version="[3.3.1, 4.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
|
||||
<dependency id="Examine" version="[0.1.88, 1.0.0)" />
|
||||
<dependency id="ImageProcessor" version="[2.5.6, 3.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.8.7, 5.0.0)" />
|
||||
<dependency id="semver" version="[1.1.2, 3.0.0)" />
|
||||
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
|
||||
<dependency id="Markdown" version="[1.14.7, 2.0.0)" />
|
||||
<dependency id="System.Threading.Tasks.Dataflow" version="[4.7.0, 5.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
|
||||
<dependency id="Examine" version="[0.1.70, 1.0.0)" />
|
||||
<dependency id="ImageProcessor" version="[2.5.1, 3.0.0)" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.7.2, 5.0.0)" />
|
||||
<dependency id="semver" version="[1.1.2, 2.0.0)" />
|
||||
<dependency id="UrlRewritingNet" version="[2.0.7, 3.0.0)" />
|
||||
<!-- Markdown can not be updated due to: https://github.com/hey-red/markdownsharp/issues/71#issuecomment-233585487 -->
|
||||
<dependency id="Markdown" version="[1.14.4, 2.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="$BuildTmp$\WebApp\bin\businesslogic.dll" target="lib\net45\businesslogic.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\businesslogic.xml" target="lib\net45\businesslogic.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\cms.dll" target="lib\net45\cms.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\cms.xml" target="lib\net45\cms.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\controls.dll" target="lib\net45\controls.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\controls.xml" target="lib\net45\controls.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\interfaces.dll" target="lib\net45\interfaces.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\interfaces.xml" target="lib\net45\interfaces.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\log4net.dll" target="lib\net45\log4net.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\net45\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\SQLCE4Umbraco.dll" target="lib\net45\SQLCE4Umbraco.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\SQLCE4Umbraco.xml" target="lib\net45\SQLCE4Umbraco.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\net45\System.Data.SqlServerCe.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\net45\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\TidyNet.dll" target="lib\net45\TidyNet.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.dll" target="lib\net45\Umbraco.Core.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.xml" target="lib\net45\Umbraco.Core.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.DataLayer.dll" target="lib\net45\umbraco.DataLayer.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.DataLayer.xml" target="lib\net45\umbraco.DataLayer.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.dll" target="lib\net45\umbraco.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.xml" target="lib\net45\umbraco.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.editorControls.dll" target="lib\net45\umbraco.editorControls.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.editorControls.xml" target="lib\net45\umbraco.editorControls.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.MacroEngines.dll" target="lib\net45\umbraco.MacroEngines.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.MacroEngines.xml" target="lib\net45\umbraco.MacroEngines.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.providers.dll" target="lib\net45\umbraco.providers.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\umbraco.providers.xml" target="lib\net45\umbraco.providers.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.dll" target="lib\net45\Umbraco.Web.UI.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.xml" target="lib\net45\Umbraco.Web.UI.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\UmbracoExamine.dll" target="lib\net45\UmbracoExamine.dll" />
|
||||
<file src="$BuildTmp$\WebApp\bin\UmbracoExamine.xml" target="lib\net45\UmbracoExamine.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.dll" target="lib\businesslogic.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\businesslogic.xml" target="lib\businesslogic.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.dll" target="lib\cms.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\cms.xml" target="lib\cms.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.dll" target="lib\controls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\controls.xml" target="lib\controls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.dll" target="lib\interfaces.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\interfaces.xml" target="lib\interfaces.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\log4net.dll" target="lib\log4net.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Microsoft.ApplicationBlocks.Data.dll" target="lib\Microsoft.ApplicationBlocks.Data.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.dll" target="lib\SQLCE4Umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\SQLCE4Umbraco.xml" target="lib\SQLCE4Umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.dll" target="lib\System.Data.SqlServerCe.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\System.Data.SqlServerCe.Entity.dll" target="lib\System.Data.SqlServerCe.Entity.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\TidyNet.dll" target="lib\TidyNet.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.dll" target="lib\Umbraco.Core.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.dll" target="lib\umbraco.DataLayer.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.DataLayer.xml" target="lib\umbraco.DataLayer.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.dll" target="lib\umbraco.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.xml" target="lib\umbraco.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.dll" target="lib\umbraco.editorControls.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.editorControls.xml" target="lib\umbraco.editorControls.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.dll" target="lib\umbraco.MacroEngines.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.MacroEngines.xml" target="lib\umbraco.MacroEngines.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.dll" target="lib\umbraco.providers.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\umbraco.providers.xml" target="lib\umbraco.providers.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.dll" target="lib\Umbraco.Web.UI.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.dll" target="lib\UmbracoExamine.dll" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\UmbracoExamine.xml" target="lib\UmbracoExamine.xml" />
|
||||
<file src="tools\install.core.ps1" target="tools\install.ps1" />
|
||||
|
||||
<!-- Added to be able to produce a symbols package -->
|
||||
<file src="$BuildTmp$\bin\SQLCE4Umbraco.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\SQLCE4Umbraco.pdb" target="lib" />
|
||||
<file src="..\..\src\SQLCE4Umbraco\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\SQLCE4Umbraco" />
|
||||
<file src="$BuildTmp$\bin\businesslogic.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\businesslogic.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.businesslogic\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.businesslogic" />
|
||||
<file src="$BuildTmp$\bin\cms.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\cms.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.cms\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.cms" />
|
||||
<file src="$BuildTmp$\bin\controls.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\controls.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.controls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.controls" />
|
||||
<file src="$BuildTmp$\bin\interfaces.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\interfaces.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.interfaces\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.interfaces" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Core.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\Umbraco.Core.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Core\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Core" />
|
||||
<file src="$BuildTmp$\bin\umbraco.DataLayer.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.DataLayer.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.datalayer\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.datalayer" />
|
||||
<file src="$BuildTmp$\bin\umbraco.editorControls.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.editorControls.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.editorControls\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.editorControls" />
|
||||
<file src="$BuildTmp$\bin\umbraco.MacroEngines.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.MacroEngines.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.MacroEngines\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.MacroEngines" />
|
||||
<file src="$BuildTmp$\bin\umbraco.providers.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.providers.pdb" target="lib" />
|
||||
<file src="..\..\src\umbraco.providers\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\umbraco.providers" />
|
||||
<file src="$BuildTmp$\bin\umbraco.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\umbraco.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Web\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Web.UI.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\Umbraco.Web.UI.pdb" target="lib" />
|
||||
<file src="..\..\src\Umbraco.Web.UI\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\Umbraco.Web.UI" />
|
||||
<file src="$BuildTmp$\bin\UmbracoExamine.pdb" target="lib" />
|
||||
<file src="..\_BuildOutput\bin\UmbracoExamine.pdb" target="lib" />
|
||||
<file src="..\..\src\UmbracoExamine\**\*.cs" exclude="..\..\src\**\TemporaryGeneratedFile*.cs" target="src\UmbracoExamine" />
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata minClientVersion="3.4.4">
|
||||
<metadata minClientVersion="2.8">
|
||||
<id>UmbracoCms</id>
|
||||
<version>7.0.0</version>
|
||||
<title>Umbraco Cms</title>
|
||||
@@ -16,25 +16,24 @@
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="UmbracoCms.Core" version="[$version$]" />
|
||||
<dependency id="Newtonsoft.Json" version="[10.0.2, 11.0.0)" />
|
||||
<dependency id="Umbraco.ModelsBuilder" version="[3.0.7, 4.0.0)" />
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.2.1, 3.0.0)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.3.1, 3.0.0)" />
|
||||
<dependency id="Newtonsoft.Json" version="[6.0.8, 10.0.0)" />
|
||||
<dependency id="Umbraco.ModelsBuilder" version="[3.0.5, 4.0.0)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.3.0, 3.0.0)" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
<file src="$BuildTmp$\Configs\**" target="Content\Config" exclude="$BuildTmp$\Configs\Web.config.transform" />
|
||||
<file src="$BuildTmp$\WebApp\Views\**" target="Content\Views" exclude="$BuildTmp$\WebApp\Views\Web.config" />
|
||||
<file src="$BuildTmp$\WebApp\default.aspx" target="Content\default.aspx" />
|
||||
<file src="$BuildTmp$\WebApp\Global.asax" target="Content\Global.asax" />
|
||||
<file src="$BuildTmp$\WebApp\Web.config" target="UmbracoFiles\Web.config" />
|
||||
<file src="$BuildTmp$\WebApp\App_Browsers\**" target="UmbracoFiles\App_Browsers" />
|
||||
<file src="$BuildTmp$\WebApp\bin\amd64\**" target="UmbracoFiles\bin\amd64" />
|
||||
<file src="$BuildTmp$\WebApp\bin\x86\**" target="UmbracoFiles\bin\x86" />
|
||||
<file src="$BuildTmp$\WebApp\config\splashes\**" target="UmbracoFiles\Config\splashes" />
|
||||
<file src="$BuildTmp$\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="$BuildTmp$\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="$BuildTmp$\WebApp\Media\Web.config" target="Content\Media\Web.config" />
|
||||
<file src="..\_BuildOutput\Configs\**" target="Content\Config" exclude="..\_BuildOutput\Configs\Web.config.transform" />
|
||||
<file src="..\_BuildOutput\WebApp\Views\**" target="Content\Views" exclude="..\_BuildOutput\WebApp\Views\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\default.aspx" target="Content\default.aspx" />
|
||||
<file src="..\_BuildOutput\WebApp\Global.asax" target="Content\Global.asax" />
|
||||
<file src="..\_BuildOutput\WebApp\Web.config" target="UmbracoFiles\Web.config" />
|
||||
<file src="..\_BuildOutput\WebApp\App_Browsers\**" target="UmbracoFiles\App_Browsers" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\amd64\**" target="UmbracoFiles\bin\amd64" />
|
||||
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="UmbracoFiles\bin\x86" />
|
||||
<file src="..\_BuildOutput\WebApp\config\splashes\**" target="UmbracoFiles\Config\splashes" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco\**" target="UmbracoFiles\umbraco" />
|
||||
<file src="..\_BuildOutput\WebApp\umbraco_client\**" target="UmbracoFiles\umbraco_client" />
|
||||
<file src="..\_BuildOutput\WebApp\Media\Web.config" target="Content\Media\Web.config" />
|
||||
<file src="tools\install.ps1" target="tools\install.ps1" />
|
||||
<file src="tools\Readme.txt" target="tools\Readme.txt" />
|
||||
<file src="tools\ReadmeUpgrade.txt" target="tools\ReadmeUpgrade.txt" />
|
||||
@@ -46,7 +45,6 @@
|
||||
<file src="tools\umbracoSettings.config.install.xdt" target="Content\config\umbracoSettings.config.install.xdt" />
|
||||
<file src="tools\Views.Web.config.install.xdt" target="Views\Web.config.install.xdt" />
|
||||
<file src="tools\processing.config.install.xdt" target="Content\Config\imageprocessor\processing.config.install.xdt" />
|
||||
<file src="tools\cache.config.install.xdt" target="Content\Config\imageprocessor\cache.config.install.xdt" />
|
||||
<file src="build\**" target="build" />
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -41,6 +41,16 @@
|
||||
views/dashboard/developer/examinemanagement.html
|
||||
</control>
|
||||
</tab>
|
||||
<tab caption="Health Check" xdt:Transform="InsertIfMissing" xdt:Locator="Match(caption)">
|
||||
<control>
|
||||
views/dashboard/developer/healthcheck.html
|
||||
</control>
|
||||
</tab>
|
||||
<tab caption="Redirect URL Management" xdt:Transform="InsertIfMissing" xdt:Locator="Match(caption)">
|
||||
<control>
|
||||
views/dashboard/developer/redirecturls.html
|
||||
</control>
|
||||
</tab>
|
||||
</section>
|
||||
|
||||
<section alias="StartupMediaDashboardSection" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
|
||||
@@ -70,26 +80,4 @@
|
||||
<tab caption="Change Password" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
|
||||
<tab caption="Last Edits" xdt:Locator="Match(caption)" xdt:Transform="Remove" />
|
||||
</section>
|
||||
|
||||
<section alias="RedirectUrlManagement" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
|
||||
<areas>
|
||||
<area>content</area>
|
||||
</areas>
|
||||
<tab caption="Redirect URL Management">
|
||||
<control>
|
||||
views/dashboard/developer/redirecturls.html
|
||||
</control>
|
||||
</tab>
|
||||
</section>
|
||||
|
||||
<section alias="UmbracoHealthCheck" xdt:Locator="Match(alias)" xdt:Transform="InsertIfMissing">
|
||||
<areas>
|
||||
<area>developer</area>
|
||||
</areas>
|
||||
<tab caption="Health Check">
|
||||
<control>
|
||||
views/dashboard/developer/healthcheck.html
|
||||
</control>
|
||||
</tab>
|
||||
</section>
|
||||
</dashBoard>
|
||||
@@ -8,17 +8,9 @@
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
*** IMPORTANT NOTICE FOR 7.6 UPGRADES ***
|
||||
|
||||
Be sure to read the version specific upgrade information before proceeding:
|
||||
https://our.umbraco.org/documentation/Getting-Started/Setup/Upgrading/version-specific#version-7-6-0
|
||||
|
||||
You will most likely need to make some changes to your web.config and you will need to be
|
||||
aware of the breaking changes listed there to see if these affect your installation.
|
||||
|
||||
|
||||
Don't forget to build!
|
||||
|
||||
|
||||
We've done our best to transform your configuration files but in case something is not quite right: remember we
|
||||
backed up your files in App_Data\NuGetBackup so you can find the original files before they were transformed.
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
<httpRuntime xdt:Transform="InsertIfMissing" />
|
||||
<httpRuntime maxRequestLength="51200" fcnMode="Single" xdt:Transform="SetAttributes(fcnMode,maxRequestLength)" />
|
||||
<httpRuntime targetFramework="4.5" xdt:Locator="Condition(count(@targetFramework) != 1)" xdt:Transform="SetAttributes(targetFramework)" />
|
||||
|
||||
|
||||
<membership defaultProvider="DefaultMembershipProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove" />
|
||||
<roleManager defaultProvider="DefaultRoleProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>
|
||||
<profile defaultProvider="DefaultProfileProvider" xdt:Locator="Match(defaultProvider)" xdt:Transform="Remove"/>>
|
||||
@@ -330,9 +330,6 @@
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.Owin.Security')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.Owin.Security.Cookies')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Net.Http.Formatting')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='Microsoft.CodeAnalysis.CSharp')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='log4net')" xdt:Transform="Remove" />
|
||||
<dependentAssembly xdt:Locator="Condition(./_defaultNamespace:assemblyIdentity/@name='System.Data.SqlServerCe')" xdt:Transform="Remove" />
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
@@ -340,7 +337,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="HtmlAgilityPack" publicKeyToken="bd319b19eaf3b43a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.4.9.5" newVersion="1.4.9.5" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.4.9.0" newVersion="1.4.9.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
|
||||
@@ -352,7 +349,7 @@
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
@@ -386,14 +383,6 @@
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0"/>
|
||||
</dependentAssembly>
|
||||
<dependentAssembly xdt:Transform="Insert">
|
||||
<assemblyIdentity name="System.Data.SqlServerCe" publicKeyToken="89845DCD8080CC91" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.1" newVersion="4.0.0.1"/>
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<caching xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
|
||||
<caches>
|
||||
<cache name="DiskCache" trimCache="false" xdt:Transform="SetAttributes(trimCache)" xdt:Locator="Match(name)" />
|
||||
</caches>
|
||||
</caching>
|
||||
@@ -53,6 +53,7 @@ if ($project) {
|
||||
if(Test-Path $umbracoBinFolder\umbraco.providers.dll) { Remove-Item $umbracoBinFolder\umbraco.providers.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\Umbraco.Web.UI.dll) { Remove-Item $umbracoBinFolder\Umbraco.Web.UI.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\UmbracoExamine.dll) { Remove-Item $umbracoBinFolder\UmbracoExamine.dll -Force -Confirm:$false }
|
||||
if(Test-Path $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll) { Remove-Item $umbracoBinFolder\UrlRewritingNet.UrlRewriter.dll -Force -Confirm:$false }
|
||||
|
||||
# Delete files Umbraco depends upon
|
||||
$amd64Folder = Join-Path $umbracoBinFolder "amd64"
|
||||
|
||||
@@ -34,16 +34,11 @@
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="templates" title="Templates" type="Umbraco.Web.Trees.TemplatesTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder-open" sortOrder="1"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
|
||||
<add application="settings" alias="partialViews" type="Umbraco.Web.Trees.PartialViewsTree, umbraco"
|
||||
xdt:Locator="Match(application,alias,type)"
|
||||
xdt:Transform="Remove()" />
|
||||
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTreeController, umbraco" sortOrder="2"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
|
||||
<add application="settings" alias="scripts" title="Scripts" type="Umbraco.Web.Trees.ScriptTreeController, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="partialViews" title="Partial Views" silent="false" initialize="true" iconClosed="icon-folder" iconOpen="icon-folder" type="Umbraco.Web.Trees.PartialViewsTree, umbraco" sortOrder="2"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="scripts" title="Scripts" type="umbraco.loadScripts, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="4"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="settings" alias="dictionary" title="Dictionary" type="umbraco.loadDictionary, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="6"
|
||||
@@ -89,14 +84,9 @@
|
||||
<add application="developer" alias="xslt" title="XSLT Files" type="umbraco.loadXslt, umbraco" iconClosed="icon-folder" iconOpen="icon-folder" sortOrder="5"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
|
||||
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco"
|
||||
xdt:Locator="Match(application,alias,type)"
|
||||
xdt:Transform="Remove()" />
|
||||
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTreeController, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="InsertIfMissing" />
|
||||
|
||||
<add application="developer" alias="partialViewMacros" type="Umbraco.Web.Trees.PartialViewMacrosTree, umbraco" silent="false" initialize="true" sortOrder="6" title="Partial View Macro Files" iconClosed="icon-folder" iconOpen="icon-folder"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="SetAttributes()" />
|
||||
<add application="developer" alias="python"
|
||||
xdt:Locator="Match(application,alias)"
|
||||
xdt:Transform="Remove" />
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
# Usage: on line 2 put the release version, on line 3 put the version comment (example: beta)
|
||||
7.5.7
|
||||
@@ -1,67 +0,0 @@
|
||||
param (
|
||||
[Parameter(Mandatory=$false)]
|
||||
[string]
|
||||
$version,
|
||||
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("mo")]
|
||||
[switch]
|
||||
$moduleOnly = $false
|
||||
)
|
||||
|
||||
# the script can run either from the solution root,
|
||||
# or from the ./build directory - anything else fails
|
||||
if ([System.IO.Path]::GetFileName($pwd) -eq "build")
|
||||
{
|
||||
$mpath = [System.IO.Path]::GetDirectoryName($pwd) + "\build\Modules\"
|
||||
}
|
||||
else
|
||||
{
|
||||
$mpath = "$pwd\build\Modules\"
|
||||
}
|
||||
|
||||
# look for the module and throw if not found
|
||||
if (-not [System.IO.Directory]::Exists($mpath + "Umbraco.Build"))
|
||||
{
|
||||
Write-Error "Could not locate Umbraco build Powershell module."
|
||||
break
|
||||
}
|
||||
|
||||
# add the module path (if not already there)
|
||||
if (-not $env:PSModulePath.Contains($mpath))
|
||||
{
|
||||
$env:PSModulePath = "$mpath;$env:PSModulePath"
|
||||
}
|
||||
|
||||
# force-import (or re-import) the module
|
||||
Write-Host "Import Umbraco build Powershell module"
|
||||
Import-Module Umbraco.Build -Force -DisableNameChecking
|
||||
|
||||
# module only?
|
||||
if ($moduleOnly)
|
||||
{
|
||||
if (-not [string]::IsNullOrWhiteSpace($version))
|
||||
{
|
||||
Write-Host "(module only: ignoring version parameter)"
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host "(module only)"
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
# get build environment
|
||||
Write-Host "Setup Umbraco build Environment"
|
||||
$uenv = Get-UmbracoBuildEnv
|
||||
|
||||
# set the version if any
|
||||
if (-not [string]::IsNullOrWhiteSpace($version))
|
||||
{
|
||||
Write-Host "Set Umbraco version to $version"
|
||||
Set-UmbracoVersion $version
|
||||
}
|
||||
|
||||
# full umbraco build
|
||||
Write-Host "Build Umbraco"
|
||||
Build-Umbraco
|
||||
@@ -1,18 +0,0 @@
|
||||
# Usage: powershell .\setversion.ps1 7.6.8
|
||||
# Or: powershell .\setversion 7.6.8-beta001
|
||||
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$version
|
||||
)
|
||||
|
||||
# report
|
||||
Write-Host "Setting Umbraco version to $version"
|
||||
|
||||
# import Umbraco Build PowerShell module - $pwd is ./build
|
||||
$env:PSModulePath = "$pwd\Modules\;$env:PSModulePath"
|
||||
Import-Module Umbraco.Build -Force -DisableNameChecking
|
||||
|
||||
# run commands
|
||||
$version = Set-UmbracoVersion -Version $version
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<solution>
|
||||
<add key="disableSourceControlIntegration" value="true" />
|
||||
</solution>
|
||||
</configuration>
|
||||
Binary file not shown.
@@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">$(MSBuildProjectDirectory)\..\</SolutionDir>
|
||||
|
||||
<!-- Enable the restore command to run before builds -->
|
||||
<RestorePackages Condition=" '$(RestorePackages)' == '' ">false</RestorePackages>
|
||||
|
||||
<!-- Property that enables building a package from a project -->
|
||||
<BuildPackage Condition=" '$(BuildPackage)' == '' ">false</BuildPackage>
|
||||
|
||||
<!-- Determines if package restore consent is required to restore packages -->
|
||||
<RequireRestoreConsent Condition=" '$(RequireRestoreConsent)' != 'false' ">true</RequireRestoreConsent>
|
||||
|
||||
<!-- Download NuGet.exe if it does not already exist -->
|
||||
<DownloadNuGetExe Condition=" '$(DownloadNuGetExe)' == '' ">false</DownloadNuGetExe>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(PackageSources)' == '' ">
|
||||
<!-- Package sources used to restore packages. By default, registered sources under %APPDATA%\NuGet\NuGet.Config will be used -->
|
||||
<!-- The official NuGet package source (https://www.nuget.org/api/v2/) will be excluded if package sources are specified and it does not appear in the list -->
|
||||
<!--
|
||||
<PackageSource Include="https://www.nuget.org/api/v2/" />
|
||||
<PackageSource Include="https://my-nuget-source/nuget/" />
|
||||
-->
|
||||
<PackageSource Include="https://nuget.org/api/v2/" />
|
||||
<PackageSource Include="http://www.myget.org/F/umbracocore/" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
|
||||
<!-- Windows specific commands -->
|
||||
<NuGetToolsPath>$([System.IO.Path]::Combine($(SolutionDir), ".nuget"))</NuGetToolsPath>
|
||||
<PackagesConfig>$([System.IO.Path]::Combine($(ProjectDir), "packages.config"))</PackagesConfig>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
|
||||
<!-- We need to launch nuget.exe with the mono command if we're not on windows -->
|
||||
<NuGetToolsPath>$(SolutionDir).nuget</NuGetToolsPath>
|
||||
<PackagesConfig>packages.config</PackagesConfig>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- NuGet command -->
|
||||
<NuGetExePath Condition=" '$(NuGetExePath)' == '' ">$(NuGetToolsPath)\NuGet.exe</NuGetExePath>
|
||||
<PackageSources Condition=" $(PackageSources) == '' ">@(PackageSource)</PackageSources>
|
||||
|
||||
<NuGetCommand Condition=" '$(OS)' == 'Windows_NT'">"$(NuGetExePath)"</NuGetCommand>
|
||||
<NuGetCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(NuGetExePath)</NuGetCommand>
|
||||
|
||||
<PackageOutputDir Condition="$(PackageOutputDir) == ''">$(TargetDir.Trim('\\'))</PackageOutputDir>
|
||||
|
||||
<RequireConsentSwitch Condition=" $(RequireRestoreConsent) == 'true' ">-RequireConsent</RequireConsentSwitch>
|
||||
<NonInteractiveSwitch Condition=" '$(VisualStudioVersion)' != '' AND '$(OS)' == 'Windows_NT' ">-NonInteractive</NonInteractiveSwitch>
|
||||
|
||||
<PaddedSolutionDir Condition=" '$(OS)' == 'Windows_NT'">"$(SolutionDir) "</PaddedSolutionDir>
|
||||
<PaddedSolutionDir Condition=" '$(OS)' != 'Windows_NT' ">"$(SolutionDir)"</PaddedSolutionDir>
|
||||
|
||||
<!-- Commands -->
|
||||
<RestoreCommand>$(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)</RestoreCommand>
|
||||
<BuildCommand>$(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols</BuildCommand>
|
||||
|
||||
<!-- We need to ensure packages are restored prior to assembly resolve -->
|
||||
<BuildDependsOn Condition="$(RestorePackages) == 'true'">
|
||||
RestorePackages;
|
||||
$(BuildDependsOn);
|
||||
</BuildDependsOn>
|
||||
|
||||
<!-- Make the build depend on restore packages -->
|
||||
<BuildDependsOn Condition="$(BuildPackage) == 'true'">
|
||||
$(BuildDependsOn);
|
||||
BuildPackage;
|
||||
</BuildDependsOn>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="CheckPrerequisites">
|
||||
<!-- Raise an error if we're unable to locate nuget.exe -->
|
||||
<Error Condition="'$(DownloadNuGetExe)' != 'true' AND !Exists('$(NuGetExePath)')" Text="Unable to locate '$(NuGetExePath)'" />
|
||||
<!--
|
||||
Take advantage of MsBuild's build dependency tracking to make sure that we only ever download nuget.exe once.
|
||||
This effectively acts as a lock that makes sure that the download operation will only happen once and all
|
||||
parallel builds will have to wait for it to complete.
|
||||
-->
|
||||
<MsBuild Targets="_DownloadNuGet" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadNuGetExe=$(DownloadNuGetExe)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="_DownloadNuGet">
|
||||
<DownloadNuGet OutputFilename="$(NuGetExePath)" Condition=" '$(DownloadNuGetExe)' == 'true' AND !Exists('$(NuGetExePath)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
|
||||
<Exec Command="$(RestoreCommand)"
|
||||
Condition="'$(OS)' != 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
||||
|
||||
<Exec Command="$(RestoreCommand)"
|
||||
LogStandardErrorAsError="true"
|
||||
Condition="'$(OS)' == 'Windows_NT' And Exists('$(PackagesConfig)')" />
|
||||
</Target>
|
||||
|
||||
<Target Name="BuildPackage" DependsOnTargets="CheckPrerequisites">
|
||||
<Exec Command="$(BuildCommand)"
|
||||
Condition=" '$(OS)' != 'Windows_NT' " />
|
||||
|
||||
<Exec Command="$(BuildCommand)"
|
||||
LogStandardErrorAsError="true"
|
||||
Condition=" '$(OS)' == 'Windows_NT' " />
|
||||
</Target>
|
||||
|
||||
<UsingTask TaskName="DownloadNuGet" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
<OutputFilename ParameterType="System.String" Required="true" />
|
||||
</ParameterGroup>
|
||||
<Task>
|
||||
<Reference Include="System.Core" />
|
||||
<Using Namespace="System" />
|
||||
<Using Namespace="System.IO" />
|
||||
<Using Namespace="System.Net" />
|
||||
<Using Namespace="Microsoft.Build.Framework" />
|
||||
<Using Namespace="Microsoft.Build.Utilities" />
|
||||
<Code Type="Fragment" Language="cs">
|
||||
<![CDATA[
|
||||
try {
|
||||
OutputFilename = Path.GetFullPath(OutputFilename);
|
||||
|
||||
Log.LogMessage("Downloading latest version of NuGet.exe...");
|
||||
WebClient webClient = new WebClient();
|
||||
webClient.DownloadFile("https://www.nuget.org/nuget.exe", OutputFilename);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Log.LogErrorFromException(ex);
|
||||
return false;
|
||||
}
|
||||
]]>
|
||||
</Code>
|
||||
</Task>
|
||||
</UsingTask>
|
||||
</Project>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
@@ -49,11 +49,9 @@
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SqlServerCE.4.0.0.1\lib\System.Data.SqlServerCe.Entity.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
@@ -93,6 +91,7 @@
|
||||
<PostBuildEvent>
|
||||
</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
||||
@@ -180,16 +180,12 @@ namespace SqlCE4Umbraco
|
||||
/// <returns>The return value of the command.</returns>
|
||||
protected override object ExecuteScalar(string commandText, SqlCeParameter[] parameters)
|
||||
{
|
||||
#if DEBUG && DebugDataLayer
|
||||
#if DEBUG && DebugDataLayer
|
||||
// Log Query Execution
|
||||
Trace.TraceInformation(GetType().Name + " SQL ExecuteScalar: " + commandText);
|
||||
#endif
|
||||
using (var cc = UseCurrentConnection)
|
||||
{
|
||||
return SqlCeApplicationBlock.ExecuteScalar(
|
||||
(SqlCeConnection) cc.Connection, (SqlCeTransaction) cc.Transaction,
|
||||
CommandType.Text, commandText, parameters);
|
||||
}
|
||||
#endif
|
||||
|
||||
return SqlCeApplicationBlock.ExecuteScalar(ConnectionString, CommandType.Text, commandText, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -202,17 +198,12 @@ namespace SqlCE4Umbraco
|
||||
/// </returns>
|
||||
protected override int ExecuteNonQuery(string commandText, SqlCeParameter[] parameters)
|
||||
{
|
||||
#if DEBUG && DebugDataLayer
|
||||
#if DEBUG && DebugDataLayer
|
||||
// Log Query Execution
|
||||
Trace.TraceInformation(GetType().Name + " SQL ExecuteNonQuery: " + commandText);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using (var cc = UseCurrentConnection)
|
||||
{
|
||||
return SqlCeApplicationBlock.ExecuteNonQuery(
|
||||
(SqlCeConnection) cc.Connection, (SqlCeTransaction) cc.Transaction,
|
||||
CommandType.Text, commandText, parameters);
|
||||
}
|
||||
return SqlCeApplicationBlock.ExecuteNonQuery(ConnectionString, CommandType.Text, commandText, parameters);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -225,17 +216,13 @@ namespace SqlCE4Umbraco
|
||||
/// </returns>
|
||||
protected override IRecordsReader ExecuteReader(string commandText, SqlCeParameter[] parameters)
|
||||
{
|
||||
#if DEBUG && DebugDataLayer
|
||||
#if DEBUG && DebugDataLayer
|
||||
// Log Query Execution
|
||||
Trace.TraceInformation(GetType().Name + " SQL ExecuteReader: " + commandText);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using (var cc = UseCurrentConnection)
|
||||
{
|
||||
return new SqlCeDataReaderHelper(SqlCeApplicationBlock.ExecuteReader(
|
||||
(SqlCeConnection) cc.Connection, (SqlCeTransaction) cc.Transaction,
|
||||
CommandType.Text, commandText, parameters));
|
||||
}
|
||||
return new SqlCeDataReaderHelper(SqlCeApplicationBlock.ExecuteReader(ConnectionString, CommandType.Text,
|
||||
commandText, parameters));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.SqlServerCe;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
@@ -23,60 +25,29 @@ namespace SqlCE4Umbraco
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var conn = SqlCeContextGuardian.Open(connectionString))
|
||||
{
|
||||
return ExecuteScalarTry(conn, null, commandText, commandParameters);
|
||||
}
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
throw new SqlCeProviderException("Error running Scalar: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee);
|
||||
}
|
||||
}
|
||||
|
||||
public static object ExecuteScalar(
|
||||
SqlCeConnection conn, SqlCeTransaction trx,
|
||||
CommandType commandType,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ExecuteScalarTry(conn, trx, commandText, commandParameters);
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
throw new SqlCeProviderException("Error running Scalar: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee);
|
||||
}
|
||||
}
|
||||
|
||||
public static object ExecuteScalar(
|
||||
SqlCeConnection conn,
|
||||
CommandType commandType,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters)
|
||||
{
|
||||
return ExecuteScalar(conn, null, commandType, commandText, commandParameters);
|
||||
}
|
||||
|
||||
private static object ExecuteScalarTry(
|
||||
SqlCeConnection conn, SqlCeTransaction trx,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters)
|
||||
{
|
||||
object retVal;
|
||||
using (var cmd = trx == null ? new SqlCeCommand(commandText, conn) : new SqlCeCommand(commandText, conn, trx))
|
||||
|
||||
try
|
||||
{
|
||||
AttachParameters(cmd, commandParameters);
|
||||
Debug.WriteLine("---------------------------------SCALAR-------------------------------------");
|
||||
Debug.WriteLine(commandText);
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
retVal = cmd.ExecuteScalar();
|
||||
using (SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString))
|
||||
{
|
||||
using (SqlCeCommand cmd = new SqlCeCommand(commandText, conn))
|
||||
{
|
||||
AttachParameters(cmd, commandParameters);
|
||||
Debug.WriteLine("---------------------------------SCALAR-------------------------------------");
|
||||
Debug.WriteLine(commandText);
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
retVal = cmd.ExecuteScalar();
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
throw new SqlCeProviderException("Error running Scalar: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee.ToString());
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -95,10 +66,49 @@ namespace SqlCE4Umbraco
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var conn = SqlCeContextGuardian.Open(connectionString))
|
||||
int rowsAffected;
|
||||
using (SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString))
|
||||
{
|
||||
return ExecuteNonQueryTry(conn, null, commandText, commandParameters);
|
||||
// this is for multiple queries in the installer
|
||||
if (commandText.Trim().StartsWith("!!!"))
|
||||
{
|
||||
commandText = commandText.Trim().Trim('!');
|
||||
string[] commands = commandText.Split('|');
|
||||
string currentCmd = String.Empty;
|
||||
|
||||
foreach (string cmd in commands)
|
||||
{
|
||||
try
|
||||
{
|
||||
currentCmd = cmd;
|
||||
if (!String.IsNullOrWhiteSpace(cmd))
|
||||
{
|
||||
SqlCeCommand c = new SqlCeCommand(cmd, conn);
|
||||
c.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("*******************************************************************");
|
||||
Debug.WriteLine(currentCmd);
|
||||
Debug.WriteLine(e);
|
||||
Debug.WriteLine("*******************************************************************");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
Debug.WriteLine(commandText);
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
SqlCeCommand cmd = new SqlCeCommand(commandText, conn);
|
||||
AttachParameters(cmd, commandParameters);
|
||||
rowsAffected = cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
return rowsAffected;
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
@@ -106,74 +116,6 @@ namespace SqlCE4Umbraco
|
||||
}
|
||||
}
|
||||
|
||||
public static int ExecuteNonQuery(
|
||||
SqlCeConnection conn,
|
||||
CommandType commandType,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters
|
||||
)
|
||||
{
|
||||
return ExecuteNonQuery(conn, null, commandType, commandText, commandParameters);
|
||||
}
|
||||
|
||||
public static int ExecuteNonQuery(
|
||||
SqlCeConnection conn, SqlCeTransaction trx,
|
||||
CommandType commandType,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ExecuteNonQueryTry(conn, trx, commandText, commandParameters);
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
throw new SqlCeProviderException("Error running NonQuery: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static int ExecuteNonQueryTry(
|
||||
SqlCeConnection conn, SqlCeTransaction trx,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters)
|
||||
{
|
||||
// this is for multiple queries in the installer
|
||||
if (commandText.Trim().StartsWith("!!!"))
|
||||
{
|
||||
commandText = commandText.Trim().Trim('!');
|
||||
var commands = commandText.Split('|');
|
||||
var currentCmd = string.Empty;
|
||||
|
||||
foreach (var command in commands)
|
||||
{
|
||||
try
|
||||
{
|
||||
currentCmd = command;
|
||||
if (string.IsNullOrWhiteSpace(command)) continue;
|
||||
var c = trx == null ? new SqlCeCommand(command, conn) : new SqlCeCommand(command, conn, trx);
|
||||
c.ExecuteNonQuery();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.WriteLine("*******************************************************************");
|
||||
Debug.WriteLine(currentCmd);
|
||||
Debug.WriteLine(e);
|
||||
Debug.WriteLine("*******************************************************************");
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
Debug.WriteLine(commandText);
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
var cmd = new SqlCeCommand(commandText, conn);
|
||||
AttachParameters(cmd, commandParameters);
|
||||
var rowsAffected = cmd.ExecuteNonQuery();
|
||||
return rowsAffected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
@@ -191,8 +133,25 @@ namespace SqlCE4Umbraco
|
||||
{
|
||||
try
|
||||
{
|
||||
var conn = SqlCeContextGuardian.Open(connectionString);
|
||||
return ExecuteReaderTry(conn, null, commandText, commandParameters);
|
||||
Debug.WriteLine("---------------------------------READER-------------------------------------");
|
||||
Debug.WriteLine(commandText);
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
SqlCeDataReader reader;
|
||||
SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString);
|
||||
|
||||
try
|
||||
{
|
||||
SqlCeCommand cmd = new SqlCeCommand(commandText, conn);
|
||||
AttachParameters(cmd, commandParameters);
|
||||
reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
|
||||
}
|
||||
catch
|
||||
{
|
||||
conn.Close();
|
||||
throw;
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
@@ -200,71 +159,30 @@ namespace SqlCE4Umbraco
|
||||
}
|
||||
}
|
||||
|
||||
public static SqlCeDataReader ExecuteReader(
|
||||
SqlCeConnection conn,
|
||||
CommandType commandType,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters
|
||||
)
|
||||
{
|
||||
return ExecuteReader(conn, commandType, commandText, commandParameters);
|
||||
}
|
||||
|
||||
public static SqlCeDataReader ExecuteReader(
|
||||
SqlCeConnection conn, SqlCeTransaction trx,
|
||||
CommandType commandType,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters
|
||||
)
|
||||
{
|
||||
try
|
||||
{
|
||||
return ExecuteReaderTry(conn, trx, commandText, commandParameters);
|
||||
}
|
||||
catch (Exception ee)
|
||||
{
|
||||
throw new SqlCeProviderException("Error running Reader: \nSQL Statement:\n" + commandText + "\n\nException:\n" + ee.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static SqlCeDataReader ExecuteReaderTry(
|
||||
SqlCeConnection conn, SqlCeTransaction trx,
|
||||
string commandText,
|
||||
params SqlCeParameter[] commandParameters)
|
||||
{
|
||||
Debug.WriteLine("---------------------------------READER-------------------------------------");
|
||||
Debug.WriteLine(commandText);
|
||||
Debug.WriteLine("----------------------------------------------------------------------------");
|
||||
|
||||
try
|
||||
{
|
||||
var cmd = trx == null ? new SqlCeCommand(commandText, conn) : new SqlCeCommand(commandText, conn, trx);
|
||||
AttachParameters(cmd, commandParameters);
|
||||
return cmd.ExecuteReader();
|
||||
}
|
||||
catch
|
||||
{
|
||||
conn.Close();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool VerifyConnection(string connectionString)
|
||||
{
|
||||
using (var conn = SqlCeContextGuardian.Open(connectionString))
|
||||
bool isConnected = false;
|
||||
using (SqlCeConnection conn = SqlCeContextGuardian.Open(connectionString))
|
||||
{
|
||||
return conn.State == ConnectionState.Open;
|
||||
isConnected = conn.State == ConnectionState.Open;
|
||||
}
|
||||
|
||||
return isConnected;
|
||||
}
|
||||
|
||||
private static void AttachParameters(SqlCeCommand command, IEnumerable<SqlCeParameter> commandParameters)
|
||||
private static void AttachParameters(SqlCeCommand command, SqlCeParameter[] commandParameters)
|
||||
{
|
||||
foreach (var parameter in commandParameters)
|
||||
foreach (SqlCeParameter parameter in commandParameters)
|
||||
{
|
||||
if ((parameter.Direction == ParameterDirection.InputOutput) && (parameter.Value == null))
|
||||
{
|
||||
parameter.Value = DBNull.Value;
|
||||
}
|
||||
command.Parameters.Add(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
@@ -30,10 +30,6 @@
|
||||
<assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
|
||||
</dependentAssembly>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup></configuration>
|
||||
</configuration>
|
||||
+2
-2
@@ -11,5 +11,5 @@ using System.Resources;
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
[assembly: AssemblyFileVersion("7.6.12")]
|
||||
[assembly: AssemblyInformationalVersion("7.6.12")]
|
||||
[assembly: AssemblyFileVersion("7.5.7")]
|
||||
[assembly: AssemblyInformationalVersion("7.5.7")]
|
||||
@@ -23,12 +23,12 @@ namespace Umbraco.Core
|
||||
: base(serviceProvider, logger, packageActions)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IAction"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IAction> Actions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IPackageAction"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<IAction> Actions
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Profiling;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
@@ -48,7 +49,7 @@ namespace Umbraco.Core
|
||||
/// <param name="cache"></param>
|
||||
[Obsolete("Use the other constructor specifying a ProfilingLogger instead")]
|
||||
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache)
|
||||
: this(dbContext, serviceContext, cache,
|
||||
: this(dbContext, serviceContext, cache,
|
||||
new ProfilingLogger(LoggerResolver.Current.Logger, ProfilerResolver.Current.Profiler))
|
||||
{
|
||||
}
|
||||
@@ -89,7 +90,7 @@ namespace Umbraco.Core
|
||||
/// <param name="replaceContext">If set to true and the singleton is already set, it will be replaced</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext)
|
||||
{
|
||||
@@ -107,14 +108,14 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <param name="cache"></param>
|
||||
/// <param name="replaceContext">
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// startup if for some reason the boot manager is not the umbraco boot manager.
|
||||
/// </param>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
[Obsolete("Use the other method specifying an ProfilingLogger instead")]
|
||||
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, bool replaceContext)
|
||||
@@ -135,14 +136,14 @@ namespace Umbraco.Core
|
||||
/// <param name="cache"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="replaceContext">
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// startup if for some reason the boot manager is not the umbraco boot manager.
|
||||
/// </param>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, CacheHelper cache, ProfilingLogger logger, bool replaceContext)
|
||||
{
|
||||
@@ -161,11 +162,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static ApplicationContext Current { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the scope provider.
|
||||
/// </summary>
|
||||
internal IScopeProvider ScopeProvider { get { return _databaseContext == null ? null : _databaseContext.ScopeProvider; } }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the application wide cache accessor
|
||||
/// </summary>
|
||||
@@ -175,7 +171,7 @@ namespace Umbraco.Core
|
||||
public CacheHelper ApplicationCache { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
|
||||
/// Exposes the global ProfilingLogger - this should generally not be accessed via the UmbracoContext and should normally just be exposed
|
||||
/// on most base classes or injected with IoC
|
||||
/// </summary>
|
||||
public ProfilingLogger ProfilingLogger { get; private set; }
|
||||
@@ -213,7 +209,7 @@ namespace Umbraco.Core
|
||||
// GlobalSettings.CurrentVersion returns the hard-coded "current version"
|
||||
// the system is configured if they match
|
||||
// if they don't, install runs, updates web.config (presumably) and updates GlobalSettings.ConfiguredStatus
|
||||
|
||||
|
||||
public bool IsConfigured
|
||||
{
|
||||
get { return _configured.Value; }
|
||||
@@ -226,8 +222,8 @@ namespace Umbraco.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsConfigured == false
|
||||
&& DatabaseContext != null
|
||||
if (IsConfigured == false
|
||||
&& DatabaseContext != null
|
||||
&& DatabaseContext.IsDatabaseConfigured)
|
||||
{
|
||||
var schemaresult = DatabaseContext.ValidateDatabaseSchema();
|
||||
@@ -274,12 +270,12 @@ namespace Umbraco.Core
|
||||
|
||||
private Lazy<bool> _configured;
|
||||
internal MainDom MainDom { get; private set; }
|
||||
|
||||
|
||||
private void Init()
|
||||
{
|
||||
MainDom = new MainDom(ProfilingLogger.Logger);
|
||||
MainDom.Acquire();
|
||||
|
||||
|
||||
//Create the lazy value to resolve whether or not the application is 'configured'
|
||||
_configured = new Lazy<bool>(() =>
|
||||
{
|
||||
@@ -289,7 +285,7 @@ namespace Umbraco.Core
|
||||
var currentVersion = UmbracoVersion.GetSemanticVersion();
|
||||
|
||||
var ok =
|
||||
//we are not configured if this is null
|
||||
//we are not configured if this is null
|
||||
string.IsNullOrWhiteSpace(configStatus) == false
|
||||
//they must match
|
||||
&& configStatus == currentVersion;
|
||||
@@ -300,10 +296,10 @@ namespace Umbraco.Core
|
||||
// if we have a db context available, if we don't then we are not installed anyways
|
||||
if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.CanConnect)
|
||||
{
|
||||
var found = Services.MigrationEntryService.FindEntry(Constants.System.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion());
|
||||
var found = Services.MigrationEntryService.FindEntry(GlobalSettings.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion());
|
||||
if (found == null)
|
||||
{
|
||||
//we haven't executed this migration in this environment, so even though the config versions match,
|
||||
//we haven't executed this migration in this environment, so even though the config versions match,
|
||||
// this db has not been updated.
|
||||
ProfilingLogger.Logger.Debug<ApplicationContext>(string.Format("The migration for version: '{0} has not been executed, there is no record in the database", currentVersion.ToSemanticString()));
|
||||
ok = false;
|
||||
@@ -323,7 +319,7 @@ namespace Umbraco.Core
|
||||
return false;
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private string ConfigurationStatus
|
||||
@@ -338,7 +334,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AssertIsNotReady()
|
||||
@@ -363,7 +359,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
internal set { _databaseContext = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current ServiceContext
|
||||
/// </summary>
|
||||
@@ -417,27 +413,20 @@ namespace Umbraco.Core
|
||||
ResolverCollection.ResetAll();
|
||||
//reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
|
||||
Resolution.Reset();
|
||||
|
||||
|
||||
//reset the instance objects
|
||||
this.ApplicationCache = null;
|
||||
if (_databaseContext != null) //need to check the internal field here
|
||||
{
|
||||
if (_databaseContext.ScopeProvider.AmbientScope != null)
|
||||
{
|
||||
var scope = _databaseContext.ScopeProvider.AmbientScope;
|
||||
scope.Dispose();
|
||||
}
|
||||
/*
|
||||
if (DatabaseContext.IsDatabaseConfigured && DatabaseContext.Database != null)
|
||||
{
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
*/
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
}
|
||||
this.DatabaseContext = null;
|
||||
this.Services = null;
|
||||
this._isReady = false; //set the internal field
|
||||
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_disposed = true;
|
||||
}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Core.Auditing
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used by events raised from hthe BackofficeUserManager
|
||||
/// </summary>
|
||||
public class IdentityAuditEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The action that got triggered from the audit event
|
||||
/// </summary>
|
||||
public AuditEvent Action { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current date/time in UTC format
|
||||
/// </summary>
|
||||
public DateTime DateTimeUtc { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The source IP address of the user performing the action
|
||||
/// </summary>
|
||||
public string IpAddress { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The user affected by the event raised
|
||||
/// </summary>
|
||||
public int AffectedUser { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// If a user is perfoming an action on a different user, then this will be set. Otherwise it will be -1
|
||||
/// </summary>
|
||||
public int PerformingUser { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// An optional comment about the action being logged
|
||||
/// </summary>
|
||||
public string Comment { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// This property is always empty except in the LoginFailed event for an unknown user trying to login
|
||||
/// </summary>
|
||||
public string Username { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the properties on the event being raised, all parameters are optional except for the action being performed
|
||||
/// </summary>
|
||||
/// <param name="action">An action based on the AuditEvent enum</param>
|
||||
/// <param name="ipAddress">The client's IP address. This is usually automatically set but could be overridden if necessary</param>
|
||||
/// <param name="performingUser">The Id of the user performing the action (if different from the user affected by the action)</param>
|
||||
public IdentityAuditEventArgs(AuditEvent action, string ipAddress, int performingUser = -1)
|
||||
{
|
||||
DateTimeUtc = DateTime.UtcNow;
|
||||
Action = action;
|
||||
|
||||
IpAddress = ipAddress;
|
||||
|
||||
PerformingUser = performingUser == -1
|
||||
? GetCurrentRequestBackofficeUserId()
|
||||
: performingUser;
|
||||
}
|
||||
|
||||
public IdentityAuditEventArgs(AuditEvent action, string ipAddress, string username, string comment)
|
||||
{
|
||||
DateTimeUtc = DateTime.UtcNow;
|
||||
Action = action;
|
||||
|
||||
IpAddress = ipAddress;
|
||||
Username = username;
|
||||
Comment = comment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current logged in backoffice user's Id logging if there is one
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected int GetCurrentRequestBackofficeUserId()
|
||||
{
|
||||
var userId = -1;
|
||||
var backOfficeIdentity = Thread.CurrentPrincipal.GetUmbracoIdentity();
|
||||
if (backOfficeIdentity != null)
|
||||
int.TryParse(backOfficeIdentity.Id.ToString(), out userId);
|
||||
return userId;
|
||||
}
|
||||
}
|
||||
|
||||
public enum AuditEvent
|
||||
{
|
||||
AccountLocked,
|
||||
AccountUnlocked,
|
||||
ForgotPasswordRequested,
|
||||
ForgotPasswordChangedSuccess,
|
||||
LoginFailed,
|
||||
LoginRequiresVerification,
|
||||
LoginSucces,
|
||||
LogoutSuccess,
|
||||
PasswordChanged,
|
||||
PasswordReset,
|
||||
ResetAccessFailedCount
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
|
||||
[assembly: PreApplicationStartMethod(typeof(BindingRedirects), "Initialize")]
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages any assembly binding redirects that cannot be done via config (i.e. unsigned --> signed assemblies)
|
||||
/// </summary>
|
||||
public sealed class BindingRedirects
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
// this only gets called when an assembly can't be resolved
|
||||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
||||
}
|
||||
|
||||
private static readonly Regex Log4NetAssemblyPattern = new Regex("log4net, Version=([\\d\\.]+?), Culture=neutral, PublicKeyToken=\\w+$", RegexOptions.Compiled);
|
||||
private const string Log4NetReplacement = "log4net, Version=2.0.8.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a";
|
||||
|
||||
/// <summary>
|
||||
/// This is used to do an assembly binding redirect via code - normally required due to signature changes in assemblies
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
//log4net:
|
||||
if (Log4NetAssemblyPattern.IsMatch(args.Name) && args.Name != Log4NetReplacement)
|
||||
{
|
||||
return Assembly.Load(Log4NetAssemblyPattern.Replace(args.Name, Log4NetReplacement));
|
||||
}
|
||||
|
||||
//AutoMapper:
|
||||
// ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again
|
||||
// do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow
|
||||
if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null"))
|
||||
return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005"));
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static class ByteArrayExtensions
|
||||
{
|
||||
private static readonly char[] BytesToHexStringLookup = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
||||
|
||||
public static string ToHexString(this byte[] bytes)
|
||||
{
|
||||
int i = 0, p = 0, bytesLength = bytes.Length;
|
||||
var chars = new char[bytesLength * 2];
|
||||
while (i < bytesLength)
|
||||
{
|
||||
var b = bytes[i++];
|
||||
chars[p++] = BytesToHexStringLookup[b / 0x10];
|
||||
chars[p++] = BytesToHexStringLookup[b % 0x10];
|
||||
}
|
||||
return new string(chars, 0, chars.Length);
|
||||
}
|
||||
|
||||
public static string ToHexString(this byte[] bytes, char separator, int blockSize, int blockCount)
|
||||
{
|
||||
int p = 0, bytesLength = bytes.Length, count = 0, size = 0;
|
||||
var chars = new char[bytesLength * 2 + blockCount];
|
||||
for (var i = 0; i < bytesLength; i++)
|
||||
{
|
||||
var b = bytes[i++];
|
||||
chars[p++] = BytesToHexStringLookup[b / 0x10];
|
||||
chars[p++] = BytesToHexStringLookup[b % 0x10];
|
||||
if (count == blockCount) continue;
|
||||
if (++size < blockSize) continue;
|
||||
|
||||
chars[p++] = '/';
|
||||
size = 0;
|
||||
count++;
|
||||
}
|
||||
return new string(chars, 0, chars.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,8 +64,7 @@ namespace Umbraco.Core.Cache
|
||||
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
|
||||
public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:";
|
||||
|
||||
[Obsolete("No longer used and will be removed in v8")]
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[UmbracoWillObsolete("This cache key is only used for legacy business logic caching, remove in v8")]
|
||||
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
@@ -89,7 +88,7 @@ namespace Umbraco.Core.Cache
|
||||
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
|
||||
public const string DataTypePreValuesCacheKey = "UmbracoPreVal";
|
||||
|
||||
public const string IdToKeyCacheKey = "UI2K__";
|
||||
public const string KeyToIdCacheKey = "UK2I__";
|
||||
public const string IdToKeyCacheKey = "UI2K";
|
||||
public const string KeyToIdCacheKey = "UK2I";
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,6 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public DeepCloneRuntimeCacheProvider(IRuntimeCacheProvider innerProvider)
|
||||
{
|
||||
if (innerProvider.GetType() == typeof(DeepCloneRuntimeCacheProvider))
|
||||
throw new InvalidOperationException("A " + typeof(DeepCloneRuntimeCacheProvider) + " cannot wrap another instance of " + typeof(DeepCloneRuntimeCacheProvider));
|
||||
|
||||
InnerProvider = innerProvider;
|
||||
}
|
||||
|
||||
@@ -108,11 +105,9 @@ namespace Umbraco.Core.Cache
|
||||
var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache
|
||||
if (value == null) return null; // do not store null values (backward compat)
|
||||
|
||||
//Clone/reset to go into the cache
|
||||
return CheckCloneableAndTracksChanges(value);
|
||||
}, timeout, isSliding, priority, removedCallback, dependentFiles);
|
||||
|
||||
//Clone/reset to go out of the cache
|
||||
return CheckCloneableAndTracksChanges(cached);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,250 +1,268 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the default cache policy.
|
||||
/// The default cache policy for retrieving a single entity
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier.</typeparam>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
/// <remarks>
|
||||
/// <para>The default cache policy caches entities with a 5 minutes sliding expiration.</para>
|
||||
/// <para>Each entity is cached individually.</para>
|
||||
/// <para>If options.GetAllCacheAllowZeroCount then a 'zero-count' array is cached when GetAll finds nothing.</para>
|
||||
/// <para>If options.GetAllCacheValidateCount then we check against the db when getting many entities.</para>
|
||||
/// This cache policy uses sliding expiration and caches instances for 5 minutes. However if allow zero count is true, then we use the
|
||||
/// default policy with no expiry.
|
||||
/// </remarks>
|
||||
internal class DefaultRepositoryCachePolicy<TEntity, TId> : RepositoryCachePolicyBase<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private static readonly TEntity[] EmptyEntities = new TEntity[0]; // const
|
||||
private readonly RepositoryCachePolicyOptions _options;
|
||||
|
||||
|
||||
public DefaultRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
|
||||
: base(cache)
|
||||
{
|
||||
{
|
||||
if (options == null) throw new ArgumentNullException("options");
|
||||
_options = options;
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public override IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
|
||||
{
|
||||
return new ScopedRepositoryCachePolicy<TEntity, TId>(this, runtimeCache, scope);
|
||||
}
|
||||
|
||||
protected string GetEntityCacheKey(object id)
|
||||
protected string GetCacheIdKey(object id)
|
||||
{
|
||||
if (id == null) throw new ArgumentNullException("id");
|
||||
return GetEntityTypeCacheKey() + id;
|
||||
|
||||
return string.Format("{0}{1}", GetCacheTypeKey(), id);
|
||||
}
|
||||
|
||||
protected string GetEntityTypeCacheKey()
|
||||
protected string GetCacheTypeKey()
|
||||
{
|
||||
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
|
||||
}
|
||||
|
||||
protected virtual void InsertEntity(string cacheKey, TEntity entity)
|
||||
{
|
||||
Cache.InsertCacheItem(cacheKey, () => entity, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
|
||||
protected virtual void InsertEntities(TId[] ids, TEntity[] entities)
|
||||
{
|
||||
if (ids.Length == 0 && entities.Length == 0 && _options.GetAllCacheAllowZeroCount)
|
||||
{
|
||||
// getting all of them, and finding nothing.
|
||||
// if we can cache a zero count, cache an empty array,
|
||||
// for as long as the cache is not cleared (no expiration)
|
||||
Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => EmptyEntities);
|
||||
}
|
||||
else
|
||||
{
|
||||
// individually cache each item
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
var capture = entity;
|
||||
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => capture, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Create(TEntity entity, Action<TEntity> persistNew)
|
||||
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
|
||||
try
|
||||
{
|
||||
persistNew(entity);
|
||||
persistMethod(entity);
|
||||
|
||||
// just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => entity,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
|
||||
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if an exception is thrown we need to remove the entry from cache,
|
||||
// this is ONLY a work around because of the way
|
||||
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
|
||||
Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way
|
||||
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
|
||||
Cache.ClearCacheItem(GetCacheIdKey(entity.Id));
|
||||
|
||||
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Update(TEntity entity, Action<TEntity> persistUpdated)
|
||||
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
|
||||
try
|
||||
{
|
||||
persistUpdated(entity);
|
||||
|
||||
// just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetEntityCacheKey(entity.Id), () => entity, TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if an exception is thrown we need to remove the entry from cache,
|
||||
// this is ONLY a work around because of the way
|
||||
// that we cache entities: http://issues.umbraco.org/issue/U4-4259
|
||||
Cache.ClearCacheItem(GetEntityCacheKey(entity.Id));
|
||||
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Delete(TEntity entity, Action<TEntity> persistDeleted)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
|
||||
try
|
||||
{
|
||||
persistDeleted(entity);
|
||||
persistMethod(entity);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// whatever happens, clear the cache
|
||||
var cacheKey = GetEntityCacheKey(entity.Id);
|
||||
Cache.ClearCacheItem(cacheKey);
|
||||
// if there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
//set the disposal action
|
||||
var cacheKey = GetCacheIdKey(entity.Id);
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
Cache.ClearCacheItem(cacheKey);
|
||||
//If there's a GetAllCacheAllowZeroCount cache, ensure it is cleared
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
|
||||
{
|
||||
var cacheKey = GetEntityCacheKey(id);
|
||||
var fromCache = Cache.GetCacheItem<TEntity>(cacheKey);
|
||||
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
|
||||
|
||||
// if found in cache then return else fetch and cache
|
||||
var cacheKey = GetCacheIdKey(id);
|
||||
var fromCache = Cache.GetCacheItem<TEntity>(cacheKey);
|
||||
if (fromCache != null)
|
||||
return fromCache;
|
||||
var entity = performGet(id);
|
||||
|
||||
var entity = getFromRepo(id);
|
||||
|
||||
if (entity != null && entity.HasIdentity)
|
||||
InsertEntity(cacheKey, entity);
|
||||
//set the disposal action
|
||||
SetCacheAction(cacheKey, entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TEntity GetCached(TId id)
|
||||
public override TEntity Get(TId id)
|
||||
{
|
||||
var cacheKey = GetEntityCacheKey(id);
|
||||
var cacheKey = GetCacheIdKey(id);
|
||||
return Cache.GetCacheItem<TEntity>(cacheKey);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
|
||||
{
|
||||
// if found in cache the return else check
|
||||
var cacheKey = GetEntityCacheKey(id);
|
||||
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
|
||||
|
||||
var cacheKey = GetCacheIdKey(id);
|
||||
var fromCache = Cache.GetCacheItem<TEntity>(cacheKey);
|
||||
return fromCache != null || performExists(id);
|
||||
return fromCache != null || getFromRepo(id);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
|
||||
{
|
||||
if (ids.Length > 0)
|
||||
if (getFromRepo == null) throw new ArgumentNullException("getFromRepo");
|
||||
|
||||
if (ids.Any())
|
||||
{
|
||||
// try to get each entity from the cache
|
||||
// if we can find all of them, return
|
||||
var entities = ids.Select(GetCached).WhereNotNull().ToArray();
|
||||
if (ids.Length.Equals(entities.Length))
|
||||
return entities; // no need for null checks, we are not caching nulls
|
||||
var entities = ids.Select(Get).ToArray();
|
||||
if (ids.Length.Equals(entities.Length) && entities.Any(x => x == null) == false)
|
||||
return entities;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get everything we have
|
||||
var entities = Cache.GetCacheItemsByKeySearch<TEntity>(GetEntityTypeCacheKey())
|
||||
.ToArray(); // no need for null checks, we are not caching nulls
|
||||
|
||||
if (entities.Length > 0)
|
||||
var allEntities = GetAllFromCache();
|
||||
if (allEntities.Any())
|
||||
{
|
||||
// if some of them were in the cache...
|
||||
if (_options.GetAllCacheValidateCount)
|
||||
{
|
||||
// need to validate the count, get the actual count and return if ok
|
||||
//Get count of all entities of current type (TEntity) to ensure cached result is correct
|
||||
var totalCount = _options.PerformCount();
|
||||
if (entities.Length == totalCount)
|
||||
return entities;
|
||||
if (allEntities.Length == totalCount)
|
||||
return allEntities;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no need to validate, just return what we have and assume it's all there is
|
||||
return entities;
|
||||
return allEntities;
|
||||
}
|
||||
}
|
||||
else if (_options.GetAllCacheAllowZeroCount)
|
||||
{
|
||||
// if none of them were in the cache
|
||||
// and we allow zero count - check for the special (empty) entry
|
||||
var empty = Cache.GetCacheItem<TEntity[]>(GetEntityTypeCacheKey());
|
||||
if (empty != null) return empty;
|
||||
//if the repository allows caching a zero count, then check the zero count cache
|
||||
if (HasZeroCountCache())
|
||||
{
|
||||
//there is a zero count cache so return an empty list
|
||||
return new TEntity[] {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cache failed, get from repo and cache
|
||||
var repoEntities = performGetAll(ids)
|
||||
.WhereNotNull() // exclude nulls!
|
||||
.Where(x => x.HasIdentity) // be safe, though would be weird...
|
||||
//we need to do the lookup from the repo
|
||||
var entityCollection = getFromRepo(ids)
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
// note: if empty & allow zero count, will cache a special (empty) entry
|
||||
InsertEntities(ids, repoEntities);
|
||||
//set the disposal action
|
||||
SetCacheAction(ids, entityCollection);
|
||||
|
||||
return repoEntities;
|
||||
return entityCollection;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ClearAll()
|
||||
/// <summary>
|
||||
/// Looks up the zero count cache, must return null if it doesn't exist
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool HasZeroCountCache()
|
||||
{
|
||||
Cache.ClearAllCache();
|
||||
var zeroCount = Cache.GetCacheItem<TEntity[]>(GetCacheTypeKey());
|
||||
return (zeroCount != null && zeroCount.Any() == false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the lookup for all entities of this type from the cache
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected TEntity[] GetAllFromCache()
|
||||
{
|
||||
var allEntities = Cache.GetCacheItemsByKeySearch<TEntity>(GetCacheTypeKey())
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
return allEntities.Any() ? allEntities : new TEntity[] {};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal for a single entity
|
||||
/// </summary>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="entity"></param>
|
||||
protected virtual void SetCacheAction(string cacheKey, TEntity entity)
|
||||
{
|
||||
if (entity == null) return;
|
||||
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(cacheKey, () => entity,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal for an entity collection
|
||||
/// </summary>
|
||||
/// <param name="ids"></param>
|
||||
/// <param name="entityCollection"></param>
|
||||
protected virtual void SetCacheAction(TId[] ids, TEntity[] entityCollection)
|
||||
{
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//This option cannot execute if we are looking up specific Ids
|
||||
if (ids.Any() == false && entityCollection.Length == 0 && _options.GetAllCacheAllowZeroCount)
|
||||
{
|
||||
//there was nothing returned but we want to cache a zero count result so add an TEntity[] to the cache
|
||||
// to signify that there is a zero count cache
|
||||
//NOTE: Don't set expiry/sliding for a zero count
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new TEntity[] {});
|
||||
}
|
||||
else
|
||||
{
|
||||
//This is the default behavior, we'll individually cache each item so that if/when these items are resolved
|
||||
// by id, they are returned from the already existing cache.
|
||||
foreach (var entity in entityCollection.WhereNotNull())
|
||||
{
|
||||
var localCopy = entity;
|
||||
//just to be safe, we cannot cache an item without an identity
|
||||
if (localCopy.HasIdentity)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheIdKey(entity.Id), () => localCopy,
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates cache policies
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
internal class DefaultRepositoryCachePolicyFactory<TEntity, TId> : IRepositoryCachePolicyFactory<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly RepositoryCachePolicyOptions _options;
|
||||
|
||||
public DefaultRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, RepositoryCachePolicyOptions options)
|
||||
{
|
||||
_runtimeCache = runtimeCache;
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
|
||||
{
|
||||
return new DefaultRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,178 +3,227 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Collections;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a caching policy that caches the entire entities set as a single collection.
|
||||
/// A caching policy that caches an entire dataset as a single collection
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier.</typeparam>
|
||||
/// <remarks>
|
||||
/// <para>Caches the entire set of entities as a single collection.</para>
|
||||
/// <para>Used by Content-, Media- and MemberTypeRepository, DataTypeRepository, DomainRepository,
|
||||
/// LanguageRepository, PublicAccessRepository, TemplateRepository... things that make sense to
|
||||
/// keep as a whole in memory.</para>
|
||||
/// </remarks>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
internal class FullDataSetRepositoryCachePolicy<TEntity, TId> : RepositoryCachePolicyBase<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly Func<TEntity, TId> _entityGetId;
|
||||
private readonly Func<TEntity, TId> _getEntityId;
|
||||
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
|
||||
private readonly bool _expires;
|
||||
|
||||
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func<TEntity, TId> entityGetId, bool expires)
|
||||
public FullDataSetRepositoryCachePolicy(IRuntimeCacheProvider cache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
|
||||
: base(cache)
|
||||
{
|
||||
_entityGetId = entityGetId;
|
||||
_getEntityId = getEntityId;
|
||||
_getAllFromRepo = getAllFromRepo;
|
||||
_expires = expires;
|
||||
}
|
||||
|
||||
public override IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
|
||||
{
|
||||
return new ScopedRepositoryCachePolicy<TEntity, TId>(this, runtimeCache, scope);
|
||||
}
|
||||
private bool? _hasZeroCountCache;
|
||||
|
||||
protected static readonly TId[] EmptyIds = new TId[0]; // const
|
||||
|
||||
protected string GetEntityTypeCacheKey()
|
||||
protected string GetCacheTypeKey()
|
||||
{
|
||||
return string.Format("uRepo_{0}_", typeof(TEntity).Name);
|
||||
}
|
||||
|
||||
protected void InsertEntities(TEntity[] entities)
|
||||
{
|
||||
// cache is expected to be a deep-cloning cache ie it deep-clones whatever is
|
||||
// IDeepCloneable when it goes in, and out. it also resets dirty properties,
|
||||
// making sure that no 'dirty' entity is cached.
|
||||
//
|
||||
// this policy is caching the entire list of entities. to ensure that entities
|
||||
// are properly deep-clones when cached, it uses a DeepCloneableList. however,
|
||||
// we don't want to deep-clone *each* entity in the list when fetching it from
|
||||
// cache as that would not be efficient for Get(id). so the DeepCloneableList is
|
||||
// set to ListCloneBehavior.CloneOnce ie it will clone *once* when inserting,
|
||||
// and then will *not* clone when retrieving.
|
||||
|
||||
if (_expires)
|
||||
{
|
||||
Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList<TEntity>(entities), TimeSpan.FromMinutes(5), true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cache.InsertCacheItem(GetEntityTypeCacheKey(), () => new DeepCloneableList<TEntity>(entities));
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Create(TEntity entity, Action<TEntity> persistNew)
|
||||
public override void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
|
||||
try
|
||||
{
|
||||
persistNew(entity);
|
||||
persistMethod(entity);
|
||||
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//Clear all
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
}
|
||||
finally
|
||||
catch
|
||||
{
|
||||
ClearAll();
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//Clear all
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Update(TEntity entity, Action<TEntity> persistUpdated)
|
||||
public override void Remove(TEntity entity, Action<TEntity> persistMethod)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
if (persistMethod == null) throw new ArgumentNullException("persistMethod");
|
||||
|
||||
try
|
||||
{
|
||||
persistUpdated(entity);
|
||||
persistMethod(entity);
|
||||
}
|
||||
finally
|
||||
{
|
||||
ClearAll();
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//Clear all
|
||||
Cache.ClearCacheItem(GetCacheTypeKey());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Delete(TEntity entity, Action<TEntity> persistDeleted)
|
||||
public override TEntity Get(TId id, Func<TId, TEntity> getFromRepo)
|
||||
{
|
||||
if (entity == null) throw new ArgumentNullException("entity");
|
||||
//Force get all with cache
|
||||
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
|
||||
|
||||
try
|
||||
//we don't have anything in cache (this should never happen), just return from the repo
|
||||
if (found == null) return getFromRepo(id);
|
||||
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
|
||||
if (entity == null) return null;
|
||||
|
||||
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
|
||||
return (TEntity)entity.DeepClone();
|
||||
}
|
||||
|
||||
public override TEntity Get(TId id)
|
||||
{
|
||||
//Force get all with cache
|
||||
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
|
||||
|
||||
//we don't have anything in cache (this should never happen), just return null
|
||||
if (found == null) return null;
|
||||
var entity = found.FirstOrDefault(x => _getEntityId(x).Equals(id));
|
||||
if (entity == null) return null;
|
||||
|
||||
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
|
||||
return (TEntity)entity.DeepClone();
|
||||
}
|
||||
|
||||
public override bool Exists(TId id, Func<TId, bool> getFromRepo)
|
||||
{
|
||||
//Force get all with cache
|
||||
var found = GetAll(new TId[] { }, ids => _getAllFromRepo().WhereNotNull());
|
||||
|
||||
//we don't have anything in cache (this should never happen), just return from the repo
|
||||
return found == null
|
||||
? getFromRepo(id)
|
||||
: found.Any(x => _getEntityId(x).Equals(id));
|
||||
}
|
||||
|
||||
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo)
|
||||
{
|
||||
//process getting all including setting the cache callback
|
||||
var result = PerformGetAll(getFromRepo);
|
||||
|
||||
//now that the base result has been calculated, they will all be cached.
|
||||
// Now we can just filter by ids if they have been supplied
|
||||
|
||||
return (ids.Any()
|
||||
? result.Where(x => ids.Contains(_getEntityId(x))).ToArray()
|
||||
: result)
|
||||
//We must ensure to deep clone each one out manually since the deep clone list only clones one way
|
||||
.Select(x => (TEntity)x.DeepClone())
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private TEntity[] PerformGetAll(Func<TId[], IEnumerable<TEntity>> getFromRepo)
|
||||
{
|
||||
var allEntities = GetAllFromCache();
|
||||
if (allEntities.Any())
|
||||
{
|
||||
persistDeleted(entity);
|
||||
return allEntities;
|
||||
}
|
||||
finally
|
||||
|
||||
//check the zero count cache
|
||||
if (HasZeroCountCache())
|
||||
{
|
||||
ClearAll();
|
||||
//there is a zero count cache so return an empty list
|
||||
return new TEntity[] { };
|
||||
}
|
||||
|
||||
//we need to do the lookup from the repo
|
||||
var entityCollection = getFromRepo(new TId[] { })
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
//set the disposal action
|
||||
SetCacheAction(entityCollection);
|
||||
|
||||
return entityCollection;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
/// <summary>
|
||||
/// For this type of caching policy, we don't cache individual items
|
||||
/// </summary>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="entity"></param>
|
||||
protected void SetCacheAction(string cacheKey, TEntity entity)
|
||||
{
|
||||
// get all from the cache, then look for the entity
|
||||
var all = GetAllCached(performGetAll);
|
||||
var entity = all.FirstOrDefault(x => _entityGetId(x).Equals(id));
|
||||
|
||||
// see note in InsertEntities - what we get here is the original
|
||||
// cached entity, not a clone, so we need to manually ensure it is deep-cloned.
|
||||
return entity == null ? null : (TEntity) entity.DeepClone();
|
||||
//No-op
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TEntity GetCached(TId id)
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal for an entity collection
|
||||
/// </summary>
|
||||
/// <param name="entityCollection"></param>
|
||||
protected void SetCacheAction(TEntity[] entityCollection)
|
||||
{
|
||||
// get all from the cache -- and only the cache, then look for the entity
|
||||
var all = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetEntityTypeCacheKey());
|
||||
var entity = all == null ? null : all.FirstOrDefault(x => _entityGetId(x).Equals(id));
|
||||
//set the disposal action
|
||||
SetCacheAction(() =>
|
||||
{
|
||||
//We want to cache the result as a single collection
|
||||
|
||||
// see note in InsertEntities - what we get here is the original
|
||||
// cached entity, not a clone, so we need to manually ensure it is deep-cloned.
|
||||
return entity == null ? null : (TEntity)entity.DeepClone();
|
||||
if (_expires)
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection),
|
||||
timeout: TimeSpan.FromMinutes(5),
|
||||
isSliding: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Cache.InsertCacheItem(GetCacheTypeKey(), () => new DeepCloneableList<TEntity>(entityCollection));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool Exists(TId id, Func<TId, bool> performExits, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
/// <summary>
|
||||
/// Looks up the zero count cache, must return null if it doesn't exist
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected bool HasZeroCountCache()
|
||||
{
|
||||
// get all as one set, then look for the entity
|
||||
var all = GetAllCached(performGetAll);
|
||||
return all.Any(x => _entityGetId(x).Equals(id));
|
||||
if (_hasZeroCountCache.HasValue)
|
||||
return _hasZeroCountCache.Value;
|
||||
|
||||
_hasZeroCountCache = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey()) != null;
|
||||
return _hasZeroCountCache.Value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
/// <summary>
|
||||
/// This policy will cache the full data set as a single collection
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected TEntity[] GetAllFromCache()
|
||||
{
|
||||
// get all as one set, from cache if possible, else repo
|
||||
var all = GetAllCached(performGetAll);
|
||||
var found = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetCacheTypeKey());
|
||||
|
||||
// if ids have been specified, filter
|
||||
if (ids.Length > 0) all = all.Where(x => ids.Contains(_entityGetId(x)));
|
||||
//This method will get called before checking for zero count cache, so we'll just set the flag here
|
||||
_hasZeroCountCache = found != null;
|
||||
|
||||
// and return
|
||||
// see note in SetCacheActionToInsertEntities - what we get here is the original
|
||||
// cached entities, not clones, so we need to manually ensure they are deep-cloned.
|
||||
return all.Select(x => (TEntity) x.DeepClone()).ToArray();
|
||||
return found == null ? new TEntity[] { } : found.WhereNotNull().ToArray();
|
||||
}
|
||||
|
||||
// does NOT clone anything, so be nice with the returned values
|
||||
private IEnumerable<TEntity> GetAllCached(Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
// try the cache first
|
||||
var all = Cache.GetCacheItem<DeepCloneableList<TEntity>>(GetEntityTypeCacheKey());
|
||||
if (all != null) return all.ToArray();
|
||||
|
||||
// else get from repo and cache
|
||||
var entities = performGetAll(EmptyIds).WhereNotNull().ToArray();
|
||||
InsertEntities(entities); // may be an empty array...
|
||||
return entities;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void ClearAll()
|
||||
{
|
||||
Cache.ClearCacheItem(GetEntityTypeCacheKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates cache policies
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
internal class FullDataSetRepositoryCachePolicyFactory<TEntity, TId> : IRepositoryCachePolicyFactory<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly Func<TEntity, TId> _getEntityId;
|
||||
private readonly Func<IEnumerable<TEntity>> _getAllFromRepo;
|
||||
private readonly bool _expires;
|
||||
|
||||
public FullDataSetRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, Func<TEntity, TId> getEntityId, Func<IEnumerable<TEntity>> getAllFromRepo, bool expires)
|
||||
{
|
||||
_runtimeCache = runtimeCache;
|
||||
_getEntityId = getEntityId;
|
||||
_getAllFromRepo = getAllFromRepo;
|
||||
_expires = expires;
|
||||
}
|
||||
|
||||
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
|
||||
{
|
||||
return new FullDataSetRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _getEntityId, _getAllFromRepo, _expires);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
value = result.Value; // will not throw (safe lazy)
|
||||
var eh = value as ExceptionHolder;
|
||||
if (eh != null) throw new Exception("Exception while creating a value.", eh.Exception); // throw once!
|
||||
if (eh != null) throw eh.Exception; // throw once!
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,97 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal interface IRepositoryCachePolicy<TEntity, TId>
|
||||
internal interface IRepositoryCachePolicy<TEntity, TId> : IDisposable
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
// note:
|
||||
// at the moment each repository instance creates its corresponding cache policy instance
|
||||
// we could reduce allocations by using static cache policy instances but then we would need
|
||||
// to modify all methods here to pass the repository and cache eg:
|
||||
//
|
||||
// TEntity Get(TRepository repository, IRuntimeCacheProvider cache, TId id);
|
||||
//
|
||||
// it is not *that* complicated but then RepositoryBase needs to have a TRepository generic
|
||||
// type parameter and it all becomes convoluted - keeping it simple for the time being.
|
||||
|
||||
/// <summary>
|
||||
/// Creates a scoped version of this cache policy.
|
||||
/// </summary>
|
||||
/// <param name="runtimeCache">The global isolated runtime cache for this policy.</param>
|
||||
/// <param name="scope">The scope.</param>
|
||||
/// <remarks>When a policy is scoped, it means that it has been created with a scoped
|
||||
/// isolated runtime cache, and now it needs to be wrapped into something that can apply
|
||||
/// changes to the global isolated runtime cache.</remarks>
|
||||
IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an entity from the cache, else from the repository.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="performGet">The repository PerformGet method.</param>
|
||||
/// <param name="performGetAll">The repository PerformGetAll method.</param>
|
||||
/// <returns>The entity with the specified identifier, if it exits, else null.</returns>
|
||||
/// <remarks>First considers the cache then the repository.</remarks>
|
||||
TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an entity from the cache.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>The entity with the specified identifier, if it is in the cache already, else null.</returns>
|
||||
/// <remarks>Does not consider the repository at all.</remarks>
|
||||
TEntity GetCached(TId id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether an entity with a specified identifier exists.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <param name="performExists">The repository PerformExists method.</param>
|
||||
/// <param name="performGetAll">The repository PerformGetAll method.</param>
|
||||
/// <returns>A value indicating whether an entity with the specified identifier exists.</returns>
|
||||
/// <remarks>First considers the cache then the repository.</remarks>
|
||||
bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <param name="persistNew">The repository PersistNewItem method.</param>
|
||||
/// <remarks>Creates the entity in the repository, and updates the cache accordingly.</remarks>
|
||||
void Create(TEntity entity, Action<TEntity> persistNew);
|
||||
|
||||
/// <summary>
|
||||
/// Updates an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <param name="persistUpdated">The reopsitory PersistUpdatedItem method.</param>
|
||||
/// <remarks>Updates the entity in the repository, and updates the cache accordingly.</remarks>
|
||||
void Update(TEntity entity, Action<TEntity> persistUpdated);
|
||||
|
||||
/// <summary>
|
||||
/// Removes an entity.
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <param name="persistDeleted">The repository PersistDeletedItem method.</param>
|
||||
/// <remarks>Removes the entity from the repository and clears the cache.</remarks>
|
||||
void Delete(TEntity entity, Action<TEntity> persistDeleted);
|
||||
|
||||
/// <summary>
|
||||
/// Gets entities.
|
||||
/// </summary>
|
||||
/// <param name="ids">The identifiers.</param>
|
||||
/// <param name="performGetAll">The repository PerformGetAll method.</param>
|
||||
/// <returns>If <paramref name="ids"/> is empty, all entities, else the entities with the specified identifiers.</returns>
|
||||
/// <remarks>Get all the entities. Either from the cache or the repository depending on the implementation.</remarks>
|
||||
TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll);
|
||||
|
||||
/// <summary>
|
||||
/// Clears the entire cache.
|
||||
/// </summary>
|
||||
void ClearAll();
|
||||
TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
|
||||
TEntity Get(TId id);
|
||||
bool Exists(TId id, Func<TId, bool> getFromRepo);
|
||||
|
||||
void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
|
||||
void Remove(TEntity entity, Action<TEntity> persistMethod);
|
||||
TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal interface IRepositoryCachePolicyFactory<TEntity, TId> where TEntity : class, IAggregateRoot
|
||||
{
|
||||
IRepositoryCachePolicy<TEntity, TId> CreatePolicy();
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal class NoRepositoryCachePolicy<TEntity, TId> : IRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private static readonly NoRepositoryCachePolicy<TEntity, TId> StaticInstance = new NoRepositoryCachePolicy<TEntity, TId>();
|
||||
|
||||
private NoRepositoryCachePolicy()
|
||||
{ }
|
||||
|
||||
public static NoRepositoryCachePolicy<TEntity, TId> Instance { get { return StaticInstance; } }
|
||||
|
||||
public IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
return performGet(id);
|
||||
}
|
||||
|
||||
public TEntity GetCached(TId id)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
return performExists(id);
|
||||
}
|
||||
|
||||
public void Create(TEntity entity, Action<TEntity> persistNew)
|
||||
{
|
||||
persistNew(entity);
|
||||
}
|
||||
|
||||
public void Update(TEntity entity, Action<TEntity> persistUpdated)
|
||||
{
|
||||
persistUpdated(entity);
|
||||
}
|
||||
|
||||
public void Delete(TEntity entity, Action<TEntity> persistDeleted)
|
||||
{
|
||||
persistDeleted(entity);
|
||||
}
|
||||
|
||||
public TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
return performGetAll(ids).ToArray();
|
||||
}
|
||||
|
||||
public void ClearAll()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates cache policies
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
internal class OnlySingleItemsRepositoryCachePolicyFactory<TEntity, TId> : IRepositoryCachePolicyFactory<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly RepositoryCachePolicyOptions _options;
|
||||
|
||||
public OnlySingleItemsRepositoryCachePolicyFactory(IRuntimeCacheProvider runtimeCache, RepositoryCachePolicyOptions options)
|
||||
{
|
||||
_runtimeCache = runtimeCache;
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public virtual IRepositoryCachePolicy<TEntity, TId> CreatePolicy()
|
||||
{
|
||||
return new SingleItemsOnlyRepositoryCachePolicy<TEntity, TId>(_runtimeCache, _options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +1,48 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for repository cache policies.
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier.</typeparam>
|
||||
internal abstract class RepositoryCachePolicyBase<TEntity, TId> : IRepositoryCachePolicy<TEntity, TId>
|
||||
internal abstract class RepositoryCachePolicyBase<TEntity, TId> : DisposableObject, IRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private Action _action;
|
||||
|
||||
protected RepositoryCachePolicyBase(IRuntimeCacheProvider cache)
|
||||
{
|
||||
if (cache == null) throw new ArgumentNullException("cache");
|
||||
if (cache == null) throw new ArgumentNullException("cache");
|
||||
|
||||
Cache = cache;
|
||||
}
|
||||
|
||||
public abstract IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope);
|
||||
|
||||
protected IRuntimeCacheProvider Cache { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll);
|
||||
/// <summary>
|
||||
/// The disposal performs the caching
|
||||
/// </summary>
|
||||
protected override void DisposeResources()
|
||||
{
|
||||
if (_action != null)
|
||||
{
|
||||
_action();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract TEntity GetCached(TId id);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void Create(TEntity entity, Action<TEntity> persistNew);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void Update(TEntity entity, Action<TEntity> persistUpdated);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void Delete(TEntity entity, Action<TEntity> persistDeleted);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract void ClearAll();
|
||||
/// <summary>
|
||||
/// Sets the action to execute on disposal
|
||||
/// </summary>
|
||||
/// <param name="action"></param>
|
||||
protected void SetCacheAction(Action action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public abstract TEntity Get(TId id, Func<TId, TEntity> getFromRepo);
|
||||
public abstract TEntity Get(TId id);
|
||||
public abstract bool Exists(TId id, Func<TId, bool> getFromRepo);
|
||||
public abstract void CreateOrUpdate(TEntity entity, Action<TEntity> persistMethod);
|
||||
public abstract void Remove(TEntity entity, Action<TEntity> persistMethod);
|
||||
public abstract TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> getFromRepo);
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,6 @@ using System;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies how a repository cache policy should cache entities.
|
||||
/// </summary>
|
||||
internal class RepositoryCachePolicyOptions
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal class ScopedRepositoryCachePolicy<TEntity, TId> : IRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IRepositoryCachePolicy<TEntity, TId> _cachePolicy;
|
||||
private readonly IRuntimeCacheProvider _globalIsolatedCache;
|
||||
private readonly IScope _scope;
|
||||
|
||||
public ScopedRepositoryCachePolicy(IRepositoryCachePolicy<TEntity, TId> cachePolicy, IRuntimeCacheProvider globalIsolatedCache, IScope scope)
|
||||
{
|
||||
_cachePolicy = cachePolicy;
|
||||
_globalIsolatedCache = globalIsolatedCache;
|
||||
_scope = scope;
|
||||
}
|
||||
|
||||
public IRepositoryCachePolicy<TEntity, TId> Scoped(IRuntimeCacheProvider runtimeCache, IScope scope)
|
||||
{
|
||||
throw new InvalidOperationException(); // obviously
|
||||
}
|
||||
|
||||
public TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
// loads into the local cache only, ok for now
|
||||
return _cachePolicy.Get(id, performGet, performGetAll);
|
||||
}
|
||||
|
||||
public TEntity GetCached(TId id)
|
||||
{
|
||||
// loads into the local cache only, ok for now
|
||||
return _cachePolicy.GetCached(id);
|
||||
}
|
||||
|
||||
public bool Exists(TId id, Func<TId, bool> performExists, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
// loads into the local cache only, ok for now
|
||||
return _cachePolicy.Exists(id, performExists, performGetAll);
|
||||
}
|
||||
|
||||
public void Create(TEntity entity, Action<TEntity> persistNew)
|
||||
{
|
||||
// writes into the local cache
|
||||
_cachePolicy.Create(entity, persistNew);
|
||||
}
|
||||
|
||||
public void Update(TEntity entity, Action<TEntity> persistUpdated)
|
||||
{
|
||||
// writes into the local cache
|
||||
_cachePolicy.Update(entity, persistUpdated);
|
||||
}
|
||||
|
||||
public void Delete(TEntity entity, Action<TEntity> persistDeleted)
|
||||
{
|
||||
// deletes the local cache
|
||||
_cachePolicy.Delete(entity, persistDeleted);
|
||||
}
|
||||
|
||||
public TEntity[] GetAll(TId[] ids, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
// loads into the local cache only, ok for now
|
||||
return _cachePolicy.GetAll(ids, performGetAll);
|
||||
}
|
||||
|
||||
public void ClearAll()
|
||||
{
|
||||
// clears the local cache
|
||||
_cachePolicy.ClearAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,24 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Collections;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a special policy that does not cache the result of GetAll.
|
||||
/// A caching policy that ignores all caches for GetAll - it will only cache calls for individual items
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity">The type of the entity.</typeparam>
|
||||
/// <typeparam name="TId">The type of the identifier.</typeparam>
|
||||
/// <remarks>
|
||||
/// <para>Overrides the default repository cache policy and does not writes the result of GetAll
|
||||
/// to cache, but only the result of individual Gets. It does read the cache for GetAll, though.</para>
|
||||
/// <para>Used by DictionaryRepository.</para>
|
||||
/// </remarks>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
internal class SingleItemsOnlyRepositoryCachePolicy<TEntity, TId> : DefaultRepositoryCachePolicy<TEntity, TId>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
public SingleItemsOnlyRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options)
|
||||
: base(cache, options)
|
||||
{ }
|
||||
|
||||
protected override void InsertEntities(TId[] ids, TEntity[] entities)
|
||||
public SingleItemsOnlyRepositoryCachePolicy(IRuntimeCacheProvider cache, RepositoryCachePolicyOptions options) : base(cache, options)
|
||||
{
|
||||
// nop
|
||||
}
|
||||
|
||||
protected override void SetCacheAction(TId[] ids, TEntity[] entityCollection)
|
||||
{
|
||||
//no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,6 @@ namespace Umbraco.Core
|
||||
private static readonly ICacheProvider NullRequestCache = new NullCacheProvider();
|
||||
private static readonly ICacheProvider NullStaticCache = new NullCacheProvider();
|
||||
private static readonly IRuntimeCacheProvider NullRuntimeCache = new NullCacheProvider();
|
||||
private static readonly IsolatedRuntimeCache NullIsolatedCache = new IsolatedRuntimeCache(_ => NullRuntimeCache);
|
||||
private static readonly CacheHelper NullCache = new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, NullIsolatedCache);
|
||||
|
||||
public static CacheHelper NoCache { get { return NullCache; } }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a cache helper with disabled caches
|
||||
@@ -35,10 +31,7 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
public static CacheHelper CreateDisabledCacheHelper()
|
||||
{
|
||||
// do *not* return NoCache
|
||||
// NoCache is a special instance that is detected by RepositoryBase and disables all cache policies
|
||||
// CreateDisabledCacheHelper is used in tests to use no cache, *but* keep all cache policies
|
||||
return new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, NullIsolatedCache);
|
||||
return new CacheHelper(NullRuntimeCache, NullStaticCache, NullRequestCache, new IsolatedRuntimeCache(t => NullRuntimeCache));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
||||
internal class UmbracoUdiTypeAttribute : Attribute
|
||||
{
|
||||
public string UdiType { get; private set; }
|
||||
|
||||
public UmbracoUdiTypeAttribute(string udiType)
|
||||
{
|
||||
UdiType = udiType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using ClientDependency.Core.CompositeFiles.Providers;
|
||||
using ClientDependency.Core.Config;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// A utility class for working with CDF config and cache files - use sparingly!
|
||||
/// </summary>
|
||||
public class ClientDependencyConfiguration
|
||||
{
|
||||
internal class ClientDependencyConfiguration
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly string _fileName;
|
||||
@@ -28,7 +21,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Changes the version number in ClientDependency.config to a random value to avoid stale caches
|
||||
/// </summary>
|
||||
public bool IncreaseVersionNumber()
|
||||
internal bool IncreaseVersionNumber()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -56,55 +49,5 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the temporary files stored for the ClientDependency folder
|
||||
/// </summary>
|
||||
/// <param name="currentHttpContext"></param>
|
||||
public bool ClearTempFiles(HttpContextBase currentHttpContext)
|
||||
{
|
||||
var cdfTempDirectories = new HashSet<string>();
|
||||
foreach (BaseCompositeFileProcessingProvider provider in ClientDependencySettings.Instance
|
||||
.CompositeFileProcessingProviderCollection)
|
||||
{
|
||||
var path = provider.CompositeFilePath.FullName;
|
||||
cdfTempDirectories.Add(path);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var fullPath = currentHttpContext.Server.MapPath(XmlFileMapper.FileMapVirtualFolder);
|
||||
if (fullPath != null)
|
||||
{
|
||||
cdfTempDirectories.Add(fullPath);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//invalid path format or something... try/catch to be safe
|
||||
LogHelper.Error<ClientDependencyConfiguration>("Could not get path from ClientDependency.config", ex);
|
||||
}
|
||||
|
||||
var success = true;
|
||||
foreach (var directory in cdfTempDirectories)
|
||||
{
|
||||
var directoryInfo = new DirectoryInfo(directory);
|
||||
if (directoryInfo.Exists == false)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
directoryInfo.Delete(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Something could be locking the directory or the was another error, making sure we don't break the upgrade installer
|
||||
LogHelper.Error<ClientDependencyConfiguration>("Could not clear temp files", ex);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
internal static class CoreDebugExtensions
|
||||
{
|
||||
private static CoreDebug _coreDebug;
|
||||
|
||||
public static CoreDebug CoreDebug(this UmbracoConfig config)
|
||||
{
|
||||
return _coreDebug ?? (_coreDebug = new CoreDebug());
|
||||
}
|
||||
}
|
||||
|
||||
internal class CoreDebug
|
||||
{
|
||||
public CoreDebug()
|
||||
{
|
||||
var appSettings = System.Configuration.ConfigurationManager.AppSettings;
|
||||
LogUncompletedScopes = string.Equals("true", appSettings["Umbraco.CoreDebug.LogUncompletedScopes"], StringComparison.OrdinalIgnoreCase);
|
||||
DumpOnTimeoutThreadAbort = string.Equals("true", appSettings["Umbraco.CoreDebug.DumpOnTimeoutThreadAbort"], StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
// when true, Scope logs the stack trace for any scope that gets disposed without being completed.
|
||||
// this helps troubleshooting rogue scopes that we forget to complete
|
||||
public bool LogUncompletedScopes { get; private set; }
|
||||
// when true, the Logger creates a minidump of w3wp in ~/App_Data/MiniDump whenever it logs
|
||||
// an error due to a ThreadAbortException that is due to a timeout.
|
||||
public bool DumpOnTimeoutThreadAbort { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -212,7 +212,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
var settings = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName];
|
||||
var settings = ConfigurationManager.ConnectionStrings[UmbracoConnectionName];
|
||||
var connectionString = string.Empty;
|
||||
|
||||
if (settings != null)
|
||||
@@ -241,7 +241,10 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO: Move these to constants!
|
||||
public const string UmbracoConnectionName = "umbracoDbDSN";
|
||||
public const string UmbracoMigrationName = "Umbraco";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration status. This will return the version number of the currently installed umbraco instance.
|
||||
@@ -517,42 +520,12 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
internal static bool ContentCacheXmlStoredInCodeGen
|
||||
{
|
||||
get { return LocalTempStorageLocation == LocalTempStorage.AspNetTemp; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is the location type to store temporary files such as cache files or other localized files for a given machine
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Currently used for the xml cache file and the plugin cache files
|
||||
/// </remarks>
|
||||
internal static LocalTempStorage LocalTempStorageLocation
|
||||
{
|
||||
get
|
||||
{
|
||||
//there's a bunch of backwards compat config checks here....
|
||||
|
||||
//This is the current one
|
||||
if (ConfigurationManager.AppSettings.ContainsKey("umbracoLocalTempStorage"))
|
||||
{
|
||||
return Enum<LocalTempStorage>.Parse(ConfigurationManager.AppSettings["umbracoLocalTempStorage"]);
|
||||
}
|
||||
|
||||
//This one is old
|
||||
if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLStorage"))
|
||||
{
|
||||
return Enum<LocalTempStorage>.Parse(ConfigurationManager.AppSettings["umbracoContentXMLStorage"]);
|
||||
}
|
||||
|
||||
//This one is older
|
||||
if (ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLUseLocalTemp"))
|
||||
{
|
||||
return bool.Parse(ConfigurationManager.AppSettings["umbracoContentXMLUseLocalTemp"])
|
||||
? LocalTempStorage.AspNetTemp
|
||||
: LocalTempStorage.Default;
|
||||
}
|
||||
return LocalTempStorage.Default;
|
||||
{
|
||||
//defaults to false
|
||||
return ConfigurationManager.AppSettings.ContainsKey("umbracoContentXMLUseLocalTemp")
|
||||
&& bool.Parse(ConfigurationManager.AppSettings["umbracoContentXMLUseLocalTemp"]); //default to false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
internal enum LocalTempStorage
|
||||
{
|
||||
Default,
|
||||
AspNetTemp,
|
||||
EnvironmentTemp
|
||||
}
|
||||
}
|
||||
@@ -139,12 +139,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
internal CommaDelimitedConfigurationElement DisallowedUploadFiles
|
||||
{
|
||||
get { return GetOptionalDelimitedElement("disallowedUploadFiles", new[] {"ashx", "aspx", "ascx", "config", "cshtml", "vbhtml", "asmx", "air", "axd"}); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("allowedUploadFiles")]
|
||||
internal CommaDelimitedConfigurationElement AllowedUploadFiles
|
||||
{
|
||||
get { return GetOptionalDelimitedElement("allowedUploadFiles", new string[0]); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("cloneXmlContent")]
|
||||
@@ -165,12 +159,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return GetOptionalTextElement("defaultDocumentTypeProperty", "Textstring"); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("showDeprecatedPropertyEditors")]
|
||||
internal InnerTextConfigurationElement<bool> ShowDeprecatedPropertyEditors
|
||||
{
|
||||
get { return GetOptionalTextElement("showDeprecatedPropertyEditors", false); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("EnableInheritedDocumentTypes")]
|
||||
internal InnerTextConfigurationElement<bool> EnableInheritedDocumentTypes
|
||||
{
|
||||
@@ -183,18 +171,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return GetOptionalTextElement("EnableInheritedMediaTypes", true); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("EnablePropertyValueConverters")]
|
||||
internal InnerTextConfigurationElement<bool> EnablePropertyValueConverters
|
||||
{
|
||||
get { return GetOptionalTextElement("EnablePropertyValueConverters", false); }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("loginBackgroundImage")]
|
||||
internal InnerTextConfigurationElement<string> LoginBackgroundImage
|
||||
{
|
||||
get { return GetOptionalTextElement("loginBackgroundImage", string.Empty); }
|
||||
}
|
||||
|
||||
string IContentSection.NotificationEmailAddress
|
||||
{
|
||||
get { return Notifications.NotificationEmailAddress; }
|
||||
@@ -313,11 +289,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
IEnumerable<string> IContentSection.DisallowedUploadFiles
|
||||
{
|
||||
get { return DisallowedUploadFiles; }
|
||||
}
|
||||
|
||||
IEnumerable<string> IContentSection.AllowedUploadFiles
|
||||
{
|
||||
get { return AllowedUploadFiles; }
|
||||
}
|
||||
|
||||
bool IContentSection.CloneXmlContent
|
||||
@@ -335,11 +306,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return DefaultDocumentTypeProperty; }
|
||||
}
|
||||
|
||||
bool IContentSection.ShowDeprecatedPropertyEditors
|
||||
{
|
||||
get { return ShowDeprecatedPropertyEditors; }
|
||||
}
|
||||
|
||||
bool IContentSection.EnableInheritedDocumentTypes
|
||||
{
|
||||
get { return EnableInheritedDocumentTypes; }
|
||||
@@ -349,14 +315,5 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
get { return EnableInheritedMediaTypes; }
|
||||
}
|
||||
bool IContentSection.EnablePropertyValueConverters
|
||||
{
|
||||
get { return EnablePropertyValueConverters; }
|
||||
}
|
||||
|
||||
string IContentSection.LoginBackgroundImage
|
||||
{
|
||||
get { return LoginBackgroundImage; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
public static class ContentSectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if file extension is allowed for upload based on (optional) white list and black list
|
||||
/// held in settings.
|
||||
/// Allow upload if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted.
|
||||
/// </summary>
|
||||
public static bool IsFileAllowedForUpload(this IContentSection contentSection, string extension)
|
||||
{
|
||||
return contentSection.AllowedUploadFiles.Any(x => x.InvariantEquals(extension)) ||
|
||||
(contentSection.AllowedUploadFiles.Any() == false &&
|
||||
contentSection.DisallowedUploadFiles.Any(x => x.InvariantEquals(extension)) == false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,9 +52,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
MacroErrorBehaviour MacroErrorBehaviour { get; }
|
||||
|
||||
IEnumerable<string> DisallowedUploadFiles { get; }
|
||||
|
||||
IEnumerable<string> AllowedUploadFiles { get; }
|
||||
IEnumerable<string> DisallowedUploadFiles { get; }
|
||||
|
||||
bool CloneXmlContent { get; }
|
||||
|
||||
@@ -62,18 +60,8 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
string DefaultDocumentTypeProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The default for this is false but if you would like deprecated property editors displayed
|
||||
/// in the data type editor you can enable this
|
||||
/// </summary>
|
||||
bool ShowDeprecatedPropertyEditors { get; }
|
||||
|
||||
bool EnableInheritedDocumentTypes { get; }
|
||||
|
||||
bool EnableInheritedMediaTypes { get; }
|
||||
|
||||
bool EnablePropertyValueConverters { get; }
|
||||
|
||||
string LoginBackgroundImage { get; }
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
Guid Id { get; }
|
||||
string RepositoryUrl { get; }
|
||||
string WebServiceUrl { get; }
|
||||
bool HasCustomWebServiceUrl { get; }
|
||||
string RestApiUrl { get; }
|
||||
bool HasCustomWebServiceUrl { get; }
|
||||
}
|
||||
}
|
||||
@@ -12,8 +12,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
bool ConvertUrlsToAscii { get; }
|
||||
|
||||
bool TryConvertUrlsToAscii { get; }
|
||||
|
||||
IEnumerable<IChar> CharCollection { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
{
|
||||
public static class RepositoryConfigExtensions
|
||||
{
|
||||
//Our package repo
|
||||
private static readonly Guid RepoGuid = new Guid("65194810-1f85-11dd-bd0b-0800200c9a66");
|
||||
|
||||
public static IRepository GetDefault(this IRepositoriesSection repos)
|
||||
{
|
||||
var found = repos.Repositories.FirstOrDefault(x => x.Id == RepoGuid);
|
||||
if (found == null)
|
||||
throw new InvalidOperationException("No default package repository found with id " + RepoGuid);
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,16 +38,9 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get
|
||||
{
|
||||
var prop = Properties["webserviceurl"];
|
||||
return (string) prop.DefaultValue != (string) this[prop];
|
||||
var repoUrl = this[prop] as ConfigurationElement;
|
||||
return (repoUrl != null && repoUrl.ElementInformation.IsPresent);
|
||||
}
|
||||
}
|
||||
|
||||
[ConfigurationProperty("restapiurl", DefaultValue = "https://our.umbraco.org/webapi/packages/v1")]
|
||||
public string RestApiUrl
|
||||
{
|
||||
get { return (string)base["restapiurl"]; }
|
||||
set { base["restapiurl"] = value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -111,12 +111,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
|
||||
bool IRequestHandlerSection.ConvertUrlsToAscii
|
||||
{
|
||||
get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("true"); }
|
||||
}
|
||||
|
||||
bool IRequestHandlerSection.TryConvertUrlsToAscii
|
||||
{
|
||||
get { return UrlReplacing.ConvertUrlsToAscii.InvariantEquals("try"); }
|
||||
get { return UrlReplacing.ConvertUrlsToAscii; }
|
||||
}
|
||||
|
||||
IEnumerable<IChar> IRequestHandlerSection.CharCollection
|
||||
|
||||
@@ -11,10 +11,10 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
|
||||
get { return (bool) base["removeDoubleDashes"]; }
|
||||
}
|
||||
|
||||
[ConfigurationProperty("toAscii", DefaultValue = "false")]
|
||||
internal string ConvertUrlsToAscii
|
||||
[ConfigurationProperty("toAscii", DefaultValue = false)]
|
||||
internal bool ConvertUrlsToAscii
|
||||
{
|
||||
get { return (string) base["toAscii"]; }
|
||||
get { return (bool)base["toAscii"]; }
|
||||
}
|
||||
|
||||
[ConfigurationCollection(typeof(CharCollection), AddItemName = "char")]
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("7.6.12");
|
||||
private static readonly Version Version = new Version("7.5.7");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -33,9 +33,9 @@ namespace Umbraco.Core.Configuration
|
||||
public static SemVersion GetSemanticVersion()
|
||||
{
|
||||
return new SemVersion(
|
||||
Current.Major,
|
||||
Current.Major,
|
||||
Current.Minor,
|
||||
Current.Build,
|
||||
Current.Build,
|
||||
CurrentComment.IsNullOrWhiteSpace() ? null : CurrentComment,
|
||||
Current.Revision > 0 ? Current.Revision.ToInvariantString() : null);
|
||||
}
|
||||
|
||||
@@ -112,15 +112,9 @@
|
||||
|
||||
public const string Languages = "languages";
|
||||
|
||||
public const string PartialViews = "partialViews";
|
||||
|
||||
public const string PartialViewMacros = "partialViewMacros";
|
||||
|
||||
public const string Scripts = "scripts";
|
||||
|
||||
//TODO: Fill in the rest!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -4,8 +4,7 @@ using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
|
||||
public static partial class Constants
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for property-type alias conventions that are used within the Umbraco core.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
public static class DatabaseProviders
|
||||
{
|
||||
public const string SqlCe = "System.Data.SqlServerCe.4.0";
|
||||
public const string SqlServer = "System.Data.SqlClient";
|
||||
public const string MySql = "MySql.Data.MySqlClient";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the valid selector values.
|
||||
/// </summary>
|
||||
public static class DeploySelector
|
||||
{
|
||||
public const string This = "this";
|
||||
public const string ThisAndChildren = "this-and-children";
|
||||
public const string ThisAndDescendants = "this-and-descendants";
|
||||
public const string ChildrenOfThis = "children";
|
||||
public const string DescendantsOfThis = "descendants";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,11 +89,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string Media = "B796F64C-1F99-4FFB-B886-4BF4BC011A9C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Document object.
|
||||
/// </summary>
|
||||
public static readonly Guid MediaGuid = new Guid(Media);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Media Recycle Bin.
|
||||
/// </summary>
|
||||
@@ -114,21 +109,11 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string Member = "39EB0F98-B348-42A1-8662-E7EB18487560";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Media Type object.
|
||||
/// </summary>
|
||||
public static readonly Guid MemberGuid = new Guid(Member);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Group object.
|
||||
/// </summary>
|
||||
public const string MemberGroup = "366E63B9-880F-4E13-A61C-98069B029728";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Group object.
|
||||
/// </summary>
|
||||
public static readonly Guid MemberGroupGuid = new Guid(MemberGroup);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Type object.
|
||||
/// </summary>
|
||||
@@ -158,11 +143,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string Template = "6FBDE604-4178-42CE-A10B-8A2600A2F07D";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Template object.
|
||||
/// </summary>
|
||||
public static readonly Guid TemplateTypeGuid = new Guid(Template);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Lock object.
|
||||
/// </summary>
|
||||
@@ -172,66 +152,6 @@ namespace Umbraco.Core
|
||||
/// Guid for a Lock object.
|
||||
/// </summary>
|
||||
public static readonly Guid LockObjectGuid = new Guid(LockObject);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a relation type.
|
||||
/// </summary>
|
||||
public const string RelationType = "B1988FAD-8675-4F47-915A-B3A602BC5D8D";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a relation type.
|
||||
/// </summary>
|
||||
public static readonly Guid RelationTypeGuid = new Guid(RelationType);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms Form.
|
||||
/// </summary>
|
||||
public const string FormsForm = "F5A9F787-6593-46F0-B8FF-BFD9BCA9F6BB";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms Form.
|
||||
/// </summary>
|
||||
public static readonly Guid FormsFormGuid = new Guid(FormsForm);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms PreValue Source.
|
||||
/// </summary>
|
||||
public const string FormsPreValue = "42D7BF9B-A362-4FEE-B45A-674D5C064B70";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms PreValue Source.
|
||||
/// </summary>
|
||||
public static readonly Guid FormsPreValueGuid = new Guid(FormsPreValue);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms DataSource.
|
||||
/// </summary>
|
||||
public const string FormsDataSource = "CFED6CE4-9359-443E-9977-9956FEB1D867";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms DataSource.
|
||||
/// </summary>
|
||||
public static readonly Guid FormsDataSourceGuid = new Guid(FormsDataSource);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Language.
|
||||
/// </summary>
|
||||
public const string Language = "6B05D05B-EC78-49BE-A4E4-79E274F07A77";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Forms DataSource.
|
||||
/// </summary>
|
||||
public static readonly Guid LanguageGuid = new Guid(Language);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for an Identifier Reservation.
|
||||
/// </summary>
|
||||
public const string IdReservation = "92849B1E-3904-4713-9356-F646F87C25F4";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for an Identifier Reservation.
|
||||
/// </summary>
|
||||
public static readonly Guid IdReservationGuid = new Guid(IdReservation);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,14 +42,10 @@ namespace Umbraco.Core
|
||||
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
|
||||
public const string ContentPicker = "158AA029-24ED-4948-939E-C3DA209E5FBA";
|
||||
|
||||
|
||||
[Obsolete("This is an obsoleted content picker, use ContentPicker2Alias instead")]
|
||||
public const string ContentPickerAlias = "Umbraco.ContentPickerAlias";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Content Picker datatype.
|
||||
/// </summary>
|
||||
public const string ContentPicker2Alias = "Umbraco.ContentPicker2";
|
||||
public const string ContentPickerAlias = "Umbraco.ContentPickerAlias";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Date datatype.
|
||||
@@ -196,15 +192,11 @@ namespace Umbraco.Core
|
||||
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
|
||||
public const string MediaPicker = "EAD69342-F06D-4253-83AC-28000225583B";
|
||||
|
||||
[Obsolete("This is an obsoleted picker, use MediaPicker2Alias instead")]
|
||||
public const string MediaPickerAlias = "Umbraco.MediaPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Media Picker datatype.
|
||||
/// </summary>
|
||||
public const string MediaPicker2Alias = "Umbraco.MediaPicker2";
|
||||
public const string MediaPickerAlias = "Umbraco.MediaPicker";
|
||||
|
||||
[Obsolete("This is an obsoleted picker, use MediaPicker2Alias instead")]
|
||||
public const string MultipleMediaPickerAlias = "Umbraco.MultipleMediaPicker";
|
||||
|
||||
/// <summary>
|
||||
@@ -213,32 +205,26 @@ namespace Umbraco.Core
|
||||
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
|
||||
public const string MemberPicker = "39F533E4-0551-4505-A64B-E0425C5CE775";
|
||||
|
||||
[Obsolete("This is an obsoleted picker, use MemberPicker2Alias instead")]
|
||||
public const string MemberPickerAlias = "Umbraco.MemberPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Member Picker datatype.
|
||||
/// </summary>
|
||||
public const string MemberPicker2Alias = "Umbraco.MemberPicker2";
|
||||
public const string MemberPickerAlias = "Umbraco.MemberPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Member Group Picker datatype.
|
||||
/// </summary>
|
||||
public const string MemberGroupPickerAlias = "Umbraco.MemberGroupPicker";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Multi-Node Tree Picker datatype
|
||||
/// </summary>
|
||||
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
|
||||
public const string MultiNodeTreePicker = "7E062C13-7C41-4AD9-B389-41D88AEEF87C";
|
||||
|
||||
[Obsolete("This is an obsoleted picker, use MultiNodeTreePicker2Alias instead")]
|
||||
public const string MultiNodeTreePickerAlias = "Umbraco.MultiNodeTreePicker";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Multi-Node Tree Picker datatype
|
||||
/// </summary>
|
||||
public const string MultiNodeTreePicker2Alias = "Umbraco.MultiNodeTreePicker2";
|
||||
public const string MultiNodeTreePickerAlias = "Umbraco.MultiNodeTreePicker";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Multiple Textstring datatype.
|
||||
@@ -289,14 +275,11 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
[Obsolete("GUIDs are no longer used to reference Property Editors, use the Alias constant instead. This will be removed in future versions")]
|
||||
public const string RelatedLinks = "71B8AD1A-8DC2-425C-B6B8-FAA158075E63";
|
||||
|
||||
[Obsolete("This is an obsoleted picker, use RelatedLinks2Alias instead")]
|
||||
public const string RelatedLinksAlias = "Umbraco.RelatedLinks";
|
||||
|
||||
/// <summary>
|
||||
/// Alias for the Related Links property editor.
|
||||
/// Alias for the Related Links datatype.
|
||||
/// </summary>
|
||||
public const string RelatedLinks2Alias = "Umbraco.RelatedLinks2";
|
||||
public const string RelatedLinksAlias = "Umbraco.RelatedLinks";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Slider datatype.
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
public static class Security
|
||||
{
|
||||
|
||||
public const string BackOfficeAuthenticationType = "UmbracoBackOffice";
|
||||
public const string BackOfficeExternalAuthenticationType = "UmbracoExternalCookie";
|
||||
public const string BackOfficeExternalCookieName = "UMB_EXTLOGIN";
|
||||
public const string BackOfficeTokenAuthenticationType = "UmbracoBackOfficeToken";
|
||||
public const string BackOfficeTwoFactorAuthenticationType = "UmbracoTwoFactorCookie";
|
||||
|
||||
internal const string EmptyPasswordPrefix = "___UIDEMPTYPWORD__";
|
||||
|
||||
/// <summary>
|
||||
/// The prefix used for external identity providers for their authentication type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default we don't want to interfere with front-end external providers and their default setup, for back office the
|
||||
/// providers need to be setup differently and each auth type for the back office will be prefixed with this value
|
||||
/// </remarks>
|
||||
public const string BackOfficeExternalAuthenticationTypePrefix = "Umbraco.";
|
||||
|
||||
public const string StartContentNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startcontentnode";
|
||||
public const string StartMediaNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startmedianode";
|
||||
public const string AllowedApplicationsClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/allowedapp";
|
||||
public const string SessionIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/sessionid";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,9 +26,15 @@
|
||||
public const int DefaultMediaListViewDataTypeId = -96;
|
||||
public const int DefaultMembersListViewDataTypeId = -97;
|
||||
|
||||
public const string UmbracoConnectionName = "umbracoDbDSN";
|
||||
public const string UmbracoMigrationName = "Umbraco";
|
||||
// identifiers for lock objects
|
||||
public const int ServersLock = -331;
|
||||
}
|
||||
|
||||
public static class DatabaseProviders
|
||||
{
|
||||
public const string SqlCe = "System.Data.SqlServerCe.4.0";
|
||||
public const string SqlServer = "System.Data.SqlClient";
|
||||
public const string MySql = "MySql.Data.MySqlClient";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,30 @@ namespace Umbraco.Core
|
||||
public const string AuthCookieName = "UMB_UCONTEXT";
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class Security
|
||||
{
|
||||
|
||||
public const string BackOfficeAuthenticationType = "UmbracoBackOffice";
|
||||
public const string BackOfficeExternalAuthenticationType = "UmbracoExternalCookie";
|
||||
public const string BackOfficeExternalCookieName = "UMB_EXTLOGIN";
|
||||
public const string BackOfficeTokenAuthenticationType = "UmbracoBackOfficeToken";
|
||||
public const string BackOfficeTwoFactorAuthenticationType = "UmbracoTwoFactorCookie";
|
||||
|
||||
/// <summary>
|
||||
/// The prefix used for external identity providers for their authentication type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// By default we don't want to interfere with front-end external providers and their default setup, for back office the
|
||||
/// providers need to be setup differently and each auth type for the back office will be prefixed with this value
|
||||
/// </remarks>
|
||||
public const string BackOfficeExternalAuthenticationTypePrefix = "Umbraco.";
|
||||
|
||||
public const string StartContentNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startcontentnode";
|
||||
public const string StartMediaNodeIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/startmedianode";
|
||||
public const string AllowedApplicationsClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/allowedapp";
|
||||
public const string SessionIdClaimType = "http://umbraco.org/2015/02/identity/claims/backoffice/sessionid";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using AutoMapper;
|
||||
@@ -29,7 +28,6 @@ using Umbraco.Core.PropertyEditors.ValueConverters;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Macros;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Core.Strings;
|
||||
@@ -107,14 +105,11 @@ namespace Umbraco.Core
|
||||
LegacyParameterEditorAliasConverter.CreateMappingsForCoreEditors();
|
||||
|
||||
//create database and service contexts for the app context
|
||||
var dbFactory = new DefaultDatabaseFactory(Constants.System.UmbracoConnectionName, ProfilingLogger.Logger);
|
||||
var dbFactory = new DefaultDatabaseFactory(GlobalSettings.UmbracoConnectionName, ProfilingLogger.Logger);
|
||||
Database.Mapper = new PetaPocoMapper();
|
||||
|
||||
var scopeProvider = new ScopeProvider(dbFactory);
|
||||
dbFactory.ScopeProvider = scopeProvider;
|
||||
|
||||
var dbContext = new DatabaseContext(
|
||||
scopeProvider,
|
||||
dbFactory,
|
||||
ProfilingLogger.Logger,
|
||||
SqlSyntaxProviders.CreateDefault(ProfilingLogger.Logger));
|
||||
|
||||
@@ -122,7 +117,7 @@ namespace Umbraco.Core
|
||||
dbContext.Initialize();
|
||||
|
||||
//get the service context
|
||||
var serviceContext = CreateServiceContext(dbContext, scopeProvider);
|
||||
var serviceContext = CreateServiceContext(dbContext, dbFactory);
|
||||
|
||||
//set property and singleton from response
|
||||
ApplicationContext.Current = ApplicationContext = CreateApplicationContext(dbContext, serviceContext);
|
||||
@@ -165,15 +160,17 @@ namespace Umbraco.Core
|
||||
/// Creates and returns the service context for the app
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="scopeProvider"></param>
|
||||
/// <param name="dbFactory"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual ServiceContext CreateServiceContext(DatabaseContext dbContext, IScopeProvider scopeProvider)
|
||||
protected virtual ServiceContext CreateServiceContext(DatabaseContext dbContext, IDatabaseFactory dbFactory)
|
||||
{
|
||||
//default transient factory
|
||||
var msgFactory = new TransientMessagesFactory();
|
||||
return new ServiceContext(
|
||||
new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()),
|
||||
new PetaPocoUnitOfWorkProvider(scopeProvider),
|
||||
new PetaPocoUnitOfWorkProvider(dbFactory),
|
||||
new FileUnitOfWorkProvider(),
|
||||
new PublishingStrategy(msgFactory, ProfilingLogger.Logger),
|
||||
ApplicationCache,
|
||||
ProfilingLogger.Logger,
|
||||
msgFactory);
|
||||
@@ -400,28 +397,6 @@ namespace Umbraco.Core
|
||||
if (ApplicationContext.IsConfigured == false) return;
|
||||
if (ApplicationContext.DatabaseContext.IsDatabaseConfigured == false) return;
|
||||
|
||||
// deal with localdb
|
||||
var databaseContext = ApplicationContext.DatabaseContext;
|
||||
var localdbex = new Regex(@"\(localdb\)\\([a-zA-Z0-9-_]+)(;|$)");
|
||||
var m = localdbex.Match(databaseContext.ConnectionString);
|
||||
if (m.Success)
|
||||
{
|
||||
var instanceName = m.Groups[1].Value;
|
||||
ProfilingLogger.Logger.Info<CoreBootManager>(string.Format("LocalDb instance \"{0}\"", instanceName));
|
||||
|
||||
var localDb = new LocalDb();
|
||||
if (localDb.IsAvailable == false)
|
||||
throw new UmbracoStartupFailedException("Umbraco cannot start. LocalDb is not available.");
|
||||
|
||||
if (localDb.InstanceExists(m.Groups[1].Value) == false)
|
||||
{
|
||||
if (localDb.CreateInstance(instanceName) == false)
|
||||
throw new UmbracoStartupFailedException(string.Format("Umbraco cannot start. LocalDb cannot create instance \"{0}\".", instanceName));
|
||||
if (localDb.StartInstance(instanceName) == false)
|
||||
throw new UmbracoStartupFailedException(string.Format("Umbraco cannot start. LocalDb cannot start instance \"{0}\".", instanceName));
|
||||
}
|
||||
}
|
||||
|
||||
//try now
|
||||
if (ApplicationContext.DatabaseContext.CanConnect)
|
||||
return;
|
||||
@@ -440,7 +415,7 @@ namespace Umbraco.Core
|
||||
|
||||
if (currentTry == 5)
|
||||
{
|
||||
throw new UmbracoStartupFailedException("Umbraco cannot start. A connection string is configured but Umbraco cannot connect to the database.");
|
||||
throw new UmbracoStartupFailedException("Umbraco cannot start. A connection string is configured but the Umbraco cannot connect to the database.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Data.SqlServerCe;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Xml.Linq;
|
||||
using Semver;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -13,7 +14,6 @@ using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Migrations;
|
||||
using Umbraco.Core.Persistence.Migrations.Initial;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Scoping;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -26,42 +26,31 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
public class DatabaseContext
|
||||
{
|
||||
internal readonly IScopeProviderInternal ScopeProvider;
|
||||
private readonly IDatabaseFactory _factory;
|
||||
private readonly ILogger _logger;
|
||||
private readonly SqlSyntaxProviders _syntaxProviders;
|
||||
private bool _configured;
|
||||
private readonly object _locker = new object();
|
||||
private string _connectionString;
|
||||
private string _providerName;
|
||||
private DatabaseSchemaResult _result;
|
||||
private DateTime? _connectionLastChecked;
|
||||
private DateTime? _connectionLastChecked = null;
|
||||
|
||||
/// <summary>
|
||||
/// The number of minutes to throttle the checks to CanConnect
|
||||
/// </summary>
|
||||
private const int ConnectionCheckMinutes = 1;
|
||||
|
||||
#region Compatibility with 7.5
|
||||
|
||||
// note: the ctors accepting IDatabaseFactory are here only for backward compatibility purpose
|
||||
//
|
||||
// problem: IDatabaseFactory2 adds the CreateNewDatabase() method which creates a new database
|
||||
// 'cos IDatabaseFactory CreateDatabase() is supposed to also manage the ambient thing. We
|
||||
// want to keep these ctors for backward compatibility reasons (in case ppl use them in tests)
|
||||
// so we need to create a scope provider (else nothing would work) and so we need a IDatabaseFactory2,
|
||||
// so...?
|
||||
// solution: wrap IDatabaseFactory and pretend we have a IDatabaseFactory2, it *should* work in most
|
||||
// cases but really, it depends on what ppl are doing in their tests... yet, cannot really see any
|
||||
// other way to do it?
|
||||
|
||||
[Obsolete("Use the constructor specifying all dependencies instead")]
|
||||
public DatabaseContext(IDatabaseFactory factory)
|
||||
: this(factory, LoggerResolver.Current.Logger, new SqlSyntaxProviders(new ISqlSyntaxProvider[]
|
||||
{
|
||||
new MySqlSyntaxProvider(LoggerResolver.Current.Logger),
|
||||
new SqlCeSyntaxProvider(),
|
||||
new SqlCeSyntaxProvider(),
|
||||
new SqlServerSyntaxProvider()
|
||||
}))
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
@@ -75,11 +64,7 @@ namespace Umbraco.Core
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
if (syntaxProviders == null) throw new ArgumentNullException("syntaxProviders");
|
||||
|
||||
var asDbFactory2 = factory as IDatabaseFactory2;
|
||||
ScopeProvider = asDbFactory2 == null
|
||||
? new ScopeProvider(new DatabaseFactoryWrapper(factory))
|
||||
: new ScopeProvider(asDbFactory2);
|
||||
|
||||
_factory = factory;
|
||||
_logger = logger;
|
||||
_syntaxProviders = syntaxProviders;
|
||||
}
|
||||
@@ -96,83 +81,7 @@ namespace Umbraco.Core
|
||||
_providerName = providerName;
|
||||
SqlSyntax = sqlSyntax;
|
||||
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
|
||||
|
||||
var asDbFactory2 = factory as IDatabaseFactory2;
|
||||
ScopeProvider = asDbFactory2 == null
|
||||
? new ScopeProvider(new DatabaseFactoryWrapper(factory))
|
||||
: new ScopeProvider(asDbFactory2);
|
||||
|
||||
_logger = logger;
|
||||
_configured = true;
|
||||
}
|
||||
|
||||
private class DatabaseFactoryWrapper : IDatabaseFactory2
|
||||
{
|
||||
private readonly IDatabaseFactory _factory;
|
||||
|
||||
public DatabaseFactoryWrapper(IDatabaseFactory factory)
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
public UmbracoDatabase CreateDatabase()
|
||||
{
|
||||
return _factory.CreateDatabase();
|
||||
}
|
||||
|
||||
public UmbracoDatabase CreateNewDatabase()
|
||||
{
|
||||
return CreateDatabase();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_factory.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[Obsolete("Use the constructor specifying all dependencies instead")]
|
||||
internal DatabaseContext(IScopeProviderInternal scopeProvider)
|
||||
: this(scopeProvider, LoggerResolver.Current.Logger, new SqlSyntaxProviders(new ISqlSyntaxProvider[]
|
||||
{
|
||||
new MySqlSyntaxProvider(LoggerResolver.Current.Logger),
|
||||
new SqlCeSyntaxProvider(),
|
||||
new SqlServerSyntaxProvider()
|
||||
}))
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor
|
||||
/// </summary>
|
||||
/// <param name="scopeProvider"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="syntaxProviders"></param>
|
||||
internal DatabaseContext(IScopeProviderInternal scopeProvider, ILogger logger, SqlSyntaxProviders syntaxProviders)
|
||||
{
|
||||
if (scopeProvider == null) throw new ArgumentNullException("scopeProvider");
|
||||
if (logger == null) throw new ArgumentNullException("logger");
|
||||
if (syntaxProviders == null) throw new ArgumentNullException("syntaxProviders");
|
||||
|
||||
ScopeProvider = scopeProvider;
|
||||
_logger = logger;
|
||||
_syntaxProviders = syntaxProviders;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a configured DatabaseContext
|
||||
/// </summary>
|
||||
/// <param name="scopeProvider"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <param name="sqlSyntax"></param>
|
||||
/// <param name="providerName"></param>
|
||||
internal DatabaseContext(IScopeProviderInternal scopeProvider, ILogger logger, ISqlSyntaxProvider sqlSyntax, string providerName)
|
||||
{
|
||||
_providerName = providerName;
|
||||
SqlSyntax = sqlSyntax;
|
||||
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
|
||||
ScopeProvider = scopeProvider;
|
||||
_factory = factory;
|
||||
_logger = logger;
|
||||
_configured = true;
|
||||
}
|
||||
@@ -180,27 +89,16 @@ namespace Umbraco.Core
|
||||
public ISqlSyntaxProvider SqlSyntax { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an "ambient" database for doing CRUD operations against custom tables that resides in the Umbraco database.
|
||||
/// Gets the <see cref="Database"/> object for doing CRUD operations
|
||||
/// against custom tables that resides in the Umbraco database.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Should not be used for operation against standard Umbraco tables; as services should be used instead.</para>
|
||||
/// <para>Gets or creates an "ambient" database that is either stored in http context + available for the whole
|
||||
/// request + auto-disposed at the end of the request, or stored in call context if there is no http context - in which
|
||||
/// case it *must* be explicitely disposed (which will remove it from call context).</para>
|
||||
/// This should not be used for CRUD operations or queries against the
|
||||
/// standard Umbraco tables! Use the Public services for that.
|
||||
/// </remarks>
|
||||
public virtual UmbracoDatabase Database
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsDatabaseConfigured == false)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create a database instance, there is no available connection string");
|
||||
}
|
||||
|
||||
return ScopeProvider.GetAmbientOrNoScope().Database;
|
||||
//var scope = ScopeProvider.AmbientScope;
|
||||
//return scope != null ? scope.Database : ScopeProvider.CreateNoScope().Database;
|
||||
}
|
||||
get { return _factory.CreateDatabase(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -223,7 +121,7 @@ namespace Umbraco.Core
|
||||
|
||||
//Don't check again if the timeout period hasn't elapsed
|
||||
//this ensures we don't keep checking the connection too many times in a row like during startup.
|
||||
//Do check if the _connectionLastChecked is null which means we're just initializing or it could
|
||||
//Do check if the _connectionLastChecked is null which means we're just initializing or it could
|
||||
//not connect last time it was checked.
|
||||
if ((_connectionLastChecked.HasValue && (DateTime.Now - _connectionLastChecked.Value).TotalMinutes > ConnectionCheckMinutes)
|
||||
|| _connectionLastChecked.HasValue == false)
|
||||
@@ -259,14 +157,14 @@ namespace Umbraco.Core
|
||||
return _providerName;
|
||||
|
||||
_providerName = Constants.DatabaseProviders.SqlServer;
|
||||
if (ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName] != null)
|
||||
if (ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName] != null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName) == false)
|
||||
_providerName = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName;
|
||||
if (string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName) == false)
|
||||
_providerName = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NullReferenceException("Can't find a connection string with the name '" + Constants.System.UmbracoConnectionName + "'");
|
||||
throw new InvalidOperationException("Can't find a connection string with the name '" + GlobalSettings.UmbracoConnectionName + "'");
|
||||
}
|
||||
return _providerName;
|
||||
}
|
||||
@@ -305,10 +203,15 @@ namespace Umbraco.Core
|
||||
var path = Path.Combine(GlobalSettings.FullpathToRoot, "App_Data", "Umbraco.sdf");
|
||||
if (File.Exists(path) == false)
|
||||
{
|
||||
using (var engine = new SqlCeEngine(connectionString))
|
||||
{
|
||||
engine.CreateDatabase();
|
||||
}
|
||||
var engine = new SqlCeEngine(connectionString);
|
||||
engine.CreateDatabase();
|
||||
|
||||
// SD: Pretty sure this should be in a using clause but i don't want to cause unknown side-effects here
|
||||
// since it's been like this for quite some time
|
||||
//using (var engine = new SqlCeEngine(connectionString))
|
||||
//{
|
||||
// engine.CreateDatabase();
|
||||
//}
|
||||
}
|
||||
|
||||
Initialize(providerName);
|
||||
@@ -348,14 +251,14 @@ namespace Umbraco.Core
|
||||
/// <param name="password">Database Password</param>
|
||||
/// <param name="databaseProvider">Type of the provider to be used (Sql, Sql Azure, Sql Ce, MySql)</param>
|
||||
public void ConfigureDatabaseConnection(string server, string databaseName, string user, string password, string databaseProvider)
|
||||
{
|
||||
{
|
||||
string providerName;
|
||||
var connectionString = GetDatabaseConnectionString(server, databaseName, user, password, databaseProvider, out providerName);
|
||||
|
||||
SaveConnectionString(connectionString, providerName);
|
||||
Initialize(providerName);
|
||||
}
|
||||
|
||||
|
||||
public string GetDatabaseConnectionString(string server, string databaseName, string user, string password, string databaseProvider, out string providerName)
|
||||
{
|
||||
providerName = Constants.DatabaseProviders.SqlServer;
|
||||
@@ -386,18 +289,18 @@ namespace Umbraco.Core
|
||||
|
||||
public string GetIntegratedSecurityDatabaseConnectionString(string server, string databaseName)
|
||||
{
|
||||
return String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
|
||||
return String.Format("Server={0};Database={1};Integrated Security=true", server, databaseName);
|
||||
}
|
||||
|
||||
internal string BuildAzureConnectionString(string server, string databaseName, string user, string password)
|
||||
{
|
||||
if (server.Contains(".") && ServerStartsWithTcp(server) == false)
|
||||
server = string.Format("tcp:{0}", server);
|
||||
|
||||
|
||||
if (server.Contains(".") == false && ServerStartsWithTcp(server))
|
||||
{
|
||||
string serverName = server.Contains(",")
|
||||
? server.Substring(0, server.IndexOf(",", StringComparison.Ordinal))
|
||||
string serverName = server.Contains(",")
|
||||
? server.Substring(0, server.IndexOf(",", StringComparison.Ordinal))
|
||||
: server;
|
||||
|
||||
var portAddition = string.Empty;
|
||||
@@ -407,10 +310,10 @@ namespace Umbraco.Core
|
||||
|
||||
server = string.Format("{0}.database.windows.net{1}", serverName, portAddition);
|
||||
}
|
||||
|
||||
|
||||
if (ServerStartsWithTcp(server) == false)
|
||||
server = string.Format("tcp:{0}.database.windows.net", server);
|
||||
|
||||
|
||||
if (server.Contains(",") == false)
|
||||
server = string.Format("{0},1433", server);
|
||||
|
||||
@@ -447,23 +350,23 @@ namespace Umbraco.Core
|
||||
{
|
||||
//Set the connection string for the new datalayer
|
||||
var connectionStringSettings = string.IsNullOrEmpty(providerName)
|
||||
? new ConnectionStringSettings(Constants.System.UmbracoConnectionName,
|
||||
? new ConnectionStringSettings(GlobalSettings.UmbracoConnectionName,
|
||||
connectionString)
|
||||
: new ConnectionStringSettings(Constants.System.UmbracoConnectionName,
|
||||
: new ConnectionStringSettings(GlobalSettings.UmbracoConnectionName,
|
||||
connectionString, providerName);
|
||||
|
||||
_connectionString = connectionString;
|
||||
_providerName = providerName;
|
||||
|
||||
|
||||
var fileName = IOHelper.MapPath(string.Format("{0}/web.config", SystemDirectories.Root));
|
||||
var xml = XDocument.Load(fileName, LoadOptions.PreserveWhitespace);
|
||||
var connectionstrings = xml.Root.DescendantsAndSelf("connectionStrings").Single();
|
||||
|
||||
// Update connectionString if it exists, or else create a new appSetting for the given key and value
|
||||
var setting = connectionstrings.Descendants("add").FirstOrDefault(s => s.Attribute("name").Value == Constants.System.UmbracoConnectionName);
|
||||
var setting = connectionstrings.Descendants("add").FirstOrDefault(s => s.Attribute("name").Value == GlobalSettings.UmbracoConnectionName);
|
||||
if (setting == null)
|
||||
connectionstrings.Add(new XElement("add",
|
||||
new XAttribute("name", Constants.System.UmbracoConnectionName),
|
||||
new XAttribute("name", GlobalSettings.UmbracoConnectionName),
|
||||
new XAttribute("connectionString", connectionStringSettings),
|
||||
new XAttribute("providerName", providerName)));
|
||||
else
|
||||
@@ -488,23 +391,23 @@ namespace Umbraco.Core
|
||||
/// </remarks>
|
||||
internal void Initialize()
|
||||
{
|
||||
var databaseSettings = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName];
|
||||
var databaseSettings = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName];
|
||||
if (databaseSettings != null && string.IsNullOrWhiteSpace(databaseSettings.ConnectionString) == false && string.IsNullOrWhiteSpace(databaseSettings.ProviderName) == false)
|
||||
{
|
||||
var providerName = Constants.DatabaseProviders.SqlServer;
|
||||
string connString = null;
|
||||
if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName))
|
||||
if (!string.IsNullOrEmpty(ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName))
|
||||
{
|
||||
providerName = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ProviderName;
|
||||
connString = ConfigurationManager.ConnectionStrings[Constants.System.UmbracoConnectionName].ConnectionString;
|
||||
providerName = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ProviderName;
|
||||
connString = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName].ConnectionString;
|
||||
}
|
||||
Initialize(providerName, connString);
|
||||
|
||||
|
||||
}
|
||||
else if (ConfigurationManager.AppSettings.ContainsKey(Constants.System.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[Constants.System.UmbracoConnectionName]) == false)
|
||||
else if (ConfigurationManager.AppSettings.ContainsKey(GlobalSettings.UmbracoConnectionName) && string.IsNullOrEmpty(ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName]) == false)
|
||||
{
|
||||
//A valid connectionstring does not exist, but the legacy appSettings key was found, so we'll reconfigure the conn.string.
|
||||
var legacyConnString = ConfigurationManager.AppSettings[Constants.System.UmbracoConnectionName];
|
||||
var legacyConnString = ConfigurationManager.AppSettings[GlobalSettings.UmbracoConnectionName];
|
||||
if (legacyConnString.ToLowerInvariant().Contains("sqlce4umbraco"))
|
||||
{
|
||||
ConfigureEmbeddedDatabaseConnection();
|
||||
@@ -535,8 +438,8 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
//Remove the legacy connection string, so we don't end up in a loop if something goes wrong.
|
||||
GlobalSettings.RemoveSetting(Constants.System.UmbracoConnectionName);
|
||||
|
||||
GlobalSettings.RemoveSetting(GlobalSettings.UmbracoConnectionName);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -555,15 +458,15 @@ namespace Umbraco.Core
|
||||
{
|
||||
if (_syntaxProviders != null)
|
||||
{
|
||||
SqlSyntax = _syntaxProviders.GetByProviderNameOrDefault(providerName);
|
||||
SqlSyntax = _syntaxProviders.GetByProviderNameOrDefault(providerName);
|
||||
}
|
||||
else if (SqlSyntax == null)
|
||||
{
|
||||
throw new InvalidOperationException("No " + typeof(ISqlSyntaxProvider) + " specified or no " + typeof(SqlSyntaxProviders) + " instance specified");
|
||||
}
|
||||
|
||||
|
||||
SqlSyntaxContext.SqlSyntaxProvider = SqlSyntax;
|
||||
|
||||
|
||||
_configured = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -603,7 +506,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
|
||||
internal Result CreateDatabaseSchemaAndData(ApplicationContext applicationContext)
|
||||
{
|
||||
{
|
||||
try
|
||||
{
|
||||
var readyForInstall = CheckReadyForInstall();
|
||||
@@ -621,7 +524,7 @@ namespace Umbraco.Core
|
||||
// If MySQL, we're going to ensure that database calls are maintaining proper casing as to remove the necessity for checks
|
||||
// for case insensitive queries. In an ideal situation (which is what we're striving for), all calls would be case sensitive.
|
||||
|
||||
/*
|
||||
/*
|
||||
var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
|
||||
if (supportsCaseInsensitiveQueries == false)
|
||||
{
|
||||
@@ -639,9 +542,9 @@ namespace Umbraco.Core
|
||||
message = GetResultMessageForMySql();
|
||||
|
||||
var schemaResult = ValidateDatabaseSchema();
|
||||
|
||||
|
||||
var installedSchemaVersion = schemaResult.DetermineInstalledVersion();
|
||||
|
||||
|
||||
//If Configuration Status is empty and the determined version is "empty" its a new install - otherwise upgrade the existing
|
||||
if (string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus) && installedSchemaVersion.Equals(new Version(0, 0, 0)))
|
||||
{
|
||||
@@ -660,9 +563,9 @@ namespace Umbraco.Core
|
||||
message = "<p>Upgrading database, this may take some time...</p>";
|
||||
return new Result
|
||||
{
|
||||
RequiresUpgrade = true,
|
||||
Message = message,
|
||||
Success = true,
|
||||
RequiresUpgrade = true,
|
||||
Message = message,
|
||||
Success = true,
|
||||
Percentage = "30"
|
||||
};
|
||||
}
|
||||
@@ -690,7 +593,7 @@ namespace Umbraco.Core
|
||||
_logger.Info<DatabaseContext>("Database upgrade started");
|
||||
|
||||
var database = new UmbracoDatabase(_connectionString, ProviderName, _logger);
|
||||
//var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
|
||||
//var supportsCaseInsensitiveQueries = SqlSyntax.SupportsCaseInsensitiveQueries(database);
|
||||
|
||||
var message = GetResultMessageForMySql();
|
||||
|
||||
@@ -698,32 +601,32 @@ namespace Umbraco.Core
|
||||
|
||||
var installedSchemaVersion = new SemVersion(schemaResult.DetermineInstalledVersion());
|
||||
|
||||
var installedMigrationVersion = schemaResult.DetermineInstalledVersionByMigrations(migrationEntryService);
|
||||
|
||||
var installedMigrationVersion = schemaResult.DetermineInstalledVersionByMigrations(migrationEntryService);
|
||||
|
||||
var targetVersion = UmbracoVersion.Current;
|
||||
|
||||
|
||||
//In some cases - like upgrading from 7.2.6 -> 7.3, there will be no migration information in the database and therefore it will
|
||||
// return a version of 0.0.0 and we don't necessarily want to run all migrations from 0 -> 7.3, so we'll just ensure that the
|
||||
// return a version of 0.0.0 and we don't necessarily want to run all migrations from 0 -> 7.3, so we'll just ensure that the
|
||||
// migrations are run for the target version
|
||||
if (installedMigrationVersion == new SemVersion(new Version(0, 0, 0)) && installedSchemaVersion > new SemVersion(new Version(0, 0, 0)))
|
||||
{
|
||||
//set the installedMigrationVersion to be one less than the target so the latest migrations are guaranteed to execute
|
||||
installedMigrationVersion = new SemVersion(targetVersion.SubtractRevision());
|
||||
}
|
||||
|
||||
|
||||
//Figure out what our current installed version is. If the web.config doesn't have a version listed, then we'll use the minimum
|
||||
// version detected between the schema installed and the migrations listed in the migration table.
|
||||
// version detected between the schema installed and the migrations listed in the migration table.
|
||||
// If there is a version in the web.config, we'll take the minimum between the listed migration in the db and what
|
||||
// is declared in the web.config.
|
||||
|
||||
|
||||
var currentInstalledVersion = string.IsNullOrEmpty(GlobalSettings.ConfigurationStatus)
|
||||
//Take the minimum version between the detected schema version and the installed migration version
|
||||
? new[] {installedSchemaVersion, installedMigrationVersion}.Min()
|
||||
//Take the minimum version between the installed migration version and the version specified in the config
|
||||
: new[] { SemVersion.Parse(GlobalSettings.ConfigurationStatus), installedMigrationVersion }.Min();
|
||||
|
||||
//Ok, another edge case here. If the current version is a pre-release,
|
||||
// then we want to ensure all migrations for the current release are executed.
|
||||
//Ok, another edge case here. If the current version is a pre-release,
|
||||
// then we want to ensure all migrations for the current release are executed.
|
||||
if (currentInstalledVersion.Prerelease.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
currentInstalledVersion = new SemVersion(currentInstalledVersion.GetVersion().SubtractRevision());
|
||||
@@ -731,7 +634,7 @@ namespace Umbraco.Core
|
||||
|
||||
//DO the upgrade!
|
||||
|
||||
var runner = new MigrationRunner(migrationEntryService, _logger, currentInstalledVersion, UmbracoVersion.GetSemanticVersion(), Constants.System.UmbracoMigrationName);
|
||||
var runner = new MigrationRunner(migrationEntryService, _logger, currentInstalledVersion, UmbracoVersion.GetSemanticVersion(), GlobalSettings.UmbracoMigrationName);
|
||||
|
||||
var upgraded = runner.Execute(database, true);
|
||||
|
||||
@@ -858,7 +761,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
var datasource = dataSourcePart.Replace("|DataDirectory|", AppDomain.CurrentDomain.GetData("DataDirectory").ToString());
|
||||
var filePath = datasource.Replace("Data Source=", string.Empty);
|
||||
sqlCeDatabaseExists = File.Exists(filePath);
|
||||
sqlCeDatabaseExists = File.Exists(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,30 +775,5 @@ namespace Umbraco.Core
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
private class UsingDatabase : IDisposable
|
||||
{
|
||||
private readonly UmbracoDatabase _orig;
|
||||
private readonly UmbracoDatabase _temp;
|
||||
|
||||
public UsingDatabase(UmbracoDatabase orig, UmbracoDatabase temp)
|
||||
{
|
||||
_orig = orig;
|
||||
_temp = temp;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_temp != null)
|
||||
{
|
||||
_temp.Dispose();
|
||||
if (_orig != null)
|
||||
DefaultDatabaseFactory.AttachAmbientDatabase(_orig);
|
||||
}
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class to all artifacts.
|
||||
/// </summary>
|
||||
public abstract class ArtifactBase<TUdi> : IArtifact
|
||||
where TUdi : Udi
|
||||
{
|
||||
protected ArtifactBase(TUdi udi, IEnumerable<ArtifactDependency> dependencies = null)
|
||||
{
|
||||
if (udi == null)
|
||||
throw new ArgumentNullException("udi");
|
||||
Udi = udi;
|
||||
Name = Udi.ToString();
|
||||
|
||||
Dependencies = dependencies ?? Enumerable.Empty<ArtifactDependency>();
|
||||
_checksum = new Lazy<string>(GetChecksum);
|
||||
}
|
||||
|
||||
private readonly Lazy<string> _checksum;
|
||||
private IEnumerable<ArtifactDependency> _dependencies;
|
||||
|
||||
protected abstract string GetChecksum();
|
||||
|
||||
#region Abstract implementation of IArtifactSignature
|
||||
|
||||
Udi IArtifactSignature.Udi
|
||||
{
|
||||
get { return Udi; }
|
||||
}
|
||||
|
||||
public TUdi Udi { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Checksum
|
||||
{
|
||||
get { return _checksum.Value; }
|
||||
}
|
||||
|
||||
public IEnumerable<ArtifactDependency> Dependencies
|
||||
{
|
||||
get { return _dependencies; }
|
||||
set { _dependencies = value.OrderBy(x => x.Udi); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public string Name { get; set; }
|
||||
public string Alias { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an artifact dependency.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Dependencies have an order property which indicates whether it must be respected when ordering artifacts.</para>
|
||||
/// <para>Dependencies have a mode which can be <c>Match</c> or <c>Exist</c> depending on whether the checksum should match.</para>
|
||||
/// </remarks>
|
||||
public class ArtifactDependency
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ArtifactDependency class with an entity identifier and a mode.
|
||||
/// </summary>
|
||||
/// <param name="udi">The entity identifier of the artifact that is a dependency.</param>
|
||||
/// <param name="ordering">A value indicating whether the dependency is ordering.</param>
|
||||
/// <param name="mode">The dependency mode.</param>
|
||||
public ArtifactDependency(Udi udi, bool ordering, ArtifactDependencyMode mode)
|
||||
{
|
||||
Udi = udi;
|
||||
Ordering = ordering;
|
||||
Mode = mode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the entity id of the artifact that is a dependency.
|
||||
/// </summary>
|
||||
public Udi Udi { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the dependency is ordering.
|
||||
/// </summary>
|
||||
public bool Ordering { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dependency mode.
|
||||
/// </summary>
|
||||
public ArtifactDependencyMode Mode { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of distinct <see cref="ArtifactDependency"/>.
|
||||
/// </summary>
|
||||
/// <remarks>The collection cannot contain duplicates and modes are properly managed.</remarks>
|
||||
public class ArtifactDependencyCollection : ICollection<ArtifactDependency>
|
||||
{
|
||||
private readonly Dictionary<Udi, ArtifactDependency> _dependencies
|
||||
= new Dictionary<Udi, ArtifactDependency>();
|
||||
|
||||
public IEnumerator<ArtifactDependency> GetEnumerator()
|
||||
{
|
||||
return _dependencies.Values.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void Add(ArtifactDependency item)
|
||||
{
|
||||
if (_dependencies.ContainsKey(item.Udi))
|
||||
{
|
||||
var exist = _dependencies[item.Udi];
|
||||
if (item.Mode == ArtifactDependencyMode.Exist || item.Mode == exist.Mode)
|
||||
return;
|
||||
}
|
||||
|
||||
_dependencies[item.Udi] = item;
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
_dependencies.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(ArtifactDependency item)
|
||||
{
|
||||
return _dependencies.ContainsKey(item.Udi) &&
|
||||
(_dependencies[item.Udi].Mode == item.Mode || _dependencies[item.Udi].Mode == ArtifactDependencyMode.Match);
|
||||
}
|
||||
|
||||
public void CopyTo(ArtifactDependency[] array, int arrayIndex)
|
||||
{
|
||||
_dependencies.Values.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public bool Remove(ArtifactDependency item)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return _dependencies.Count; }
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the mode of the dependency.
|
||||
/// </summary>
|
||||
public enum ArtifactDependencyMode
|
||||
{
|
||||
/// <summary>
|
||||
/// The dependency must match exactly.
|
||||
/// </summary>
|
||||
Match,
|
||||
|
||||
/// <summary>
|
||||
/// The dependency must exist.
|
||||
/// </summary>
|
||||
Exist
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent the state of an artifact being deployed.
|
||||
/// </summary>
|
||||
public abstract class ArtifactDeployState
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ArtifactDeployState"/> class from an artifact and an entity.
|
||||
/// </summary>
|
||||
/// <typeparam name="TArtifact">The type of the artifact.</typeparam>
|
||||
/// <typeparam name="TEntity">The type of the entity.</typeparam>
|
||||
/// <param name="art">The artifact.</param>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <param name="connector">The service connector deploying the artifact.</param>
|
||||
/// <param name="nextPass">The next pass number.</param>
|
||||
/// <returns>A deploying artifact.</returns>
|
||||
public static ArtifactDeployState<TArtifact, TEntity> Create<TArtifact, TEntity>(TArtifact art, TEntity entity, IServiceConnector connector, int nextPass)
|
||||
where TArtifact : IArtifact
|
||||
{
|
||||
return new ArtifactDeployState<TArtifact, TEntity>(art, entity, connector, nextPass);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the artifact.
|
||||
/// </summary>
|
||||
public IArtifact Artifact
|
||||
{
|
||||
get { return GetArtifactAsIArtifact(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the artifact as an <see cref="IArtifact"/>.
|
||||
/// </summary>
|
||||
/// <returns>The artifact, as an <see cref="IArtifact"/>.</returns>
|
||||
/// <remarks>This is because classes that inherit from this class cannot override the Artifact property
|
||||
/// with a property that specializes the return type, and so they need to 'new' the property.</remarks>
|
||||
protected abstract IArtifact GetArtifactAsIArtifact();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the service connector in charge of deploying the artifact.
|
||||
/// </summary>
|
||||
public IServiceConnector Connector { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the next pass number.
|
||||
/// </summary>
|
||||
public int NextPass { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Represent the state of an artifact being deployed.
|
||||
/// </summary>
|
||||
/// <typeparam name="TArtifact">The type of the artifact.</typeparam>
|
||||
/// <typeparam name="TEntity">The type of the entity.</typeparam>
|
||||
public class ArtifactDeployState<TArtifact, TEntity> : ArtifactDeployState
|
||||
where TArtifact : IArtifact
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArtifactDeployState{TArtifact,TEntity}"/> class.
|
||||
/// </summary>
|
||||
public ArtifactDeployState()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ArtifactDeployState{TArtifact,TEntity}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="art">The artifact.</param>
|
||||
/// <param name="entity">The entity.</param>
|
||||
/// <param name="connector">The service connector deploying the artifact.</param>
|
||||
/// <param name="nextPass">The next pass number.</param>
|
||||
public ArtifactDeployState(TArtifact art, TEntity entity, IServiceConnector connector, int nextPass)
|
||||
{
|
||||
Artifact = art;
|
||||
Entity = entity;
|
||||
Connector = connector;
|
||||
NextPass = nextPass;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the artifact.
|
||||
/// </summary>
|
||||
public new TArtifact Artifact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the entity.
|
||||
/// </summary>
|
||||
public TEntity Entity { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected sealed override IArtifact GetArtifactAsIArtifact()
|
||||
{
|
||||
return Artifact;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
public sealed class ArtifactSignature : IArtifactSignature
|
||||
{
|
||||
public ArtifactSignature(Udi udi, string checksum, IEnumerable<ArtifactDependency> dependencies = null)
|
||||
{
|
||||
Udi = udi;
|
||||
Checksum = checksum;
|
||||
Dependencies = dependencies ?? Enumerable.Empty<ArtifactDependency>();
|
||||
}
|
||||
|
||||
public Udi Udi { get; private set; }
|
||||
|
||||
public string Checksum { get; private set; }
|
||||
|
||||
public IEnumerable<ArtifactDependency> Dependencies { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
public class Difference
|
||||
{
|
||||
public Difference(string title, string text = null, string category = null)
|
||||
{
|
||||
Title = title;
|
||||
Text = text;
|
||||
Category = category;
|
||||
}
|
||||
|
||||
public string Title { get; set; }
|
||||
public string Text { get; set; }
|
||||
public string Category { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var s = Title;
|
||||
if (!string.IsNullOrWhiteSpace(Category)) s += string.Format("[{0}]", Category);
|
||||
if (!string.IsNullOrWhiteSpace(Text))
|
||||
{
|
||||
if (s.Length > 0) s += ":";
|
||||
s += Text;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
public enum Direction
|
||||
{
|
||||
ToArtifact,
|
||||
FromArtifact
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an artifact ie an object that can be transfered between environments.
|
||||
/// </summary>
|
||||
public interface IArtifact : IArtifactSignature
|
||||
{
|
||||
string Name { get; }
|
||||
string Alias { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the signature of an artifact.
|
||||
/// </summary>
|
||||
public interface IArtifactSignature
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the entity unique identifier of this artifact.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The project identifier is independent from the state of the artifact, its data
|
||||
/// values, dependencies, anything. It never changes and fully identifies the artifact.</para>
|
||||
/// <para>What an entity uses as a unique identifier will influence what we can transfer
|
||||
/// between environments. Eg content type "Foo" on one environment is not necessarily the
|
||||
/// same as "Foo" on another environment, if guids are used as unique identifiers. What is
|
||||
/// used should be documented for each entity, along with the consequences of the choice.</para>
|
||||
/// </remarks>
|
||||
Udi Udi { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the checksum of this artifact.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The checksum depends on the artifact's properties, and on the identifiers of all its dependencies,
|
||||
/// but not on their checksums. So the checksum changes when any of the artifact's properties changes,
|
||||
/// or when the list of dependencies changes. But not if one of these dependencies change.</para>
|
||||
/// <para>It is assumed that checksum collisions cannot happen ie that no two different artifact's
|
||||
/// states will ever produce the same checksum, so that if two artifacts have the same checksum then
|
||||
/// they are identical.</para>
|
||||
/// </remarks>
|
||||
string Checksum { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the dependencies of this artifact.
|
||||
/// </summary>
|
||||
IEnumerable<ArtifactDependency> Dependencies { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.Deploy
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a deployment context.
|
||||
/// </summary>
|
||||
public interface IDeployContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the deployment.
|
||||
/// </summary>
|
||||
Guid SessionId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file source.
|
||||
/// </summary>
|
||||
/// <remarks>The file source is used to obtain files from the source environment.</remarks>
|
||||
IFileSource FileSource { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the next number in a numerical sequence.
|
||||
/// </summary>
|
||||
/// <returns>The next sequence number.</returns>
|
||||
/// <remarks>Can be used to uniquely number things during a deployment.</remarks>
|
||||
int NextSeq();
|
||||
|
||||
/// <summary>
|
||||
/// Gets items.
|
||||
/// </summary>
|
||||
IDictionary<string, object> Items { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets item.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the item.</typeparam>
|
||||
/// <param name="key">The key of the item.</param>
|
||||
/// <returns>The item with the specified key and type, if any, else null.</returns>
|
||||
T Item<T>(string key) where T : class;
|
||||
|
||||
///// <summary>
|
||||
///// Gets the global deployment cancellation token.
|
||||
///// </summary>
|
||||
//CancellationToken CancellationToken { get; }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user