How to create a file by registerMultiTask (gruntjs) - gruntjs

I want gruntjs to create a file on each build that contains some PHP code to define a version number.
the following code fragments are in my grunt.initConfig:
1st some meta
meta: {
versionfile: '<?php \n' +
'define(\'VERSION\', \'<%= grunt.template.today("yyyymmddhhii") =%>\'); \n' +
'?>'
}
2nd the configuration
versionfile: {
'lib/define-version.php': '<%= meta.versionfile %>'
}
and then the multitask definition
grunt.registerMultiTask('versionfile', 'create version file.', function() {
grunt.file.write(this.target, this.data);
});
when I run the job the following error comes up and the file is not written:
Running "versionfile:lib/define-version.php" (versionfile) task
Warning: An error occurred while processing a template (Unexpected token )). Use --force to continue.
I am thankful for every hint on what exactly this error means.
Maybe there is another way to write a file containing the php-code?

I found the error. The correct configuration has a = too much.
Instead of
'define(\'VERSION\', \'<%= grunt.template.today("yyyymmddhhii") =%>\'); \n' +
it must be
'define(\'VERSION\', \'<%= grunt.template.today("yyyymmddhhMM") %>\'); \n' +
(ignore the ii>MM, that's just another error ;)

Related

path not being detected by Nextflow

i'm new to nf-core/nextflow and needless to say the documentation does not reflect what might be actually implemented. But i'm defining the basic pipeline below:
nextflow.enable.dsl=2
process RUNBLAST{
input:
val thr
path query
path db
path output
output:
path output
script:
"""
blastn -query ${query} -db ${db} -out ${output} -num_threads ${thr}
"""
}
workflow{
//println "I want to BLAST $params.query to $params.dbDir/$params.dbName using $params.threads CPUs and output it to $params.outdir"
RUNBLAST(params.threads,params.query,params.dbDir, params.output)
}
Then i'm executing the pipeline with
nextflow run main.nf --query test2.fa --dbDir blast/blastDB
Then i get the following error:
N E X T F L O W ~ version 22.10.6
Launching `main.nf` [dreamy_hugle] DSL2 - revision: c388cf8f31
Error executing process > 'RUNBLAST'
Error executing process > 'RUNBLAST'
Caused by:
Not a valid path value: 'test2.fa'
Tip: you can replicate the issue by changing to the process work dir and entering the command bash .command.run
I know test2.fa exists in the current directory:
(nfcore) MN:nf-core-basicblast jraygozagaray$ ls
CHANGELOG.md conf other.nf
CITATIONS.md docs pyproject.toml
CODE_OF_CONDUCT.md lib subworkflows
LICENSE main.nf test.fa
README.md modules test2.fa
assets modules.json work
bin nextflow.config workflows
blast nextflow_schema.json
I also tried with "file" instead of path but that is deprecated and raises other kind of errors.
It'll be helpful to know how to fix this to get myself started with the pipeline building process.
Shouldn't nextflow copy the file to the execution path?
Thanks
You get the above error because params.query is not actually a path value. It's probably just a simple String or GString. The solution is to instead supply a file object, for example:
workflow {
query = file(params.query)
BLAST( query, ... )
}
Note that a value channel is implicitly created by a process when it is invoked with a simple value, like the above file object. If you need to be able to BLAST multiple query files, you'll instead need a queue channel, which can be created using the fromPath factory method, for example:
params.query = "${baseDir}/data/*.fa"
params.db = "${baseDir}/blastdb/nt"
params.outdir = './results'
db_name = file(params.db).name
db_path = file(params.db).parent
process BLAST {
publishDir(
path: "{params.outdir}/blast",
mode: 'copy',
)
input:
tuple val(query_id), path(query)
path db
output:
tuple val(query_id), path("${query_id}.out")
"""
blastn \\
-num_threads ${task.cpus} \\
-query "${query}" \\
-db "${db}/${db_name}" \\
-out "${query_id}.out"
"""
}
workflow{
Channel
.fromPath( params.query )
.map { file -> tuple(file.baseName, file) }
.set { query_ch }
BLAST( query_ch, db_path )
}
Note that the usual way to specify the number of threads/cpus is using cpus directive, which can be configured using a process selector in your nextflow.config. For example:
process {
withName: BLAST {
cpus = 4
}
}

QBS: Explicitly setting qbs.profiles inside Products causing build to fail

My use-case is this:
I have a static library which I want to be available for some profiles (e.g. "gcc", "arm-gcc", "mips-gcc").
I also have an application which links to this library, but this applications should only build using a specific profile (e.g. "arm-gcc").
For this I am modifying the app-and-lib QBS example.
The lib.qbs file:
import qbs 1.0
Product {
qbs.profiles: ["gcc", "arm-gcc", "mips-gcc"] //I added only this line
type: "staticlibrary"
name: "mylib"
files: [
"lib.cpp",
"lib.h",
]
Depends { name: 'cpp' }
cpp.defines: ['CRUCIAL_DEFINE']
Export {
Depends { name: "cpp" }
cpp.includePaths: [product.sourceDirectory]
}
}
The app.qbs file:
import qbs 1.0
Product {
qbs.profiles: ["arm-gcc"] //I added only this line
type: "application"
consoleApplication: true
files : [ "main.cpp" ]
Depends { name: "cpp" }
Depends { name: "mylib" }
}
The app build fails. Qbs wrongly tries to link to the "gcc" version of the library instead of the "arm-gcc" version, as you can see in the log:
Build graph does not yet exist for configuration 'default'. Starting from scratch.
Resolving project for configuration default
Setting up build graph for configuration default
Building for configuration default
compiling lib.cpp [mylib {"profile":"gcc"}]
compiling lib.cpp [mylib {"profile":"arm-gcc"}]
compiling lib.cpp [mylib {"profile":"mips-gcc"}]
compiling main.cpp [app]
creating libmylib.a [mylib {"profile":"gcc"}]
creating libmylib.a [mylib {"profile":"mips-gcc"}]
creating libmylib.a [mylib {"profile":"arm-gcc"}]
linking app [app]
ERROR: /usr/bin/arm-linux-gnueabihf-g++ -o /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/app.7d104347/app /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/app.7d104347/3a52ce780950d4d9/main.cpp.o /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/mylib.eyJwcm9maWxlIjoiZ2NjIn0-.792f47ec/libmylib.a
ERROR: /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/mylib.eyJwcm9maWxlIjoiZ2NjIn0-.792f47ec/libmylib.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
ERROR: Process failed with exit code 1.
The following products could not be built for configuration default:
app
The build fails only when selecting one profile in the app.qbs file, and this profile should not be the first profile in the qbs.profiles line in the lib.qbs file.
When selecting two or more profiles - the build succeeds.
My analysis:
I think this problem is related to multiplexing:
The lib.qbs contains more than one profile. This turns on multiplexing when building the library, which, in turn, adds additional 'multiplexConfigurationId' to the build-directory name (moduleloader.cpp).
The app.lib contains only one profile, so multiplexing is not turned on and the build-directory name does not get the extra string.
The problem can be solved by changing the code (moduleloader.cpp) so that multiplexing is turned even if there is only one profile i.e. with the following patch:
--- moduleloader.cpp 2018-10-24 16:17:43.633527397 +0300
+++ moduleloader.cpp.new 2018-10-24 16:18:27.541370544 +0300
## -872,7 +872,7 ##
= callWithTemporaryBaseModule<const MultiplexInfo>(dummyContext,
extractMultiplexInfoFromProduct);
- if (multiplexInfo.table.size() > 1)
+ if (multiplexInfo.table.size() > 0)
productItem->setProperty(StringConstants::multiplexedProperty(), VariantValue::trueValue());
VariantValuePtr productNameValue = VariantValue::create(productName);
## -891,7 +891,7 ##
const QString multiplexConfigurationId = multiplexInfo.toIdString(row);
const VariantValuePtr multiplexConfigurationIdValue
= VariantValue::create(multiplexConfigurationId);
- if (multiplexInfo.table.size() > 1 || aggregator) {
+ if (multiplexInfo.table.size() > 0 || aggregator) {
multiplexConfigurationIdValues.push_back(multiplexConfigurationIdValue);
item->setProperty(StringConstants::multiplexConfigurationIdProperty(),
multiplexConfigurationIdValue);
This worked for my use case. I don't know if it make sense in a broader view.
Finally, the questions:
Does it all make sense?
Is this a normal behavior?
Is this use-case simply not supported?
Is there a better solution?
Thanks in advance.
Yes, the default behavior with multiplexing is that the a non-multiplexed product depends on all variants of the dependency. In general, there is no way for a user to change that behavior, but there should be.
However, luckily for you, profiles are special:
Depends { name: "mylib"; profiles: "arm-gcc" }
This should fix your problem.

mruby-require error: NoMethodError: undefined method 'puts' for main

I managed to compile the mruby code adding the mrubygem - mruby-require from https://github.com/mattn/mruby-require
However when I try to call the require './' I get an error. Below is my code:
inc.rb
def test(a, b)
print "Inside the include->test(..)"
return a+b
end
test1.rb
require 'inc.rb'
def helloworld(var1)
print 'hello world ' + var1 + ". Test number = " + test(4, 5)
end
helloworld('test')
When I execute test1.rb I get this error from mruby:
NoMethodError: undefined method 'puts' for main
After some analysis I found out the 'puts' is not working with mruby. Infact after adding mruby-require gem, no ruby code gets execute. Do I need to add any dependency with mruby-require?
Can someone help me please?
Update: Pasting the content of build_config.rb as requested. I have removed the lines which are commented.
build_config.rb
MRuby::Build.new do |conf|
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
toolchain :visualcpp
else
toolchain :gcc
end
enable_debug
# adding the mruby-require library
conf.gem 'mrbgems/mruby-require'
conf.gembox 'default'
end
MRuby::Build.new('host-debug') do |conf|
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
toolchain :visualcpp
else
toolchain :gcc
end
enable_debug
conf.gembox 'default'
conf.cc.defines = %w(ENABLE_DEBUG)
conf.gem :core => "mruby-bin-debugger"
end
The following quote is from its README.md:
When mruby-require is being used, additional mrbgems that appear after mruby-require in build_config.rb must be required to be used.
This is from your build_config.rb:
conf.gem 'mrbgems/mruby-require'
conf.gembox 'default'
The default gembox contains mruby-print. So either require mruby-print or preferably swap the lines to make it a built-in gem (the default behavior without mruby-require).

How to get grunt task name given on command line?

In order to customize my grunt tasks, I need access to the grunt task name given on the command line when starting grunt.
The options is no problem, since its well documented (grunt.options).
It's also well documented how to find out the task name, when running a grunt task.
But I need access to the task name before.
Eg, the user writes
grunt build --target=client
When configuring the grunt job in my Gruntfile.js, I can use
grunt.option('target') to get 'client'.
But how do I get hold of parameter build before the task build starts?
Any guidance is much appreciated!
Your grunt file is basically just a function. Try adding this line to the top:
module.exports = function( grunt ) {
/*==> */ console.log(grunt.option('target'));
/*==> */ console.log(grunt.cli.tasks);
// Add your pre task code here...
Running with grunt build --target=client should give you the output:
client
[ 'build' ]
At that point, you can run any code you need to before your task is run including setting values with new dependencies.
A better way is to use grunt.task.current which has information about the currently running task, including a name property. Within a task, the context (i.e. this) is the same object. So . . .
grunt.registerTask('foo', 'Foobar all the things', function() {
console.log(grunt.task.current.name); // foo
console.log(this.name); // foo
console.log(this === grunt.task.current); // true
});
If build is an alias to other tasks and you just want to know what command was typed that led to the current task execution, I typically use process.argv[2]. If you examine process.argv, you'll see that argv[0] is node (because grunt is a node process), argv[1] is grunt, and argv[2] is the actual grunt task (followed by any params in the remainder of argv).
EDIT:
Example output from console.log(grunt.task.current) on grunt#0.4.5 from within a task (can't have a current task from not a current task).
{
nameArgs: 'server:dev',
name: 'server',
args: [],
flags: {},
async: [Function],
errorCount: [Getter],
requires: [Function],
requiresConfig: [Function],
options: [Function],
target: 'dev',
data: { options: { debugPort: 5858, cwd: 'server' } },
files: [],
filesSrc: [Getter]
}
You can use grunt.util.hooker.hook for this.
Example (part of Gruntfile.coffee):
grunt.util.hooker.hook grunt.task, (opt) ->
if grunt.task.current and grunt.task.current.nameArgs
console.log "Task to run: " + grunt.task.current.nameArgs
CMD:
C:\some_dir>grunt concat --cmp my_cmp
Task to run: concat
Running "concat:coffee" (concat) task
Task to run: concat:coffee
File "core.coffee" created.
Done, without errors.
There is also a hack that I've used to prevent certain task execution:
grunt.util.hooker.hook grunt.task, (opt) ->
if grunt.task.current and grunt.task.current.nameArgs
console.log "Task to run: " + grunt.task.current.nameArgs
if grunt.task.current.nameArgs is "<some task you don't want user to run>"
console.log "Ooooh, not <doing smth> today :("
exit() # Not valid. Don't know how to exit :), but will stop grunt anyway
CMD, when allowed:
C:\some_dir>grunt concat:coffee --cmp my_cmp
Running "concat:coffee" (concat) task
Task to run: concat:coffee
File "core.coffee" created.
Done, without errors.
CMD, when prevented:
C:\some_dir>grunt concat:coffee --cmp my_cmp
Running "concat:coffee" (concat) task
Task to run: concat:coffee
Ooooh, not concating today :(
Warning: exit is not defined Use --force to continue.
Aborted due to warnings.

Boost-build/BJam language - checking the value of a flag

I need to edit a .jam file used by boost-build for a specific kind of projects. The official manual on BJAM language says:
One of the toolsets that cares about DEF files is msvc. The following line should be added to it. flags msvc.link DEF_FILE
;
Since the DEF_FILE variable is not used by the msvc.link action, we need to modify it to be: actions link bind DEF_FILE { $(.LD) ....
/DEF:$(DEF_FILE) .... } Note the bind DEF_FILE part. It tells bjam to
translate the internal target name in DEF_FILE to a corresponding
filename in the link
So apparently just printing DEF_FILE with ECHO wouldn't work. How can it be expanded to a string variable or something that can actually be checked?
What I need to do is to print an error message and abort the build in case the flag is not set. I tried:
if ! $(DEF_FILE)
{
errors.user-error "file not found" ;
EXIT ;
}
but this "if" is always true
I also tried putting "if ! $_DEF_FILE {...}" inside the "actions" contained but apparently it is ignored.
I am not sure I understand the global task you have. However, if you wanted to add checking for non-empty DEF_FILE -- expanding on the documentation bit you quote, you need to add the check in msvc.link function.
If you have a command line pattern (specified with 'actions') its content is what is passed to OS for execution. But, you can also have a function with the same name, that will be called before generating the actions. For example, here's what current codebase have:
rule link.dll ( targets + : sources * : properties * )
{
DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
if <embed-manifest>on in $(properties)
{
msvc.manifest.dll $(targets) : $(sources) : $(properties) ;
}
}
You can modify this code to additionally:
if ! [ on $(<) return $(DEF_FILE) ] {
ECHO "error" ;
}

Resources