Skip to content

Commit

Permalink
(GH-20) Add support for npm publish
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalberger committed May 18, 2017
1 parent 8d2f042 commit d57b486
Show file tree
Hide file tree
Showing 8 changed files with 507 additions and 0 deletions.
12 changes: 12 additions & 0 deletions src/Cake.Npm/Namespaces.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@ internal class NamespaceDoc
}
}

// ReSharper disable once CheckNamespace
namespace Cake.Npm.Publish
{
/// <summary>
/// This namespace contain types used for publishing npm packages.
/// </summary>
[CompilerGenerated]
internal class NamespaceDoc
{
}
}

// ReSharper disable once CheckNamespace
namespace Cake.Npm.RunScript
{
Expand Down
107 changes: 107 additions & 0 deletions src/Cake.Npm/NpmPublishAliases.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
using System;
using Cake.Core;
using Cake.Core.Annotations;
using Cake.Npm.Publish;

namespace Cake.Npm
{
/// <summary>
/// Npm publish aliases.
/// </summary>
[CakeAliasCategory("Npm")]
[CakeNamespaceImport("Cake.Npm.Publish")]
public static class NpmPublishAliases
{
/// <summary>
/// Publishes the npm package in the current working directory.
/// </summary>
/// <param name="context">The context.</param>
/// <example>
/// <code>
/// <![CDATA[
/// NpmPublish();
/// ]]>
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Publish")]
public static void NpmPublish(this ICakeContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

context.NpmPublish(new NpmPublishSettings());
}

/// <summary>
/// Publishes the npm package created from a specific source.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="source">Source to publish.
/// A folder containing a package.json file or an url or file path to a gzipped tar archive
/// containing a single folder with a package.json file inside.</param>
/// <example>
/// <code>
/// <![CDATA[
/// NpmPublish("c:\mypackagesource");
/// ]]>
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Publish")]
public static void NpmPublish(this ICakeContext context, string source)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (String.IsNullOrWhiteSpace(source))
{
throw new ArgumentNullException(nameof(source));
}

context.NpmPublish(new NpmPublishSettings { Source = source });
}

/// <summary>
/// Publishes a npm package based on the specified settings.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="settings">The settings.</param>
/// <example>
/// <code>
/// <![CDATA[
/// var settings =
/// new NpmPublishSettings
/// {
/// LogLevel = NpmLogLevel.Verbose,
/// Source = "c:\mypackagesource"
/// };
/// NpmPublish(settings);
/// ]]>
/// </code>
/// </example>
[CakeMethodAlias]
[CakeAliasCategory("Publish")]
public static void NpmPublish(this ICakeContext context, NpmPublishSettings settings)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}

if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}

AddinInformation.LogVersionInformation(context.Log);

