Rollup tree-shakes imported variables, causing important code to be lost - rollupjs

I'm using rollup to bundle the build script for one of my projects. In the builds (their source is ts), I use node's worker_threads module to parallelize some work. I'm using an import of isMainThread (which is a boolean from the worker_threads module) to check whether or not to use the worker logic or the main thread logic. However, when building the build script from its source, rollup is removing the else statement. It seems to be checking the isMainThread variable during its tree-shaking process, and deciding that isMainThread will always be true, and so the else statement isn't needed. How can I change that logic?
Source:
if (isMainThread) {
const { dev, watch } = getOptions(process.argv);
if (watch) watcher(dev);
else singleBuild(dev);
} else {
worker();
}
Output:
if (isMainThread) {
const { dev, watch } = getOptions(process.argv);
if (watch)
watcher();
else
singleBuild();
}

Related

Inform Jenkins about failed TestNG tests from Gradle run task to mark build as Failed

For the reasons I cannot influence, there is the following mechanism on TestNG launching on the project.
In a word, it creates a new instance of TestNG, adds listeners, specifies classes and runs the tests. Then, all this dirty code is called from Gradle run task (which is actually empty and as far as I understood, simply calls the TestManager.main() method).
I removed the part of code just to show the main direction:
class TestManager {
static void main(String[] args) {
try {
runTests(args[0])
} catch (Exception e) {
e.printStackTrace()
System.in.read()
}
}
private static void runTests(Application app) {
TagsConfig.runs.each { run ->
if (run.execute) {
List<TagsSuite> suites = TagsConfig.suites
suites.each { suite ->
if (suite.execute) {
Reflections reflections = new Reflections("${app.packageName}.${suite.name}")
def classes = reflections.getSubTypesOf(${suite.name})
if (classes.size() > 0) {
TestNG testNG = new TestNG()
testNG.testClasses = classes
testNG.groupByInstances = true
testNG.outputDirectory = "testng-output"
testNG.addListener(new TestListenerAdapter())
testNG.addListener(new ExceptionListener())
testNG.addListener(new AllureTestListener())
if (TagsConfig.isSmoke) {
testNG.setGroups("smoke")
} else if (TagsConfig.isExtendedSmoke) {
testNG.setGroups("extended_smoke")
}
testNG.run()
}
}
}
}
}
}
So the test launch looks like this:
gradle clean
gradle run
I can not change the way the tests are started now and one of the problems is that the build in Jenkins is always Sucessful even if there are failed/broken/skipped tests.
So, I can get the number of failed tests from TestListenerAdapter, but how can I let Jenkins know that there were failed tests?
Maybe by returning an exit code from a Gradle run task or by installing some plugin that will check the count of failed tests in TestListenerAdapter?
For now, I'm setting a "FAILED_TESTS_COUNT" system property in onFinish() event and change the build status in pipeline if it is not 0, but this looks really dirty.
Jenkins 2.89.3
Gradle 3.5.1
TestNG 6.9.8
I personally use the Jenkins Text Finder post-build action. In the above example, it looks for a pattern in the standard output and set the build to "unstable" (orange) when it's found.
In your case, just uncheck both checkboxes and find the according matching pattern.

Groovy - How to reflect code from another groovy app to find Classes/Properties/Types within

First, I came from a .NET background so please excuse my lack of groovy lingo. Back when I was in a .NET shop, we were using TypeScript with C# to build web apps. In our controllers, we would always receive/respond with DTOs (data xfer objects). This got to be quite the headache every time you create/modify a DTO you had to update the TypeScript interface (the d.ts file) that corresponded to it.
So we created a little app (a simple exe) that loaded the dll from the webapp into it, then reflected over it to find the DTOs (filtering by specific namespaces), and parse through them to find each class name within, their properties, and their properties' data types, generate that information into a string, and finally saved as into a d.ts file.
This app was then configured to run on every build of the website. That way, when you go to run/debug/build the website, it would update your d.ts files automatically - which made working with TypeScript that much easier.
Long story short, how could I achieve this with a Grails Website if I were to write a simple groovy app to generate the d.ts that I want?
-- OR --
How do I get the IDE (ex IntelliJ) to run a groovy file (that is part of the app) that does this generation post-build?
I did find this but still need a way to run on compile:
Groovy property iteration
class Foo {
def feck = "fe"
def arse = "ar"
def drink = "dr"
}
class Foo2 {
def feck = "fe2"
def arse = "ar2"
def drink = "dr2"
}
def f = new Foo()
def f2 = new Foo2()
f2.properties.each { prop, val ->
if(prop in ["metaClass","class"]) return
if(f.hasProperty(prop)) f[prop] = val
}
assert f.feck == "fe2"
assert f.arse == "ar2"
assert f.drink == "dr2"
I've been able to extract the Domain Objects and their persistent fields via the following Gant script:
In scripts/Props.groovy:
import static groovy.json.JsonOutput.*
includeTargets << grailsScript("_GrailsBootstrap")
target(props: "Lists persistent properties for each domain class") {
depends(loadApp)
def propMap = [:].withDefault { [] }
grailsApp.domainClasses.each {
it?.persistentProperties?.each { prop ->
if (prop.hasProperty('name') && prop.name) {
propMap[it.clazz.name] << ["${prop.name}": "${prop.getType()?.name}"]
}
}
}
// do any necessary file I/O here (just printing it now as an example)
println prettyPrint(toJson(propMap))
}
setDefaultTarget(props)
This can be run via the command line like so:
grails props
Which produces output like the following:
{
"com.mycompany.User": [
{ "type": "java.lang.String" },
{ "username": "java.lang.String" },
{ "password": "java.lang.String" }
],
"com.mycompany.Person": [
{ "name": "java.lang.String" },
{ "alive": "java.lang.Boolean" }
]
}
A couple of drawbacks to this approach is that we don't get any transient properties and I'm not exactly sure how to hook this into the _Events.groovy eventCompileEnd event.
Thanks Kevin! Just wanted to mention, in order to get this to run, here are a few steps I had to make sure to do in my case that I thought I would share:
-> Open up the grails BuildConfig.groovy
-> Change tomcat from build to compile like this:
plugins {
compile ":tomcat:[version]"
}
-> Drop your Props.groovy into the scripts folder on the root (noting the path to the grails-app folder for reference)
[application root]/scripts/Props.groovy
[application root]/grails-app
-> Open Terminal
gvm use grails [version]
grails compile
grails Props
Note: I was using Grails 2.3.11 for the project I was running this on.
That gets everything in your script to run successfully for me. Now to modify the println portion to generate Typescript interfaces.
Will post a github link when it is ready so be sure to check back.

How does electron handle global dependencies

I'm new to electron. I'm building an app that uses ffmpeg and sox, which are installed globally. How do I guarantee that these dependencies will be installed on the users computer?
Try this, it is not specific to electron, but can help
http://12factor.net/dependencies
There could be two kind of system level dependencies:
NPM based package expected to be installed at a system level
Non NPM package, like a system level library(in your case ffmpeg)
For NPM based package, you can do a peer dependency like the following:
{
....
"peerDependencies": {
"chai": "1.x"
}
....
}
For non NPM package, usual pattern is to check this during your application start flow and inform the user if it's not available.
Answering specific to ffmpeg, following should help:
/**
* Check for ffmpeg availability
*
* If the FFMPEG_PATH environment variable is set, try to use it.
* If it is unset or incorrect, try to find ffmpeg in the PATH instead.
*
* #method FfmpegCommand#_getFfmpegPath
* #param {Function} callback callback with signature (err, path)
* #private
*/
proto._getFfmpegPath = function(callback) {
if ('ffmpegPath' in cache) {
return callback(null, cache.ffmpegPath);
}
async.waterfall([
// Try FFMPEG_PATH
function(cb) {
if (process.env.FFMPEG_PATH) {
fs.exists(process.env.FFMPEG_PATH, function(exists) {
if (exists) {
cb(null, process.env.FFMPEG_PATH);
} else {
cb(null, '');
}
});
} else {
cb(null, '');
}
},
// Search in the PATH
function(ffmpeg, cb) {
if (ffmpeg.length) {
return cb(null, ffmpeg);
}
utils.which('ffmpeg', function(err, ffmpeg) {
cb(err, ffmpeg);
});
}
], function(err, ffmpeg) {
if (err) {
callback(err);
} else {
callback(null, cache.ffmpegPath = (ffmpeg || ''));
}
});
};
The above code is taken from here. node-fluent-ffmpeg is a nice project which works on top of ffmpeg. I believe, it will be a good reference for your project.
You could package the different installers for the dependencies with your app, then create a custom installer for your app that also launches the dependency installers in sequence, or simply prompt the user to install the dependencies themselves and link them to a download page.
There are lots of resources for creating installers, try a google search for electron installer for your specific platform.
sorry I'm late to the party but just in case this is still relevant - I've created ffbinaries module specifically for this purpose.
You can check it out on npm, it'll simply download the binaries on user machine during app boot, the platform will be detected automatically (you can override it though if you're planning to include it in CI of some sort).

