Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Commit

Permalink
Merge pull request #203 from twsouthwick/file-output-service
Browse files Browse the repository at this point in the history
Remove NotImplementedExceptions in FileOutputService
  • Loading branch information
twsouthwick committed Nov 24, 2015
2 parents 2621e51 + 89851a2 commit ccc2dbe
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 50 deletions.
58 changes: 55 additions & 3 deletions docs/HowTo/Introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,8 @@ ApiPort.exe analyze -f foo.dll -t ".NET CORE, Version=5.0" -t ".NET Framework" -

### List targets

The targets available to analyze against are retrieved from a service that is updated regularly (except when running in
[offline mode](OfflineMode.md)). These are ever growing, and include the previous versions of the framework, although
it defaults to the most current platforms and versions.
The targets available to analyze against are retrieved from a service that is updated regularly. These targets change over time as new
platforms are available. The service will default to the most current platforms and versions.

For example, the command `ApiPort.exe listTargets` will output:

Expand Down Expand Up @@ -124,3 +123,56 @@ results in the following output formats:
- json
- HTML
- Excel

# Alternate modes

The tool by default will gather the results and submit to a webservice that will analyze the data to determine which APIs need to be addressed. For full
details on this process, please read the [privacy policy](/docs/LicenseTerms/Microsoft%20.NET%20Portability%20Analyzer%20Privacy%20Statement.txt).
There are two alternate modes that can be used to alter this workflow.

## See the data being transmitted

The first option is to output the request to a file. This will result in an output that shows what data is being transmitted to the service, but provides
no details as to API portability or breaking changes. This is a good option if you would like to see what data will be collected.

In order to enable this mode, create a file `unity.config` and place it in the same directory as `ApiPort.exe`. Add the following contents:

```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<typeAliases>
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity" />
<typeAlias alias="IApiPortService" type="Microsoft.Fx.Portability.IApiPortService, Microsoft.Fx.Portability" />
<typeAlias alias="FileOutputApiPortService" type="ApiPort.FileOutputApiPortService, ApiPort" />
</typeAliases>
<container>
<register type="IApiPortService" mapTo="FileOutputApiPortService" >
<lifetime type="singleton" />
</register>
<instance name="DefaultOutputFormat" value="json" />
</container>
</unity>
</configuration>
```

Now, when you run, it will output a file with the information that is sent to the .NET Portability service.

## Run the tool in an offline mode

Another option is to enable full offline access. This mode will not get automatic updates and no official releases of it are available. In order to use this mode,
the solution must be manually built. To do so, please follow these steps:

1. Clone the project: `git clone https://github.com/Microsoft/dotnet-apiport`
2. Build the project: `build.cmd`.

*Note: This command must be used as it gathers the correct assemblies for offline mode. Building in VS does not do this.*

3. Go to `bin\release\ApiPort.Offline`
4. Run `ApiPort.exe` from this directory as normal.

Additional reports can be generated in offline mode. Any implementation of `Microsoft.Fx.Portability.Reporting.IReportWriter` can be used. Add an entry to `unity.config`
following the pattern of the HTML and json writers. The offline mode will pick it up and allow reports to be returned in custom formats.
18 changes: 0 additions & 18 deletions docs/HowTo/OfflineMode.md

This file was deleted.

71 changes: 45 additions & 26 deletions src/ApiPort/FileOutputApiPortService.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using ApiPort.Resources;
using Microsoft.Fx.Portability;
using Microsoft.Fx.Portability.ObjectModel;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

Expand All @@ -17,59 +16,85 @@ namespace ApiPort
/// </summary>
internal class FileOutputApiPortService : IApiPortService
{
private static readonly IReadOnlyCollection<ApiDefinition> s_emptySearchResults = new ApiDefinition[] { };
private static readonly IEnumerable<ResultFormatInformation> s_formats = new[]
{
new ResultFormatInformation
{
DisplayName = "json",
FileExtension = ".json"
}
};

private readonly IProgressReporter _progress;

public FileOutputApiPortService(IProgressReporter progress)
{
_progress = progress;
}

public Task<ServiceResponse<AnalyzeResponse>> GetAnalysisAsync(string submissionId)
{
throw new NotImplementedException();
_progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported);
var result = ServiceResponse.Create(new AnalyzeResponse());

return Task.FromResult(result);
}

