Skip to content

Commit

Permalink
feature: bring reactiveui.fody into the main project (reactiveui#1503)
Browse files Browse the repository at this point in the history
* added fody

* Fix unhandled exception on netstandard (reactiveui#1578)

* Align Fody dependencies to ReactiveUI (reactiveui#1649)

* added @reactiveui/fody-team

* Finish up ReactiveUI.Fody (reactiveui#1671)

* Fix package versioning

* Fix ReactiveUI.Fody NuGet package and include tests in build

* Add Fody projects to solution

* Fixed CLI build for Fody

* Added another Reactive Test
  • Loading branch information
ghuntley authored and vatsalyagoel committed Jun 10, 2018
1 parent 53151e2 commit cd92852
Show file tree
Hide file tree
Showing 31 changed files with 1,579 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ src/ReactiveUI.Blend/* @reactiveui/wpf-team @reactiveui/winf
src/ReactiveUI.Events.WPF/* @reactiveui/wpf-team
src/ReactiveUI.Events.XamForms/* @reactiveui/xamarin-forms-team

src/ReactiveUI.Fody*/* @reactiveui/fody-team

src/ReactiveUI.Winforms/* @reactiveui/winforms-team

src/ReactiveUI.Wpf/* @reactiveui/wpf-team
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,6 @@ src/ReactiveUI.Events*/Events_*.cs

src/*.Tests/API/*.received.txt
.idea/

# Fody Weavers (for tests)
src/Tools/
31 changes: 30 additions & 1 deletion build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ var packageWhitelist = new[] { "ReactiveUI.Testing",
"ReactiveUI.Events.Winforms",
"ReactiveUI.Events.XamForms",
"ReactiveUI",
"ReactiveUI.Fody",
"ReactiveUI.Fody.Helpers",
"ReactiveUI.AndroidSupport",
"ReactiveUI.Blend",
"ReactiveUI.WPF",
Expand Down Expand Up @@ -198,15 +200,23 @@ Task("BuildReactiveUI")

build("./src/ReactiveUI.Tests/ReactiveUI.Tests.csproj", "ReactiveUI.Tests");
build("./src/ReactiveUI.LeakTests/ReactiveUI.LeakTests.csproj", "ReactiveUI.LeakTests");
build("./src/ReactiveUI.Fody.Tests/ReactiveUI.Fody.Tests.csproj", "ReactiveUI.Fody.Tests");
});

Task("RunUnitTests")
.IsDependentOn("BuildReactiveUI")
.Does(() =>
{
Action<ICakeContext> testAction = tool => {
tool.XUnit2("./src/ReactiveUI.Tests/bin/**/*.Tests.dll", new XUnit2Settings {
OutputDirectory = artifactDirectory,
XmlReport = true,
NoAppDomain = true
});
};

tool.XUnit2("./src/ReactiveUI.*Tests/bin/**/*.Tests.dll", new XUnit2Settings {
Action<ICakeContext> testFodyAction = tool => {
tool.XUnit2("./src/ReactiveUI.Fody.Tests/bin/**/*.Tests.dll", new XUnit2Settings {
OutputDirectory = artifactDirectory,
XmlReport = true,
NoAppDomain = true
Expand All @@ -232,6 +242,25 @@ Task("RunUnitTests")
.ExcludeByFile("*splat/splat*")
.ExcludeByFile("*ApprovalTests*"));

OpenCover(testFodyAction,
testCoverageOutputFile,
new OpenCoverSettings {
ReturnTargetCodeOffset = 0,
ArgumentCustomization = args => args.Append("-mergeoutput")
}
.WithFilter("+[*]*")
.WithFilter("-[*.Testing]*")
.WithFilter("-[*.Tests*]*")
.WithFilter("-[ReactiveUI.Events]*")
.WithFilter("-[Splat*]*")
.WithFilter("-[ApprovalTests*]*")
.ExcludeByAttribute("*.ExcludeFromCodeCoverage*")
.ExcludeByFile("*/*Designer.cs")
.ExcludeByFile("*/*.g.cs")
.ExcludeByFile("*/*.g.i.cs")
.ExcludeByFile("*splat/splat*")
.ExcludeByFile("*ApprovalTests*"));

ReportGenerator(testCoverageOutputFile, artifactDirectory);
}).ReportError(exception =>
{
Expand Down
9 changes: 8 additions & 1 deletion src/Directory.build.props
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,14 @@
<ItemGroup>
<PackageReference Include="Nerdbank.GitVersioning" Version="2.1.23" PrivateAssets="all" />
</ItemGroup>


<ItemGroup Condition="$(IsTestProject)">
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.console" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<PackageReference Include="Xunit.StaFact" Version="0.2.9" />
</ItemGroup>

<ItemGroup Condition="'$(IsTestProject)' != 'true' and '$(SourceLinkEnabled)' != 'false'">
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.0" PrivateAssets="All" />
</ItemGroup>
Expand Down
13 changes: 13 additions & 0 deletions src/ReactiveUI.Fody.Helpers/ObservableAsPropertyAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.

using System;

namespace ReactiveUI.Fody.Helpers
{
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)]
public class ObservableAsPropertyAttribute : Attribute
{
}
}
41 changes: 41 additions & 0 deletions src/ReactiveUI.Fody.Helpers/ObservableAsPropertyExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.

using System;
using System.Linq.Expressions;
using System.Reactive.Concurrency;
using System.Reflection;

namespace ReactiveUI.Fody.Helpers
{
public static class ObservableAsPropertyExtensions
{
public static ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this IObservable<TRet> @this, TObj source, Expression<Func<TObj, TRet>> property, TRet initialValue = default(TRet), bool deferSubscription = false, IScheduler scheduler = null) where TObj : ReactiveObject
{
var result = @this.ToProperty(source, property, initialValue, deferSubscription, scheduler);

// Now assign the field via reflection.
var propertyInfo = property.GetPropertyInfo();
if (propertyInfo == null)
throw new Exception("Could not resolve expression " + property + " into a property.");

var field = propertyInfo.DeclaringType.GetTypeInfo().GetDeclaredField("$" + propertyInfo.Name);
if (field == null)
throw new Exception("Backing field not found for " + propertyInfo);
field.SetValue(source, result);

return result;
}

static PropertyInfo GetPropertyInfo(this LambdaExpression expression)
{
var current = expression.Body;
var unary = current as UnaryExpression;
if (unary != null)
current = unary.Operand;
var call = (MemberExpression)current;
return (PropertyInfo)call.Member;
}
}
}
11 changes: 11 additions & 0 deletions src/ReactiveUI.Fody.Helpers/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("ReactiveUI.Tests")]
[assembly: InternalsVisibleTo("ReactiveUI.Winforms")]
[assembly: InternalsVisibleTo("ReactiveUI.Wpf")]
[assembly: InternalsVisibleTo("ReactiveUI.XamForms")]
[assembly: InternalsVisibleTo("ReactiveUI.AndroidSupport")]
13 changes: 13 additions & 0 deletions src/ReactiveUI.Fody.Helpers/ReactiveAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.

using System;

namespace ReactiveUI.Fody.Helpers
{
[AttributeUsage(AttributeTargets.Property)]
public class ReactiveAttribute : Attribute
{
}
}
31 changes: 31 additions & 0 deletions src/ReactiveUI.Fody.Helpers/ReactiveDependencyAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Generic;
using System.Text;

namespace ReactiveUI.Fody.Helpers
{
[AttributeUsage(AttributeTargets.Property)]
public class ReactiveDependencyAttribute : Attribute
{
private readonly string _targetName;

public ReactiveDependencyAttribute(string targetName)
{
_targetName = targetName;
}

/// <summary>
/// The name of the backing property
/// </summary>
public string Target => _targetName;

/// <summary>
/// Target property on the backing property
/// </summary>
public string TargetProperty { get; set; }
}
}
51 changes: 51 additions & 0 deletions src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net461;uap10.0.16299;Xamarin.iOS10;Xamarin.Mac20;MonoAndroid80;netcoreapp2.0</TargetFrameworks>
<AssemblyName>ReactiveUI.Fody.Helpers</AssemblyName>
<RootNamespace>ReactiveUI.Fody.Helpers</RootNamespace>
<Description>Fody extension to generate RaisePropertyChange notifications for properties and ObservableAsPropertyHelper properties.</Description>

<!-- Override FodyPackaging since project is named differently than expected -->
<PackageId>ReactiveUI.Fody</PackageId>
<WeaverDirPath>..\$(PackageId)\bin\$(Configuration)\</WeaverDirPath>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Fody" Version="3.0.3" PrivateAssets="None" />
<PackageReference Include="FodyPackaging" Version="3.0.3" PrivateAssets="All" />
<PackageReference Include="System.Reactive" Version="[3.1.1,4)" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('netstandard'))">
<PackageReference Include="System.ComponentModel" Version="4.3.0" />
<PackageReference Include="System.Diagnostics.Contracts" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.iOS'))">
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('Xamarin.Mac'))">
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('MonoAndroid'))">
<Reference Include="System.Runtime.Serialization" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('netcoreapp'))">
<PackageReference Include="System.ComponentModel" Version="4.3.0" />
<PackageReference Include="System.Diagnostics.Contracts" Version="4.3.0" />
<PackageReference Include="System.Dynamic.Runtime" Version="4.3.0" />
<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ReactiveUI\ReactiveUI.csproj" />
</ItemGroup>

