How do you set bashScriptExtraDefines? - sbt-native-packager

I have a project which needs to set $LD_LIBRARY_PATH to include some native shared objects. I believe all that I need to do is ensure that the JVM is launched with this environment variable set to a location inside my project's path (lib/linux-x86-64).
I figure that all I really need to do is make sure that bashScriptExtraDefines add an entry of export LD_LIBRARY_PATH=$lib_dir/linux-x86-64, however I cannot seem to figure out the correct way of setting it. I believe this is an issue with SBT 0.13 not being able to see these settings until they have all compiled, but there must be some way to do so.
I tried simply doing the following in my .sbt file:
bashScriptExtraDefines += "export LD_LIBRARY_PATH=$lib_dir/linux-x86-64"
and I tried changing my Project's settings in Build.scala file in the following way:
lazy val root = Project("my-project",file("."),Project.defaultSettings ++ Seq(bashScriptExtraDefines += "export LD_LIBRARY_PATH=$lib_dir/linux-x86-64"))
Neither method works correctly.

I learned that this setting can't be accessed in the regular scope since it seems to be limited to the Plugin's scope. The way to get around this is by accessing it out of the NativePackagerKeys object that the plugin exports. The following works inside my sbt file:
NativePackagerKeys.bashScriptExtraDefines += "export $LD_LIBRARY_PATH=$lib_dir/linux-x86-64"

Related

In a Kotlin multi-platform (or JS) project, (how) can one pass custom command line arguments to Node.js?

I'm working on a Kotlin multi-platform project, and I need my JS tests to run on Node.js but with custom command line arguments (specifically I need node to run with the --expose-gc flag, because some tests need to trigger garbage collection).
Looking at the documentation for the Gradle Kotlin JS DSL I didn't find any mention of how to do that; does anyone know whether it's at all possible and how?
Unfortunately can not answer your question directly, but there is some suggestion to help you with reverse engineering.
Let's start from some example. We have Gradle tasks to run our project using webpack's dev server such as browserDevelopmentRun, browserProductionRun (not sure if multi-platform projects have it, but JS projects do). We can add:
println(tasks.named("browserProductionRun").get().javaClass)
to build.gradle.kts to find out the exact class used for this task. When we sync Gradle, it outputs:
org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack_Decorated
Now we know the exact class of this task so we can investigate its API. The auto completion or navigating inside of the KotlinWebpack class helps us to find out that it has a helpful nodeArgs property to configure NodeJS arguments for it, so we can set them, for example:
tasks.named("browserProductionRun", org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack::class).get().nodeArgs.add("--trace-deprecation")
Getting back to your question.
In your case I guess you need to investigate the browserTest task. Let's get some info about it by adding:
println(tasks.named("browserTest").get().javaClass)
to build.gradle.kts - a-ha - it seems to be of the org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest_Decorated type. Let's check what's inside. Open KotlinJsTest.kt somehow - for example by typing its name into the window being opened by CMD + Shift + O (make sure to select "All Places" here) or just by typing its name somewhere in build.gradle.kts and navigating inside it.
The only interesting thing I see inside this open class is the following block:
override fun createTestExecutionSpec(): TCServiceMessagesTestExecutionSpec {
val forkOptions = DefaultProcessForkOptions(fileResolver)
forkOptions.workingDir = npmProject.dir
forkOptions.executable = nodeJs.requireConfigured().nodeExecutable
val nodeJsArgs = mutableListOf<String>()
return testFramework!!.createTestExecutionSpec(
task = this,
forkOptions = forkOptions,
nodeJsArgs = nodeJsArgs,
debug = debug
)
}
So maybe it can work out to create your own extension of this class, override its createTestExecutionSpec method and provide nodeJsArgs as you need inside it. After that you'll be needing to declare another Gradle task to launch tests inside build.gradle.kts which will use this new extended class.

Bypass NODE_ENV with node-config

