2020-12-09 10:05:52 +01:00
using System ;
using System.Collections.Generic ;
using System.IO ;
using System.Linq ;
using ln.build.pipeline ;
using ln.build.semver ;
using ln.build.support.dotnet ;
using ln.logging ;
using ln.type ;
namespace ln.build.commands
{
public static class DotNetCommand
{
public static void Prepare ( Stage stage , params string [ ] arguments )
{
2020-12-09 11:03:03 +01:00
if ( Directory . Exists ( Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" ) ) )
Directory . Delete ( Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" ) , true ) ;
2020-12-09 10:05:52 +01:00
List < string > projectFiles = new List < string > ( ) ;
List < string > slnFiles = new List < string > ( ) ;
foreach ( string argument in arguments )
{
foreach ( string filename in PathHelper . ResolvePattern ( argument , stage . CommandEnvironment . WorkingDirectory ) )
{
stage . CommandEnvironment . Logger . Log ( LogLevel . INFO , "dotnet prepare: found {0}" , filename ) ;
if ( filename . EndsWith ( ".csproj" , StringComparison . InvariantCultureIgnoreCase ) )
projectFiles . Add ( filename ) ;
else
slnFiles . Add ( filename ) ;
}
}
// ToDo: Parse .sln files for referenced projects
2020-12-09 12:06:51 +01:00
SemVersion highestVersion = new SemVersion ( 0 , 0 , 0 ) ;
2020-12-09 10:05:52 +01:00
foreach ( string projectFileName in projectFiles )
{
CSProjHelper csp = new CSProjHelper ( projectFileName ) ;
string projectName = csp . GetName ( ) ;
SemVersion projectVersion = csp . GetVersion ( ) ;
string ot = csp . GetOutputType ( ) ;
stage . CommandEnvironment . Logger . Log ( LogLevel . INFO , "dotnet prepare: project {0} version={1} type={2}" , projectName , projectVersion , ot ) ;
2020-12-09 12:06:51 +01:00
2020-12-09 17:16:22 +01:00
if ( projectVersion = = null )
continue ;
2020-12-09 12:06:51 +01:00
if ( projectVersion > highestVersion )
highestVersion = projectVersion ;
2020-12-09 17:16:22 +01:00
stage . PipeLine . CommandEnvironment . Extend ( "DOTNET_PROJECTS" , projectFileName ) ;
2020-12-09 10:05:52 +01:00
}
2020-12-09 12:06:51 +01:00
stage . PipeLine . CommandEnvironment . Set ( "RELEASE_VERSION" , highestVersion . ToString ( ) ) ;
2020-12-09 10:05:52 +01:00
}
public static void Build ( Stage stage , params string [ ] arguments )
{
foreach ( string projectFileName in stage . CommandEnvironment . Get ( "DOTNET_PROJECTS" , "" ) . Split ( ':' ) )
{
new CommandRunner ( "dotnet" , "build" , projectFileName , new CommandRunner . Option ( "-c" , stage . CommandEnvironment . Get ( "DOTNET_CONFIGURATION" ) ) )
. Run ( stage . CommandEnvironment ) ;
}
}
public static void Pack ( Stage stage , params string [ ] arguments )
{
foreach ( string projectFileName in stage . CommandEnvironment . Get ( "DOTNET_PROJECTS" , "" ) . Split ( ':' ) )
{
CSProjHelper csProject = new CSProjHelper ( projectFileName ) ;
if ( ! csProject . GetOutputType ( ) . Equals ( "Library" ) )
{
stage . CommandEnvironment . Logger . Log ( LogLevel . WARNING , "dotnet pack: not packing {0} [{1}]" , projectFileName , csProject . GetOutputType ( ) ) ;
continue ;
}
stage . CommandEnvironment . Logger . Log ( LogLevel . WARNING , "dotnet pack: packing now {0} [{1}]" , projectFileName , csProject . GetOutputType ( ) ) ;
new CommandRunner ( "dotnet" , "pack" , projectFileName )
. AddArgument ( new CommandRunner . Option ( "-c" , stage . CommandEnvironment . Get ( "DOTNET_CONFIGURATION" ) ) )
2020-12-09 11:03:03 +01:00
. AddArguments ( "-o" , Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build/" ) )
2020-12-09 10:05:52 +01:00
. Run ( stage . CommandEnvironment ) ;
2020-12-09 11:03:03 +01:00
string artefact = String . Format ( Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" , "{0}.{1}.nupkg" ) , csProject . GetName ( ) , csProject . GetVersion ( ) ) ;
2020-12-09 10:05:52 +01:00
if ( ! File . Exists ( artefact ) )
throw new FileNotFoundException ( artefact ) ;
stage . PipeLine . CommandEnvironment . Extend ( "DOTNET_ARTEFACTS" , artefact ) ;
}
}
public static void Publish ( Stage stage , params string [ ] arguments )
{
List < string > projectFileNames = new List < string > ( ) ;
List < string > artefacts = new List < string > ( ) ;
if ( arguments . Length = = 0 )
projectFileNames . AddRange ( stage . CommandEnvironment . Get ( "DOTNET_PROJECTS" , "" ) . Split ( ':' ) ) ;
else
projectFileNames . AddRange ( arguments ) ;
foreach ( string projectFileName in projectFileNames )
{
CSProjHelper csProject = new CSProjHelper ( projectFileName ) ;
if ( ! csProject . GetOutputType ( ) . Equals ( "Exe" ) )
{
stage . CommandEnvironment . Logger . Log ( LogLevel . WARNING , "dotnet publish: not publishing {0} [{1}]" , projectFileName , csProject . GetOutputType ( ) ) ;
continue ;
}
stage . CommandEnvironment . Logger . Log ( LogLevel . WARNING , "dotnet publish: publishing now {0} [{1}]" , projectFileName , csProject . GetOutputType ( ) ) ;
CommandRunner cr = new CommandRunner ( "dotnet" , "publish" , projectFileName )
. AddArgument ( new CommandRunner . Option ( "-c" , stage . CommandEnvironment . Get ( "DOTNET_CONFIGURATION" ) ) )
. AddArguments ( "-p:PublishTrimmed=true" , "-p:PublishSingleFile=true" , "-p:PublishReadyToRun=false" ) ;
2020-12-09 11:03:03 +01:00
CommandRunner . Option outputOption = new CommandRunner . Option ( "-o" , Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" ) ) ;
2020-12-09 10:05:52 +01:00
cr . AddArgument ( outputOption ) ;
string [ ] rids = stage . CommandEnvironment . Get ( "DOTNET_RIDS" , "" ) . Split ( ':' ) ;
stage . CommandEnvironment . Logger . Log ( LogLevel . INFO , "dotnet publish: using rids: {0}" , string . Join ( ' ' , rids ) ) ;
if ( rids . Length = = 0 )
{
cr . Run ( stage . CommandEnvironment ) ;
} else
{
CommandRunner . Option ridOption = new CommandRunner . Option ( "-r" , "" ) ;
cr . AddArgument ( ridOption ) ;
cr . AddArgument ( "--self-contained" ) ;
foreach ( string rid in rids )
{
ridOption . SetValue ( rid ) ;
2020-12-09 11:03:03 +01:00
outputOption . SetValue ( Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" , rid ) ) ;
2020-12-09 10:05:52 +01:00
cr . Run ( stage . CommandEnvironment ) ;
2020-12-09 11:03:03 +01:00
string artefact = Directory . GetFiles ( Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" , rid ) ) . Where ( ( fn ) = > ! fn . EndsWith ( ".pdb" ) ) . FirstOrDefault ( ) ;
2020-12-09 10:05:52 +01:00
if ( artefact ! = null )
{
string ext = Path . GetExtension ( artefact ) ;
if ( ! ext . Equals ( ".exe" ) )
ext = "" ;
2020-12-09 11:03:03 +01:00
string finalName = Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" , string . Format ( "{0}-{3}-{1}{2}" , csProject . GetName ( ) , rid , ext , csProject . GetVersion ( ) ) ) ;
2020-12-09 10:05:52 +01:00
File . Move ( artefact , finalName ) ;
artefacts . Add ( finalName ) ;
stage . PipeLine . CommandEnvironment . Extend ( "DOTNET_ARTEFACTS" , finalName ) ;
2020-12-09 11:03:03 +01:00
Directory . Delete ( Path . Combine ( stage . CommandEnvironment . WorkingDirectory , ".build" , rid ) , true ) ;
2020-12-09 10:05:52 +01:00
}
}
}
}
stage . CommandEnvironment . Logger . Log ( LogLevel . INFO , "dotnet publish: created the following artefacts: {0}" , string . Join ( ' ' , artefacts ) ) ;
}
public static void Test ( Stage stage , params string [ ] arguments )
{
foreach ( string projectFileName in stage . CommandEnvironment . Get ( "DOTNET_PROJECTS" , "" ) . Split ( ':' ) )
{
new CommandRunner ( "dotnet" , "test" , projectFileName , new CommandRunner . Option ( "-c" , stage . CommandEnvironment . Get ( "DOTNET_CONFIGURATION" ) ) )
. Run ( stage . CommandEnvironment ) ;
}
}
public static void Push ( Stage stage , params string [ ] arguments )
{
if ( stage . CommandEnvironment . SecretStorage = = null )
{
stage . CommandEnvironment . Logger . Log ( LogLevel . WARNING , "dotnet push: no SecretStorage available, push operations are going to fail without authorization!" ) ;
} else {
stage . CommandEnvironment . Logger . Log ( LogLevel . INFO , "dotnet push: using secrets from {0}" , stage . CommandEnvironment . SecretStorage . FileName ) ;
}
string [ ] nupkgList = stage . CommandEnvironment . Get ( "DOTNET_ARTEFACTS" , "" ) . Split ( ':' ) . Where ( ( fn ) = > fn . EndsWith ( ".nupkg" ) ) . ToArray ( ) ;
string [ ] binaryList = stage . CommandEnvironment . Get ( "DOTNET_ARTEFACTS" , "" ) . Split ( ':' ) . Where ( ( fn ) = > ! fn . EndsWith ( ".nupkg" ) ) . ToArray ( ) ;
2020-12-09 12:06:51 +01:00
foreach ( string binaryArtefact in binaryList )
{
stage . PipeLine . CommandEnvironment . Extend ( "RELEASE_ARTEFACTS" , binaryArtefact ) ;
}
2020-12-09 10:05:52 +01:00
if ( nupkgList . Length > 0 )
{
string nugetSource = stage . CommandEnvironment . Get ( "NUGET_SOURCE" ) ;
string nugetApiKey = null ;
if ( ! ( stage . CommandEnvironment . SecretStorage ? . TryGetSecret ( nugetSource , out nugetApiKey ) ? ? false ) )
{
URI uriNuget = new URI ( nugetSource ) ;
stage . CommandEnvironment . SecretStorage ? . TryGetSecret ( new URI ( uriNuget . Scheme , uriNuget . Authority , "" ) . ToString ( ) , out nugetApiKey ) ;
}
CommandRunner cr = new CommandRunner ( "dotnet" , "nuget" , "push" ) ;
CommandRunner . Argument argNupkg = new CommandRunner . Argument ( "" ) ;
cr . AddArgument ( argNupkg ) ;
CommandRunner . Option optSource = new CommandRunner . Option ( "-s" , nugetSource ) ;
cr . AddArgument ( optSource ) ;
CommandRunner . Option optApiKey = new CommandRunner . Option ( "-k" , nugetApiKey ) ;
cr . AddArgument ( optApiKey ) ;
foreach ( string nupkg in nupkgList )
{
argNupkg . SetValue ( nupkg ) ;
cr . Run ( stage . CommandEnvironment ) ;
2020-12-09 12:06:51 +01:00
stage . PipeLine . CommandEnvironment . Extend ( "RELEASE_ARTEFACTS" , nupkg ) ;
2020-12-09 10:05:52 +01:00
}
}
}
}
}