I have an issue with copying files in gradle. Here is a snippet of build.gradle:
task mydir() {
new File("build/models").mkdir()
}
task copyTask(dependsOn:mydir, type: Copy){
from 'src/test/groovy/models'
into 'build/models'
from 'src/test/groovy/test.groovy'
into 'build/'
}
The issue here is in the first copy, that is, test.groovy is copied into build. But the first copy, where I am copying all the files in src/../models into build/models is not working. It simply copies the files into build directory only. My build/models remain empty. Can someone please tell me where what I'm doing wrong? I also have a separate task to create build/models directory prior to copyTask execution.
The build script contains the following mistakes:
The directory is created when mydir is configured, not when it is executed. (This means the directory will be created on every build invocation, regardless of which tasks get executed.)
new File('some/path') creates a path relative to the current working directory of the Gradle process, not a path relative to the project directory. Always use project.file() instead.
A Copy task can only have a single top-level into.
Here is a corrected version:
task mydir {
doLast {
mkdir('build/models')
}
}
task copyTask(dependsOn: mydir, type: Copy) {
into 'build'
from 'src/test/groovy/test.groovy'
into('models') {
from 'src/test/groovy/models'
}
}
The Copy task will create build/models automatically, so there is likely no need to have the mydir task. It's odd to use build as the target directory of a Copy task (should use a subdirectory).
In gradle, the copy task could only have single 'into' target with multiple froms.
The second 'into' override the first 'into' value and that's why it's only copied into 'build/' not 'build/models''
You may want to have a separate copy task or use ant.copy instead.
Related
I have an sbt project where docker:publishLocal will create a docker image on my machine for testing, and docker:publish will publish the image to a repository and also publish jar files from the build to a repository.
If my project is a snapshot, I would like to disable publishing to the repositories, while still being able to build the local image.
ThisBuild / publishArtifact := ! isSnapshot.value
does the right thing for the publish command, but it also disables publishLocal.
I want to write something like
if (isSnapshot.value) {
publish := { }
}
but that gives me an error that I do not understand at all:
[info] Loading project definition from /Users/dev/project
/Users/dev/build.sbt:1: error: type mismatch;
found : Unit
required: sbt.internal.DslEntry
if (isSnapshot.value) {
^
Past experience dictates that redefining publish to conditionally call the original version won't work, as
publish := {
if (!isSnapshot.value) publish.value
}
gives warnings that the task is always evaluated.
Is there a way to do this?
The problem with this code is that it evaluates publish.value regardless of the if structure. I recommend reading the documentation on task dependencies. If you want to "delay" the evaluation of a task in one of the if branches, you need to use dynamic task definition:
publish := Def.taskDyn {
if (isSnapshot.value)
Def.task {} // doing nothing
else
Def.task { publish.value } // could be written as just publish
}.value
But apart from fixing your code, you should be aware that there is a special setting for the functionality you want, it's called skip:
publish/skip := isSnapshot.value
Another thing to notice, is the scoping. If you want to override docker:publish, which is the same as Docker/publish in the new syntax, you should add this Docker/ scope prefix to every mention of publish in the code above.
I have experienced certain problems when using libraries in premake4 scripts.
1) When creating a shared library (.dll) on Windows 10 using a premake4 script, it creates the dll fine, but it also creates a static library of small size (2K).
In my case, I was creating a shared library named MathLib.dll using a premake4 script. It did that correctly, but it also created a file named libMathLib.a of size 2K. (It may be empty.)
I don't see why there was a need for the Makefile generated by premake4 to create libMathLib.a, when in fact the objective was to create a .dll file. I think this may be a premake4 bug and I have raised it on the premake4 Issue tracker on github.
The premake4 lua script is as follows:
-- Dir : Files > C > SW > Applications > Samples >
-- premakeSamples > premake-sharedlib-create
--#!lua
-- A solution contains projects,
-- and defines the available configurations
solution "MathLib"
configurations { "Debug", "Release" }
-- A project defines one build target
project "MathLib"
kind "SharedLib"
language "C++"
files { "**.h", "**.cpp" }
includedirs {"../../../ProgramLibraries/Headers/"}
-- Create target library in Files > C > SW >
-- Applications > ProgramLibraries
targetdir "../../../ProgramLibraries/"
configuration "Debug"
defines { "DEBUG" }
flags { "Symbols" }
configuration "Release"
defines { "NDEBUG" }
flags { "Optimize" }
-- Register the "runmakefile" action.
newaction
{
trigger = "runmakefile",
description = "run the generated makefile to create the executable using the default ('debug' config)",
execute = function()
os.execute("make")
end
}
-- Register the "runmakefilerelease" action.
newaction
{
trigger = "runmakefilerelease",
description = "run the generated makefile to create the executable using the 'release' config)",
execute = function()
os.execute("make config=release")
end
}
2) The above problem is more serious than it sounds. Supposing I had already created a genuine static library named libMathLib.a in the Libraries dir, using a separate premake4 script. Subsequently, if I also create a shared library named MathLib.dll in the same directory as the static library, a dummy static library (possibly empty) would be created and replace the earlier genuine static library.
3) -- EDIT -- : I had reported this point (use of a static library) as a problem, but it has started working now. I don't know the reason, but the only difference, as far as I am aware, is that I had shut down and restarted my PC (and therefore my MSYS session on Windows 10). Therefore I am deleting this point.
How can I solve the above 2 problems?
That's the import library. You can turn it off with Premake's NoImportLib flag.
flags { "NoImportLib" }
I'm using skipper to receive the files, sharp to resize (and save) and fs unlink to remove the old image. But I got a very weird error this time that concerns me a lot:
error: ** Grunt :: An error occurred. **
error:
Aborted due to warnings.
Running "copy:dev" (copy) task
Warning: Unable to read "assets/images/users/c8e303ca-1036-4f52-88c7-fda7e01b6bba.jpg" file (Error code: ENOENT).
error: Looks like a Grunt error occurred--
error: Please fix it, then restart Sails to continue running tasks (e.g. watching for changes in assets)
error: Or if you're stuck, check out the troubleshooting tips below.
error: Troubleshooting tips:
error:
error: *-> Are "grunt" and related grunt task modules installed locally? Run npm install if you're not sure.
error:
error: *-> You might have a malformed LESS, SASS, CoffeeScript file, etc.
error:
error: *-> Or maybe you don't have permissions to access the .tmp directory?
error: e.g., (edited for privacy)/sails/.tmp ?
error:
error: If you think this might be the case, try running:
error: sudo chown -R 1000 (edited for privacy)/sails/.tmp
Grunt stopped running and to have that in production is a big NoNo... I believe that this is caused because of concurrency with fs.unlinkSync(fname). The error is also intermittent and very hard to reproduce in some machines (IO ops/sec maybe?).
I have the following controller action:
var id = 1; // for example
req.file('avatar').upload({
dirname: require('path').resolve(sails.config.appPath, 'assets/images')
}, function(err, files){
var avatar = files.pop();
//file name operations here. output is defined as the path + id + filetype
//...
sharp(avatar.fd)
.resize(800, 800)
.toFile(output, (err, info)=>{
if(err){
res.badRequest();
} else {
fs.unlinkSync(avatar.fd);
res.ok();
}
});
});
Now I've been thinking about a few solutions:
Output the new image directly to .temp
Unlink when files exists on .tmp. Explanation: Grunt already copied the old file so removing it would be safe!
But I don't know if this is some spaghetti code or even if a better solution exists.
EDIT: My solution was, as proposed by arbuthnott, wrap a controller like this:
get : function(req, res){
var filepath = req.path.slice(1,req.path.length);
//remove '/' root identifier. path.resolve() could be used
if(fs.existsSync(path.resolve(filepath))){
return res.sendfile(filepath);
} else {
return res.notFound();
}
}
I think you are on the right track about the error. You are making some rapid changes to in the assets folder. If I read your code right:
Add an image with user-generated filename to assets/images (ex cat.jpg)
Copy/resize the file to an id filename in assets/images (ex abc123.jpg)
Delete the original upload (cat.jpg)
(I don't know the details of sharp, there may be more under the hood there)
If sails is running in dev mode, then Grunt will be trying to watch the whole assets/ folder, and copy all the changes to .tmp/public/. It's easy to imagine Grunt may register a change, but when it gets around to copying the added file (assets/images/cat.jpg) it is already gone.
I have two suggestions for the solution:
One:
Like you suggested, upload your original to the .tmp folder (maybe even a custom subfolder of .tmp). Still place your sized copy into /assets/images/, and it will be copied to /.tmp/public/ where it can be accessed as an asset by the running app. But Grunt will ignore the quick add-then-delete in the .tmp folder.
Two:
Do a bit of general thinking about both what you want to include in version control, and what Grunt tasks you want to be running in production. Note that if you use sails lift --prod then Grunt watch is turned off by default, and this error would not even occur. Generally, I don't feel like we want Grunt to do too much in production, it is more of a development shortcut. Specifically, Grunt watch can use a lot of resources on a production server.
The note about version control is just that you probably want some of the contents of assets/images/ to be in version control (images used by the site, etc), but maybe not in the case of user-uploaded avatars. Make sure you have a way to differentiate these contents (subdirectories or whatever). Then they can be easily .git-ignore'd or whatever is appropriate.
Hope this helps, good luck!
I have to write the script in Gradle and I therefore have some questions.
The script must unpack the .ear file, and then included in the jar, then edit the content and save as ear (text file> jar> ear.)
1) Firstly, I would like to learn how to save a file to the current directory.
(The following code saves the file to another folder.)
task unzip(type: Copy) {
def zipFile = file('C:/Test/file.ear')
def outputDir = file('jar')
from zipTree(zipFile)
into getDestDir()
}
Phrases such as '.', '/' don't work.
2)Secondly, I would like to ask how to unpack the jar file because I can't unpack the above method. (It works only to the EAR)
3)At the end I would ask how you can convert the edited text file on the jar, and then on ear (without dependencies and manifest).
Because the resulting file do I have to file .ear
Thank you in advance for your answer.
You don't want to be writing files into your working directory. All the work should be done under the $buildDir.
A standard method is to set your into directory to a temporary location:
task myTask(type: Copy) {
from 'my/dir/'
into temporaryDir
}
You can unpack a JAR or ZIP file like so:
copy {
from zipTree('path/tozip.zip')
into temporaryDir
}
I'm writing a Javafx Application where I had to include a fxml file to copy from the source to the build directory. This is my task.
task copyRequiredFiles(type: Copy) {
from '/src/com/indywiz/game/ui/view/Game2048.fxml'
into 'build/classes/main/com/indywiz/game/ui'
}
task (runui, dependsOn: ['classes', 'copyRequiredFiles'], type: JavaExec) {
main = 'com.indywiz.game.ui.Main'
classpath = sourceSets.main.runtimeClasspath
}
If I run runui task, I get Skipping task ':copy Required Files' as it has no source files.
What is going wrong? Please let me know if you need any more information.
Below is my folder structure:
You gave an absolute part for from, but it needs to be a relative path (i.e. no leading /).