I am trying to test my config files by validating them, nothing fancy, a schema, a list of envs, iterate over it, load the config and validate the variable against the schema.
Problem is, to do that, I currently have to set process.env.NODE_ENV. Since the tests have their own reserved config file, this mean if the tests were run in parrallel, it may happen that the test change the NODE_ENV variable when the other tests are loading the config, which while it doesn't seems likely to happens, still bother me.
A simple solution would be to be able to tell node-config to ignore the environment variable, and use a given value as if it was, something like require('config')('myNodeEnv'), but I couldn't find anything similar in the wiki nor the documentation. The closest is custom env variable, but this would just move the problem to another variable.
Instead of tests having their own config files, tests should load a same "base" test-config.
When a specific test needs to override a specific value it should override that specific value and not the entire config (needless to say, we need to make sure to fix the overridden value when the test finishes).
When we work as described above, it reduces the chances of any collision because the chances that different tests will override the exact same value at the exact same moment is very low.
Another option is to run tests separately, for example:
npm run test:suite1
npm run test:suite2
where test:suite1 could be declared in package.json under scripts section, for example:
"test:suite1": "NODE_ENV=test-conf-1 tests/suite1.js",
...

Is there a way to use a global variable for the whole npm project?

I need to use a variable between node modules folder and src folder.Is there a way to use a variable to be used within the whole project?
Thanks.
Typically this is done with process environment variables. Any project can look for a common environment variable and handle that case accordingly, as well as the node modules of said project. As long as they agree on the name, they all share the same environment. Have a good default, don't force people to set this environment variable.
The environment can be set using an environment file (do not check this into source control!), on your container or cloud configuration, or even right on the command line itself.
TLOG=info npm test
That is an example that I use frequently. My project runs logging for the test cases only at alert level - there are a lot of tests so it makes the output less verbose. However, sometimes while developing I want to see all the logs, so my project is looking for an environment variable TLOG (short for "test logging") and I can set it just for that run! Also no code change is needed, which is nicer than JavaScript variables that need to be set back to original values, forget to be turned off, etc.

Suave with netcoreapp2.0

I've been following this Suave tutorial:
https://legacy.gitbook.com/book/theimowski/suave-music-store/details
And in general this looks good. However, I was trying to make it work with Linux and for some reason I was unable to compile it with code when TargetFramework was set to "net461" (Target Framework not found), so I tried changing it to "netcoreapp2.0". It compiled, but I hit a problem later on:
https://theimowski.gitbooks.io/suave-music-store/content/en/css.html
At the end it says to add a WebPart:
pathRegex "(.*)\.(css|png)" >=> Files.browseHome
which fails for me. All compiles, but I get
This page isn’t working
localhost didn’t send any data.
I took a look at Suave's source code and it turned out that "Files.browseHome" searches for a file under "ctx.runtime.homeDirectory".
I noticed that this is set on my machine to:
/home/<my_user_name>/.nuget/packages/suave/2.2.1/lib/netstandard1.6
and obviously, that's not my project directory, so no wonder it couldn't find the file.
My question here is: what shall I do in order to make my Suave app handle my css/png files correctly using Files.browseHome ?
EDIT:
Just found out that replacing the WebPart with:
pathRegex "(.*)\.(css|png)" >=> Files.browse "/home/<my_username>/<path_to_my_project>/bin/Debug/netcoreapp2.0/"
works fine, but it looks ugly. Any idea how to make it better ? Basically I don't want to be forced to hardcode the absolute path anywhere.
I think the answer is to be found in https://suave.io/files.html, which suggests creating a config as follows:
let config =
{ defaultConfig with homeFolder = Some (Path.GetFullPath "./public") }
The path returned by Path.GetFullPath will depend on the current working directory that your app sees when it's started (which will, in turn, depend on how you start the app: from the command line, from a systemd unit file, etc.) There are too many possible variables here for me to be able to give you exact instructions, but if your startup method can cd into an appropriate folder before starting your Suave server, then that should solve your problem.
If you run into difficulties with getting the current working directory set correctly, then you could just hardcode the full path in the config:
let config =
{ defaultConfig with homeFolder = Some "/home/<your_username>/<path_to_your_project>/bin/Debug/netcoreapp2.0/" }
But that's kind of ugly, and not really portable (you'd have to modify that path again once you deploy the app). So I'd recommend the approach of making sure your start script does a cd to the right location, then using Path.GetFullPath with a relative path. Alternately, you could have a config file that gets read in at app startup where you specify the home path, or pass it in as an environment variable... All kinds of possibilities. Just make sure that your code can be handed some information on startup that specifies the correct "home" folder, and then put that in your Suave config as I've shown, and that should solve it.