var publisher = new NpmPublisher(context.FileSystem, context.Environment, context.ProcessRunner, context.Tools, context.Log);
publisher.Publish(settings);
}
}
}
51 changes: 51 additions & 0 deletions src/Cake.Npm/Publish/NpmPublishSettings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
namespace Cake.Npm.Publish
{
using System;
using Core;
using Core.IO;

/// <summary>
/// Contains settings used by <see cref="NpmPublisher"/>.
/// </summary>
public class NpmPublishSettings : NpmSettings
{
/// <summary>
/// Initializes a new instance of the <see cref="NpmPublishSettings"/> class.
/// </summary>
public NpmPublishSettings()
: base("publish")
{
}

/// <summary>
/// Source to publish.
/// A folder containing a package.json file or an url or file path to a gzipped tar archive
/// containing a single folder with a package.json file inside.
/// </summary>
public string Source { get; set; }

/// <summary>
/// Registry where the package should be published to.
/// </summary>
public Uri Registry { get; set; }

/// <summary>
/// Evaluates the settings and writes them to <paramref name="args"/>.
/// </summary>
/// <param name="args">The argument builder into which the settings should be written.</param>
protected override void EvaluateCore(ProcessArgumentBuilder args)
{
base.EvaluateCore(args);

if (!string.IsNullOrWhiteSpace(Source))
{
args.AppendQuoted(Source);
}

if (Registry != null)
{
args.AppendSwitch("--registry", Registry.ToString());
}
}
}
}
58 changes: 58 additions & 0 deletions src/Cake.Npm/Publish/NpmPublishSettingsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace Cake.Npm.Publish
{
using System;

/// <summary>
/// Extensions for <see cref="NpmPublishSettings"/>.
/// </summary>
public static class NpmPublishSettingsExtensions
{
/// <summary>
/// Sets the source to publish.
/// </summary>
/// <param name="settings">The settings.</param>
/// <param name="source">Source to publish.
/// A folder containing a package.json file or an url or file path to a gzipped tar archive
/// containing a single folder with a package.json file inside.</param>
/// <returns>The <paramref name="settings"/> instance with <see cref="NpmPublishSettings.Source"/> set to <paramref name="source"/>.</returns>
public static NpmPublishSettings FromSource(this NpmPublishSettings settings, string source)
{
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}

if (string.IsNullOrWhiteSpace(source))
{
throw new ArgumentNullException(nameof(source));
}

settings.Source = source;

return settings;
}

/// <summary>
/// Sets the registry where the package will be published to.
/// </summary>
/// <param name="settings">The settings.</param>
/// <param name="registry">Registry where the package will be published to.</param>
/// <returns>The <paramref name="settings"/> instance with <see cref="NpmPublishSettings.Registry"/> set to <paramref name="registry"/>.</returns>
public static NpmPublishSettings ToRegistry(this NpmPublishSettings settings, Uri registry)
{
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}

if (registry == null)
{
throw new ArgumentNullException(nameof(registry));
}

settings.Registry = registry;

return settings;
}
}
}
46 changes: 46 additions & 0 deletions src/Cake.Npm/Publish/NpmPublisher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
namespace Cake.Npm.Publish
{
using System;
using Core;
using Core.Diagnostics;
using Core.IO;
using Core.Tooling;

/// <summary>
/// Tool for publishing npm modules.
/// </summary>
public class NpmPublisher : NpmTool<NpmPublishSettings>
{
/// <summary>
/// Initializes a new instance of the <see cref="NpmPublisher"/> class.
/// </summary>
/// <param name="fileSystem">The file system.</param>
/// <param name="environment">The environment.</param>
/// <param name="processRunner">The process runner.</param>
/// <param name="tools">The tool locator.</param>
/// <param name="log">Cake log instance.</param>
public NpmPublisher(
IFileSystem fileSystem,
ICakeEnvironment environment,
IProcessRunner processRunner,
IToolLocator tools,
ICakeLog log)
: base(fileSystem, environment, processRunner, tools, log)
{
}

/// <summary>
/// Publishes a npm package based on the specified settings.
/// </summary>
/// <param name="settings">The settings.</param>
public void Publish(NpmPublishSettings settings)
{
if (settings == null)
{
throw new ArgumentNullException(nameof(settings));
}

RunCore(settings);
}
}
}
106 changes: 106 additions & 0 deletions tests/Cake.Npm.Tests/Publish/NpmPublishSettingsExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
namespace Cake.Npm.Tests.Publish
{
using System;
using Cake.Npm.Publish;
using Shouldly;
using Xunit;

public sealed class NpmPublishSettingsExtensionsTests
{
public sealed class TheFromSourceMethod
{
[Fact]
public void Should_Throw_If_Settings_Are_Null()
{
// Given
NpmPublishSettings settings = null;

// When
var result = Record.Exception(() => settings.FromSource("foo"));

// Then
result.IsArgumentNullException("settings");
}

[Fact]
public void Should_Throw_If_Source_Is_Null()
{
// Given
var settings = new NpmPublishSettings();

// When
var result = Record.Exception(() => settings.FromSource(null));

// Then
result.IsArgumentNullException("source");
}

[Fact]
public void Should_Throw_If_Source_Is_Empty()
{
// Given
var settings = new NpmPublishSettings();

// When
var result = Record.Exception(() => settings.FromSource(string.Empty));

// Then
result.IsArgumentNullException("source");
}

[Fact]
public void Should_Throw_If_Source_Is_WhiteSpace()
{
// Given
var settings = new NpmPublishSettings();

// When
var result = Record.Exception(() => settings.FromSource(" "));

// Then
result.IsArgumentNullException("source");
}

[Fact]
public void Should_Set_Source()
{
// Given
var settings = new NpmPublishSettings();
var source = "foo";

// When
settings.FromSource(source);

// Then
settings.Source.ShouldBe(source);
}

[Fact]
public void Should_Throw_If_Registry_Is_Null()
{
// Given
var settings = new NpmPublishSettings();

// When
var result = Record.Exception(() => settings.ToRegistry(null));

// Then
result.IsArgumentNullException("registry");
}

[Fact]
public void Should_Set_Registry()
{
// Given
var settings = new NpmPublishSettings();
var registry = new Uri("https://example.com");

// When
settings.ToRegistry(registry);

// Then
settings.Registry.ShouldBe(registry);
}
}
}
}
Loading

0 comments on commit d57b486

Please sign in to comment.