Copying default external configuration on first run of Grails web app

In our Grails web applications, we'd like to use external configuration files so that we can change the configuration without releasing a new version. We'd also like these files to be outside of the application directory so that they stay unchanged during continuous integration.
The last thing we need to do is to make sure the external configuration files exist. If they don't, then we'd like to create them, fill them with predefined content (production environment defaults) and then use them as if they existed before. This allows any administrator to change settings of the application without detailed knowledge of the options actually available.
For this purpose, there's a couple of files within web-app/WEB-INF/conf ready to be copied to the external configuration location upon the first run of the application.
So far so good. But we need to do this before the application is initialized so that production-related modifications to data sources definitions are taken into account.
I can do the copy-and-load operation inside the Config.groovy file, but I don't know the absolute location of the WEB-INF/conf directory at the moment.
How can I get the location during this early phase of initialization? Is there any other solution to the problem?
There is a best practice for this.
In general, never write to the folder where the application is deployed. You have no control over it. The next rollout will remove everything you wrote there.
Instead, leverage the builtin configuration capabilities the real pro's use (Spring and/or JPA).
JNDI is the norm for looking up resources like databases, files and URL's.
Operations will have to configure JNDI, but they appreciate the attention.
They also need an initial set of configuration files, and be prepared to make changes at times as required by the development team.
As always, all configuration files should be in your source code repo.
I finally managed to solve this myself by using the Java's ability to locate resources placed on the classpath.
I took the .groovy files later to be copied outside, placed them into the grails-app/conf directory (which is on the classpath) and appended a suffix to their name so that they wouldn't get compiled upon packaging the application. So now I have *Config.groovy files containing configuration defaults (for all environments) and *Config.groovy.production files containing defaults for production environment (overriding the precompiled defaults).
Now - Config.groovy starts like this:
grails.config.defaults.locations = [ EmailConfig, AccessConfig, LogConfig, SecurityConfig ]
environments {
production {
grails.config.locations = ConfigUtils.getExternalConfigFiles(
'.production',
"${userHome}${File.separator}.config${File.separator}${appName}",
'AccessConfig.groovy',
'Config.groovy',
'DataSource.groovy',
'EmailConfig.groovy',
'LogConfig.groovy',
'SecurityConfig.groovy'
)
}
}
Then the ConfigUtils class:
public class ConfigUtils {
// Log4j may not be initialized yet
private static final Logger LOG = Logger.getGlobal()
public static def getExternalConfigFiles(final String defaultSuffix, final String externalConfigFilesLocation, final String... externalConfigFiles) {
final def externalConfigFilesDir = new File(externalConfigFilesLocation)
LOG.info "Loading configuration from ${externalConfigFilesDir}"
if (!externalConfigFilesDir.exists()) {
LOG.warning "${externalConfigFilesDir} not found. Creating..."
try {
externalConfigFilesDir.mkdirs()
} catch (e) {
LOG.severe "Failed to create external configuration storage. Default configuration will be used."
e.printStackTrace()
return []
}
}
final def cl = ConfigUtils.class.getClassLoader()
def result = []
externalConfigFiles.each {
final def file = new File(externalConfigFilesDir, it)
if (file.exists()) {
result << file.toURI().toURL()
return
}
final def error = false
final def defaultFileURL = cl.getResource(it + defaultSuffix)
final def defaultFile
if (defaultFileURL) {
defaultFile = new File(defaultFileURL.toURI())
error = !defaultFile.exists();
} else {
error = true
}
if (error) {
LOG.severe "Neither of ${file} or ${defaultFile} exists. Skipping..."
return
}
LOG.warning "${file} does not exist. Copying ${defaultFile} -> ${file}..."
try {
FileUtils.copyFile(defaultFile, file)
} catch (e) {
LOG.severe "Couldn't copy ${defaultFile} -> ${file}. Skipping..."
e.printStackTrace()
return
}
result << file.toURI().toURL()
}
return result
}
}

