diff --git a/.gitignore b/.gitignore
index 08cb4a8..3ca2406 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,17 @@ node_modules/
__pycache__/
*.pyc
*.pyo
+
+
+# .NET Core build assets
+tmp/dotnet/
+release/dotnet/
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
\ No newline at end of file
diff --git a/ReadMe.md b/ReadMe.md
index 56af35d..2c73e97 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -28,6 +28,7 @@ see: [100+ Working Service Examples](https://github.com/stackvana/microcule-exam
- coffee-script
- common lisp
- bash
+ - dotnet (.NET Core)
- lua
- golang
- ocaml
diff --git a/bin/microcule b/bin/microcule
index dfaf439..fd7a896 100755
--- a/bin/microcule
+++ b/bin/microcule
@@ -15,12 +15,12 @@ config.http.port = argv.p || argv.port || config.http.port;
config.watch = argv.w || argv.watch || config.watch;
config.stream = argv.s || argv.stream || config.stream;
-// default to releasing compiled binaries to current working directory of `microcule` binary
+// If no config, default to releasing compiled binaries to current working directory of `microcule` binary
config.releaseDir = config.releaseDir || process.cwd();
if (typeof argv.v !== "undefined" || typeof argv.version !== "undefined") {
- var pkg = require('../package.json')
- console.log(pkg.version)
+ var pkg = require('../package.json');
+ console.log(pkg.version);
process.exit();
}
@@ -48,6 +48,10 @@ var _service;
try {
_service = requireServiceSync({ path: servicePath });
+
+ //console.log('#### microcule: requireServiceSync() ######');
+ //console.dir(_service);
+
} catch (err) {
if (err.code === 'ENOENT') {
// if we could not find the service, attempt to see if it's a globally available binary
@@ -71,7 +75,7 @@ if (typeof argv.l !== "undefined" || typeof argv.language !== "undefined") {
}
if (stdin.isTTY) {
- // console.log('ignoring will not run in TTY mode')
+ //console.log('ignoring will not run in TTY mode')
// helps with peformance of STDIN tool
http = require('resource-http');
startServer(_service);
@@ -109,6 +113,7 @@ function startSTDIN (service) {
mode: 'stream'
};
+
var Readable = require('stream').Readable;
var Writable = require('stream').Writable;
@@ -116,7 +121,7 @@ function startSTDIN (service) {
var output = Writable();
output._write = function (chunk, enc, next) {
- // console.log('wirtint out',chunk.toString());
+ console.log('wirtint out',chunk.toString());
process.stdout.write(chunk);
next();
};
@@ -145,6 +150,7 @@ function startSTDIN (service) {
bin: service.bin,
argv: service.argv,
code: service.code,
+ originalCodeFilePath: service.originalCodeFilePath,
schema: service.schema,
view: service.view,
presenter: service.presenter,
@@ -153,7 +159,7 @@ function startSTDIN (service) {
config: config,
log: console.log
})(stdin, output, function(){
- // console.log("COMPLETED STREAMING SERVICE")
+ console.log("COMPLETED STREAMING SERVICE")
});
} else {
var result = '';
@@ -164,11 +170,12 @@ function startSTDIN (service) {
STDIN: result
}
};
- // console.log('spawning service'.yellow)
+ console.log('spawning service'.yellow)
microcule.plugins.spawn({
bin: service.bin,
argv: service.argv,
code: service.code,
+ originalCodeFilePath: service.originalCodeFilePath,
schema: service.schema,
view: service.view,
presenter: service.presenter,
@@ -208,7 +215,7 @@ function startServer (_service) {
console.log('using presenter for service')
}
- console.log(_service.language + ' microcule started at: http://' + addr.address + ":" + addr.port);
+ console.log(_service.language + ' microcule started at: http://'.blue + addr.address + ":" + addr.port);
// Remark: Will automatically map the process.env `microcule` was spawned in to the service.env of the spawned function
config.env = process.env;
@@ -233,9 +240,11 @@ function startServer (_service) {
spawnService(__service);
});
*/
+ console.log('1'.red);
spawnService(requireServiceSync({ path: servicePath }));
} else {
- spawnService(_service)
+ console.log('2'.red);
+ spawnService(_service);
}
function spawnService (service) {
@@ -248,10 +257,12 @@ function startServer (_service) {
if (err) {
return next(err);
}
+ console.log('3'.red);
microcule.plugins.spawn({
bin: service.bin,
argv: service.argv,
code: service.code,
+ originalCodeFilePath: service.originalCodeFilePath,
schema: service.schema,
view: service.view,
presenter: service.presenter,
@@ -266,10 +277,12 @@ function startServer (_service) {
});
});
} else {
+ console.log('4'.red);
microcule.plugins.spawn({
bin: service.bin,
argv: service.argv,
code: service.code,
+ originalCodeFilePath: service.originalCodeFilePath,
schema: service.schema,
view: service.view,
presenter: service.presenter,
diff --git a/config/index.js b/config/index.js
index 8684793..71cb614 100644
--- a/config/index.js
+++ b/config/index.js
@@ -10,10 +10,12 @@ module.exports = {
ca: [fs.readFileSync(__dirname + '/ssl/ca-crt.pem').toString()],
sslRequired: true, // redirects all http traffic to https, optional
onlySSL: false // will only start https server with no unprotected http interface, optional
+
},
SERVICE_MAX_TIMEOUT: 10000,
messages: {
childProcessSpawnError: require('./messages/childProcessSpawnError'),
serviceExecutionTimeout: require('./messages/serviceExecutionTimeout')
- }
+ },
+ releaseDir: process.cwd() + '/release'
};
\ No newline at end of file
diff --git a/examples/express-compiled-languages.js b/examples/express-compiled-languages.js
index a62bbcf..a21c27e 100644
--- a/examples/express-compiled-languages.js
+++ b/examples/express-compiled-languages.js
@@ -10,7 +10,7 @@ var service = {
var spawn = microcule.plugins.spawn(service);
app.use(function(req, res, next){
- console.log('attempting to spawn', service)
+ console.log('[express-compiled-languages.js] attempting to spawn ', service)
spawn(req, res, next);
});
diff --git a/examples/services/hello-world/dotnet-hello/Program.cs b/examples/services/hello-world/dotnet-hello/Program.cs
new file mode 100755
index 0000000..65ce358
--- /dev/null
+++ b/examples/services/hello-world/dotnet-hello/Program.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace dotnet_hello
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ Console.WriteLine("Hello World from .NET Core!!!");
+
+ foreach (var arg in args)
+ {
+ Console.WriteLine("param: {0}", arg);
+ }
+
+ }
+ }
+}
diff --git a/examples/services/hello-world/dotnet-hello/dotnet-hello.csproj b/examples/services/hello-world/dotnet-hello/dotnet-hello.csproj
new file mode 100755
index 0000000..97a38c1
--- /dev/null
+++ b/examples/services/hello-world/dotnet-hello/dotnet-hello.csproj
@@ -0,0 +1,7 @@
+
+
+
+ Exe
+ netcoreapp1.1
+
+
diff --git a/lib/plugins/compile/compileServiceCode/dotnet/index.js b/lib/plugins/compile/compileServiceCode/dotnet/index.js
new file mode 100644
index 0000000..37e23ed
--- /dev/null
+++ b/lib/plugins/compile/compileServiceCode/dotnet/index.js
@@ -0,0 +1,155 @@
+var fs = require('fs');
+var spawn = require('child_process').spawn;
+var crypto = require('crypto');
+var path = require('path');
+var ncp = require('ncp').ncp;
+var shasum = require('shasum');
+var path = require('path');
+
+module.exports = function (req, res, cb) {
+console.log('compileServiceCode.dotnet(). just executed'.yellow);
+ var service = req.service;
+
+ // TODO: override hash logic here to include the csproj contents.
+ // by default handled in compile/index.js and only used the code file
+ var hash = service.sha1;
+
+ console.log('inside compileServiceCode.dotnet()'.yellow)
+ console.dir(service);
+ /*
+ Supported Target: .NET Core 1.1
+ .NET Core 2.0 (untested)
+ Uasge:
+ - Standard .NET Core console app created via `dotnet new console -n `
+ - To execute run `microcule .//Program.cs`
+ */
+
+ //console.log('buildDir: ' + service.buildDir);
+ //console.log('releaseDir: ' + service.releaseDir);
+
+
+ // release is explicityly defaulted to the root of the microcule binary. Not sure why given there is a release folder.
+ // This may will break if the releaseDir default is overriden in config
+ //service.releaseDir = service.releaseDir + '/release';
+
+
+ // first, we need to write the file to a temporary location on the disk
+ // it could be possible to bypass writing to the disk entirely here, but it will be easier to debug user-scripts,
+ // and also interact with various compilers without having to look up special use cases for stdin / argv code parsing
+
+
+ //console.dir(service, { depth: null, colors: true });
+
+ var tmpBuildDir = service.buildDir + '/dotnet/' + hash;
+ var buildOutputDir = service.releaseDir + '/dotnet/' + hash;
+ //service.sourceCodeFilePath = '/Users/janaka.abeywardhana/code-projects/microcule/examples/services/hello-world/dotnet-hello/Program.cs';
+ //console.log('codefilepath = '.yellow, service.originalCodeFilePath);
+
+
+
+ // Create the folders we need. Because put code in a folders based on the hash we need to create folders it code changes.
+ // Logic for deciding if we needed re-build is in the shared complile logic.
+ if (!fs.existsSync(buildOutputDir)) {
+ fs.mkdirSync(buildOutputDir);
+ if (!fs.existsSync(tmpBuildDir)) {
+ fs.mkdirSync(tmpBuildDir);
+ }
+ }
+
+
+ console.log('Copy from ', service.originalSourceCodeDir, ' to ', tmpBuildDir);
+
+
+ ncp.limit = 5; // concurrent copies
+
+ ncp(service.originalSourceCodeDir, tmpBuildDir, function (err) {
+
+ if (err) {
+ return cb(err);
+ }
+ console.log('Successfully copied code to temp build dir');
+ console.log('starting dependency restore', 'dotnet restore');
+
+ var restore = spawn('dotnet', ['restore'], {
+ cwd: tmpBuildDir // ensure binary compiles to target directory
+ });
+
+ var stderr = '', stdout = '';
+
+ restore.on('error', function (data) {
+ console.log('error', data);
+ cb(data);
+ });
+
+
+ restore.on('exit', function (data) {
+ console.log('exit', data);
+
+ console.log('starting compiler dotnet', 'dotnet build -c release -v minimal -o ', buildOutputDir);
+
+ // command syntax: dotnet build -f 1.1 -c release -o