<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
</Project>
12 changes: 12 additions & 0 deletions src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.licenseheader
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
extensions: designer.cs generated.cs
extensions: .cs
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.

extensions: .xml .config .xsd
<!--
Licensed to the .NET Foundation under one or more agreements.
The .NET Foundation licenses this file to you under the MS-PL license.
See the LICENSE file in the project root for more information.
-->
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.AndroidSupport")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Tests")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Winforms")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.Wpf")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleToAttribute("ReactiveUI.XamForms")]
[assembly: System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.1", FrameworkDisplayName=".NET Framework 4.6.1")]
namespace ReactiveUI.Fody.Helpers
{
[System.AttributeUsageAttribute(System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.All)]
public class ObservableAsPropertyAttribute : System.Attribute
{
public ObservableAsPropertyAttribute() { }
}
public class static ObservableAsPropertyExtensions
{
public static ReactiveUI.ObservableAsPropertyHelper<TRet> ToPropertyEx<TObj, TRet>(this System.IObservable<TRet> @this, TObj source, System.Linq.Expressions.Expression<System.Func<TObj, TRet>> property, TRet initialValue = null, bool deferSubscription = False, System.Reactive.Concurrency.IScheduler scheduler = null)
where TObj : ReactiveUI.ReactiveObject { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.All)]
public class ReactiveAttribute : System.Attribute
{
public ReactiveAttribute() { }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Property | System.AttributeTargets.All)]
public class ReactiveDependencyAttribute : System.Attribute
{
public ReactiveDependencyAttribute(string targetName) { }
public string Target { get; }
public string TargetProperty { get; set; }
}
}
41 changes: 41 additions & 0 deletions src/ReactiveUI.Fody.Tests/API/ApiApprovalTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using ApprovalTests;
using ApprovalTests.Reporters;
using PublicApiGenerator;
using ReactiveUI.Fody.Helpers;
using Xunit;