Dart - How do you write a test against a function that calls exit()?

I want to test a function that calls exit.
Basicly, I have a console application, that asks the user if he is sure that he wants a directory to be overwritten. When the users answers "No", the directory won't be overwritten, and the program should exit.
promptToDeleteRepo() {
bool okToDelete = ...
if(okToDelete) {
deleteRepo();
} else {
exit(0);
}
}
So I want to test that if the user answers "No", that the program really exits. But if I test this, my test runner exits.
In python I seem to be able to do something like:
with pytest.raises(SystemExit):
promptToDeleteRepo();
Is there something like this in Dart?
You can inject a custom exit function during the tests.
import 'dart:io' as io;
typedef ExitFn(int code);
ExitFn exit = io.exit;
promptToDeleteRepo() {
bool okToDelete = ...
if(okToDelete) {
deleteRepo();
} else {
exit(0);
}
}
and in your test :
int exitCodeUsed;
mylib.exit = (int code) {exitCodeUsed = code};
mylib.promptToDeleteRepo();
A better solution whould have to use zones but there doesn't seem to be possible to handle exit. It could be worth to file an issue.
One option that comes to my mind is to run the code you want to test in a new process Process.run() or Process.start() and check the exit code at the end. You can use stdin/stdout to communicate with the process (send keyboard input, read output)

Resources