cake-build / cake

:cake: Cake (C# Make) is a cross platform build automation system.
https://cakebuild.net
MIT License
3.92k stars 731 forks source link

Honor #if when preprocessing #1860

Open bjorkstromm opened 7 years ago

bjorkstromm commented 7 years ago

Now that https://github.com/cake-build/cake/pull/1858 is merged it would be nice if script processing also would honor defines. E.g. conditionally load files or install addins/tools.

patriksvensson commented 7 years ago

@mholo65 According to @devlead's integration tests, this should work ootb with the Roslyn script engine (unless I misunderstood something).

patriksvensson commented 7 years ago

@mholo65 Ah, I read your issue again, and I misunderstood. Sorry.

bjorkstromm commented 7 years ago

😄 np. Yeah, according to @devlead's testing, not even csi.exe supports it. See https://github.com/cake-build/cake/issues/1766#issuecomment-333958357

patriksvensson commented 7 years ago

@mholo65 This is not a trivial problem to solve unless we want to implement our own preprocessor evaluator.

#if (DEBUG && !MYTEST)  
        Console.WriteLine("DEBUG is defined");  
#elif (!DEBUG && MYTEST)  
        Console.WriteLine("MYTEST is defined");  
#elif (DEBUG && MYTEST)  
        Console.WriteLine("DEBUG and MYTEST are defined");  
#else  
        Console.WriteLine("DEBUG and MYTEST are not defined");  
#endif 
devlead commented 7 years ago

I rather see us implementing conditionals in the directives themselves, than doing our own compiler, while there's great reward, I feel there's great risk, with the potential of coming back to haunt us multiple times. Also the more we diverge from standards, the harder tooling will be.

savornicesei commented 5 years ago

Hi all,

I was redirected here from gitter, when I asked about conditionally loading an addin.

If I want to query an Oracle database from windows and linux hosts (i.e. when running integration tests) I need 2 different packages: ODP.NET Core for linux if .NET core is installed and ODP.NET for windows. Another scenario is loading different db clients based on available databases on the machine but I can live with pulling down all supported clients packages.

Thanks, Simo

devlead commented 5 years ago

Oracle.ManagedDataAccess.Core is .NET Standard 2.0 so should be able to work both .NET & .NET Core, if you have a recent version of .NET framework.

If you utilize Cake global tool you can use the same runtime & Cake version on all platforms and .NET Framwork won't be an factor.

That said if you really need to load different assemblies for different environments, an hacky way would be to utilize environment variables

Example this script

#addin "nuget:https://api.nuget.org/v3/index.json?package=%ORACLE_MANAGED_DATA_ACCESS_PACKAGE%"

Information(typeof(Oracle.ManagedDataAccess.Client.OracleConnection).Assembly.Location);

Calles from PowerShell


$ENV:ORACLE_MANAGED_DATA_ACCESS_PACKAGE='Oracle.ManagedDataAccess&version=18.3.0'
cake .\odpcore.cake

$ENV:ORACLE_MANAGED_DATA_ACCESS_PACKAGE='Oracle.ManagedDataAccess.Core&version=2.18.3'
cake .\odpcore.cake

Will output

+ {path to tools}\Addins\Oracle.ManagedDataAccess.18.3.0\lib\net40\Oracle.ManagedDataAccess.dll
+ {path to tools}\Addins\Oracle.ManagedDataAccess.Core.2.18.3\lib\netstandard2.0\Oracle.ManagedDataAccess.dll

Both these examples used Cake.exe so it seems Oracle.ManagedDataAccess.Core was able to be loaded on full framework, didn't try to execute anything though.

Environment variable expanding works with all preprocessor directives so if there's multiple assemblies that differ between environments an have one cake file per environment.

and do something like #load "%MY_SCRIPT_ENVVAR%"

A less magical approach would be to have something like

+ full.cake
+ core.cake
+ build.cake

have addin directives that differ in full / core and then have them load build.cake i.e.

Full

#addin "nuget:https://api.nuget.org/v3/index.json?package=Oracle.ManagedDataAccess&version=18.3.0"
#load "build.cake"

Core

#addin "nuget:https://api.nuget.org/v3/index.json?package=Oracle.ManagedDataAccess.Core&version=2.18.3"
#load "build.cake"

Build

Information(typeof(Oracle.ManagedDataAccess.Client.OracleConnection).Assembly.Location);

And have either core.cake or full.cake be the entry point depending on environment.