namespace ReactiveUI.Fody.Tests.API
{
[ExcludeFromCodeCoverage]
[UseReporter(typeof(DiffReporter))]
public class ApiApprovalTests
{

[Fact]
public void ReactiveUI_Fody()
{
var publicApi = Filter(ApiGenerator.GeneratePublicApi(typeof(ReactiveAttribute).Assembly));
Approvals.Verify(publicApi);
}

private static string Filter(string text)
{
return string.Join(Environment.NewLine, text.Split(new[]
{
Environment.NewLine
}, StringSplitOptions.RemoveEmptyEntries)
.Where(l => !l.StartsWith("[assembly: AssemblyVersion("))
.Where(l => !l.StartsWith("[assembly: AssemblyFileVersion("))
.Where(l => !l.StartsWith("[assembly: AssemblyInformationalVersion("))
.Where(l => !string.IsNullOrWhiteSpace(l))
);
}
}
}
10 changes: 10 additions & 0 deletions src/ReactiveUI.Fody.Tests/FodyWeavers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Licensed to the .NET Foundation under one or more agreements.
The .NET Foundation licenses this file to you under the MS-PL license.
See the LICENSE file in the project root for more information.
-->

<Weavers>
<ReactiveUI />
</Weavers>
Loading

0 comments on commit cd92852

Please sign in to comment.