public Task<ServiceResponse<byte[]>> GetAnalysisAsync(string submissionId, string format)
{
throw new NotImplementedException();
_progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported);
var result = ServiceResponse.Create(new byte[] { });

return Task.FromResult(result);
}

public Task<ServiceResponse<ApiInformation>> GetApiInformationAsync(string docId)
{
throw new NotImplementedException();
_progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported);
var response = ServiceResponse.Create(new ApiInformation());

return Task.FromResult(response);
}

public Task<ServiceResponse<IEnumerable<ResultFormatInformation>>> GetResultFormatsAsync()
{
var format = new ResultFormatInformation { DisplayName = "Excel", FileExtension = ".xlsx" };
var response = new ServiceResponse<IEnumerable<ResultFormatInformation>>(new[] { format });
var response = ServiceResponse.Create(s_formats);

return Task.FromResult(response);
}

public Task<ServiceResponse<IEnumerable<AvailableTarget>>> GetTargetsAsync()
{
throw new NotImplementedException();
var response = ServiceResponse.Create(Enumerable.Empty<AvailableTarget>());

return Task.FromResult(response);
}

public Task<ServiceResponse<UsageDataCollection>> GetUsageDataAsync(int? skip = default(int?), int? top = default(int?), UsageDataFilter? filter = default(UsageDataFilter?), IEnumerable<string> targets = null)
{
throw new NotImplementedException();
_progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported);
var response = ServiceResponse.Create(new UsageDataCollection());

return Task.FromResult(response);
}

public Task<ServiceResponse<IReadOnlyCollection<ApiDefinition>>> SearchFxApiAsync(string query, int? top = default(int?))
{
throw new NotImplementedException();
_progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported);
var response = ServiceResponse.Create(s_emptySearchResults);

return Task.FromResult(response);
}

public Task<ServiceResponse<AnalyzeResponse>> SendAnalysisAsync(AnalyzeRequest a)
{
WriteOutput(a);
_progress.ReportIssue(LocalizedStrings.FileOutputServiceNotSupported);

return Task.FromResult(new ServiceResponse<AnalyzeResponse>(new AnalyzeResponse()));
}

public Task<ServiceResponse<byte[]>> SendAnalysisAsync(AnalyzeRequest a, string format)
{
WriteOutput(a);

return Task.FromResult(new ServiceResponse<byte[]>(new byte[] { }));
}

private void WriteOutput(AnalyzeRequest a)
{
var sortedAnalyzeRequest = new AnalyzeRequest
{
Expand All @@ -91,15 +116,9 @@ private void WriteOutput(AnalyzeRequest a)
AssembliesToIgnore = a.AssembliesToIgnore.OrderBy(i => i.AssemblyIdentity)
};

var tmp = $"{Path.GetTempFileName()}.json";

using (var ms = new MemoryStream(sortedAnalyzeRequest.Serialize()))
using (var fs = File.OpenWrite(tmp))
{
ms.CopyTo(fs);
}
var result = sortedAnalyzeRequest.Serialize();

Process.Start(tmp);
return Task.FromResult(ServiceResponse.Create(result));
}
}
}
9 changes: 9 additions & 0 deletions src/ApiPort/Resources/LocalizedStrings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/ApiPort/Resources/LocalizedStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -279,4 +279,7 @@ gives a summary of issues and possible steps forward.

-h, -?, --help Show help</value>
</data>
<data name="FileOutputServiceNotSupported" xml:space="preserve">
<value>Analyze request file output does not support this operation</value>
</data>
</root>
11 changes: 8 additions & 3 deletions src/Microsoft.Fx.Portability/IObjectCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@

namespace Microsoft.Fx.Portability
{
public interface IObjectCache<TObject> : IDisposable
public interface IObjectCache : IDisposable
{
TObject Value { get; }
DateTimeOffset LastUpdated { get; }
Task UpdateAsync();

DateTimeOffset LastUpdated { get; }
}

public interface IObjectCache<TObject> : IObjectCache
{
TObject Value { get; }
}
}
8 changes: 8 additions & 0 deletions src/Microsoft.Fx.Portability/ServiceResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,12 @@ public ServiceResponse(T result, HttpResponseMessage response)
Headers = new ServiceHeaders(response);
}
}

public static class ServiceResponse
{
public static ServiceResponse<T> Create<T>(T response)
{
return new ServiceResponse<T>(response);
}
}
}

0 comments on commit ccc2dbe

Please sign in to comment.