minko / lua issue : premake5.lua:3: attempt to index global 'minko' (a nil value)

I am working with minko and managed to compile MINKO SDK properly for 3 platforms (Linux, Android, HTML5) and build all tutorials / examples. Moving on to create my own project, I followed the instructions on how to use the existing skeleton project, then using an existing example project.
(I believe there is an error in the skeleton code at this line :
auto sceneManager = SceneManager::create(canvas->context()); //does not compile
where as the example file look like this :
auto sceneManager = SceneManager::create(canvas); //compile and generate binary
I was able to do so by modifying premake5.lua (to include more plugins) and calling script/solution_gmake_gcc.sh
to generate the make solution a week ago. Today, I tried to make a new project in a new folder but calling
script/solution_gmake_gcc.sh and script/clean failed with this error:
minko-master/skel_tut/mycode/premake5.lua:3: attempt to index global 'minko' (a nil value)
Now at premake5.lua line 3 there is this line : minko.project.solution(PROJECT_NAME),
however sine i am not familiar with lua at all, can anyone shed any light on the issue ?
What is supposed to be declared here, why is it failing suddenly... ?
(I can still modify,compile and run the code but i can't for example add more plug-ins)
PS: weirdly enough, the previously 'working' project is also failing at this point.
Thanks.
PROJECT_NAME = path.getname(os.getcwd())
minko.project.application("minko-tutorial-" .. PROJECT_NAME)
files { "src/**.cpp", "src/**.hpp", "asset/**" }
includedirs { "src" }
-- plugins
minko.plugin.enable("sdl")
minko.plugin.enable("assimp")
minko.plugin.enable("jpeg")
minko.plugin.enable("bullet")
minko.plugin.enable("png")
--html overlay
minko.plugin.enable("html-overlay")
Assuming that's indeed your project premake5.lua file (please us the code tags next time), you should have include "script" at the beginning of the file:
https://github.com/aerys/minko/blob/master/skeleton/premake5.lua#L1
If you don't have this line, it will not include script/premake5.lua which is in charge of including the SDK build system files that defines everything inside the minko Lua namespace/table. That's why you get that error.
I think you copy pasted one of the examples/tutorials premake5.lua file instead of modifying the one provided by the skeleton. The premake conf file of the examples/tutorials are different since they are included from the SDK premake files. But your app premake5.lua does the "opposite": it includes the SDK conf files rather than being included by them.
The best practice is to edit your app's copy of the skeleton's premake5.lua (instead of copy/pasting one from the examples/tutorials).
(I believe there is an error in the skeleton code at this line :
That's possible. Our build server doesn't test the skeleton code. That's a mistake we will fix ASAP to make sure it works properly.
script/solution_gmake_gcc.sh and script/clean failed with this error:
minko-master/skel_tut/mycode/premake5.lua:3: attempt to index global 'minko' (a nil value)
Could you copy/paste your premake5.lua file?
Also, what's the value you set for the MINKO_HOME env var? Maybe you've moved the SDK...
Note that instead of setting a global MINKO_HOME env var, you can also set the corresponding LUA constant at the very begining of your premake5.lua file.

Resources