Shake: automatically deleting file after failed command - shake-build-system

Using Shake, to create an mp3 (this is just a learning example), I use lame, and then id3v2 to tag it.
If the lame succeeds, but the id3v2 fails, then I'm left with the mp3 file in place; but of course it is "wrong". I was looking for an option to automatically delete target files if a producing command errors, but I can't find anything. I can do this manually by checking the exit code and using removeFiles, or by building in a temporary directory and moving as the last step; but this seems like a common-enough requirement (make does this by default), so I wonder if there's a function or simple technique that I'm just not seeing.

The reason Make does this by default is that if Make has a partial incomplete file on disk, it considers the task to have run successfully and be up to date, which breaks everything. In contrast, Shake records that a task ran successfully in a separate file (.shake.database), so it knows that your mp3 file isn't complete, and will rebuild it next time.
While Shake doesn't need you to delete the file, you might still want to so as to avoid confusing users. You can do that with actionOnException, something like:
let generateMp3 = do cmd "lame" ... ; cmd "id3v2" ...
let deleteMp3 = removeFile "foo.mp3"
actionOnException generateMp3 deleteMp3

Related

why won't my AutoCAD accoreconsole open files or execute scripts?

I am running Vanilla AutoCAD 2017
The accoreconsole.exe will start but and show the example Screen and will appears to run commands, although i am unaware of a way to open a file directly from core console so i cant really do anything with it.
Methods attempted
1. Script Pro 2.0:
From https://knowledge.autodesk.com/support/autocad/downloads/caas/downloads/content/autodesk-customization-conversion-tools.html
Script pro executes scripts successfully when using AutoCAd But then Fails when i switch to Core Console
It generates a log file that reads: Error while reading log file for C:\Users\Documents\TEST\ARCH01_FIRST FLOOR PLAN - AREA C.dwg
2.Auto Lisp
From AutoCAD using an Auto Lisp command i found on House of BIM. The command works and i tested several scripts which i first tested using the Run Script Button in AutoCad and they worked, but not when i used core console.
This generated a Temp file called accc34642 which reads m_kernelList still has 1 entry
/i core console flashes and then disappears
/I core console opens a new file from the Qnew Template file path
This seems to happen no matter whats after that in the lisp statement.
Then OPEN command in core console doesn't return a prompt or an error, it just returns twice and does nothing.
Typing in a file path generates an error
3.Widows batch files
I have only used one of these in the past successfully but i checked the ones i found a couple different websites and still no luck on getting the scripts to execute.
I also tried all this from different File Paths
The main idea of AutoCAD Console is to process 1 file and exit. That's also important to avoid memory fragmentation and errors when you process multiple files in a single instance of accoreconsole.exe
So, as already mentioned, consider a workflow where each instance process a single file and then exit. You may even consider multiple instances of accoreconsole to process multiple files at once.
Wed0,
to get started with working with accoreconsole, here are a couple links that will help you:
1) http://adndevblog.typepad.com/autocad/2012/04/getting-started-with-accoreconsole.html
2) http://through-the-interface.typepad.com/through_the_interface/2012/02/the-autocad-2013-core-console.html
for the second article, Kean goes into quite a bit of detail, but I don't especially like his approach with using .bat files. It is much nicer to use a programming language like C#.
As for opening files, it actually is possible!
I recently discovered a VERY fast method of processing dwg files using accorconsole (or AutoCAD if that is what you prefer). For example, running a search and replace operation of dbtext and mtext on a batch of dwg files runs at around 15 drawings/second on a single process. Setting up 5 or 6 in parallel will process close to 5000 drawings/minute! I thought I would share this with the community as this discovery has been a game-changer for my company when it comes to processing large batches of dwg files.
For this you have to use the .NET API(or C++, etc). I did all the code for processing in C#, and the only 2 lines in the lisp script file is to NETLOAD my dll and call the command that does the processing.
Turns out, you can work on multiple dwg files in the same instance of accoreconsole. The idea here is to just load the dwg database without actually opening the drawing (takes ~70ms), manipulate the database, then save it. For the i/ switch, you can use any dummy drawing file as it will have no effect on your batch. Then in C# in your command method, you would do something like this:
string[] dwgFiles = Directory.GetFiles("C:\\MyDWGFiles");
foreach(string drawingFilePath in dwgFiles)
{
using(Database database = new Database(false, true))
{
database.ReadDwgFile(drawingFilePath, FileShare.ReadWrite,
true String.Empty);
using(Transaction transaction =
database.TransactionManager.StartTransaction())
{
//DO STUFF HERE
transaction.Commit();
database.SaveAs(drawingFilePath, DwgVersion.Current);
}
}
}
Let me know if you have any questions or need more detail,
I don't believe it is possible to open files from within core console. I am relatively certain core console has to be initialized with the path as an argument of the drawing you wish it to open. Once it is open you can then do work with that file. So, you would essentially have to open a single instance of core console for each file you want to do work on.
Hope that helps.
The best way as drive AutoCAD commands as dwg files is use the concept mencioned by "Autodesk Knowledge Network": Out-of-Process .NET
a. https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2016/ENU/AutoCAD-NET/files/GUID-C8C65D7A-EC3A-42D8-BF02-4B13C2EA1A4B-htm.html),
and this alternative is supported by Autodesk; the accoreconsole is not.
With this features, you may execute AutoCAD software, open Projects, batch iterates on files and manipulate data. Recently, I developed one plugin that has two requirements:
b. be executed without user-intervention and,
c. interates on all Dwg files to execute a process per-file;
Like link above, I instantiated AutoCAD and send commands like a lisp sintaxe to call the customized command (as "("CUSTOM_CMD", "PARAMS1", "PARAMS2" ...)" );
My custom command was like this:
[CommandMethod("CUSTOM_CMD")]
public static void CustomCmd
{
//stuff iterate on DWGs
}
3.Comments: It's importante to use Thread Safe Collection (for example ConcurrentBag) to memory Dwg Collection to ensure non interference between Next Moving contiguous Dwgs iteraction's running.

Rename code in c have a error

i want to move a file from a directory to anther directory with C Coding.
I search and find rename(); function , but when working it doesnt work and have a error:
my code:
#include <stdio.h>
int main() {
if(rename("/root/tmpfile.php", "/home/check-tmp.php"))
perror( NULL );
}
the code well compiled but when running this code showing this error:
Invalid cross-device link
How to move a file from a directory to anther directory without using System for fopen?
Aslo , i finded many codes and ways to do it but doesnt working all codes.
Please say me a way and make sure it will work
Thanks.
Many aspects of the behavior of `rename' are inherently platform-dependent: The rename operation might not be able to move a file from one file system to another , it might not be atomic, and it might not succeed if a file with the destination abstract pathname already exists.
In other words, your system does not support rename files cross different partitions (your root partition and your home partition are different.)
So the solution is when it fails, copy the file to the destination and delete the original.
The rename call can only rename and move files within a single disk partition. The error "cross-device link" indicates that you attempted to move a file from one partition to another. (If you were on a Windows system, you can imagine if you tried to rename a file from C: to D:.)
When you use the Unix mv command to move files, it first tries a rename, but if it fails in this way, it falls back and makes a new copy of the file in the new location, then deletes the original. That's what you would have to have your code do in this situation, too.
(Copying a file is easy enough, but there are plenty of library functions out there that will do it for you, and also take care of things like preserving the last-modified time and other file attributes.)

How to get file name when file change is observed via watch_file

I am currently facing an issue which I don't know how to fix. I got the following Julia code:
while true
print(watch_file("test"))
end
So this should get me all the file changes in the directory named "test". At least on windows.
Now thats all well and good, and it kinda works, at least for creating a file or moving a file to that directory. This is an example of what I get:
("New Textfile.txt",Base.FileEvent(true,false,false))
But when I delete or rename that file, I don't get the filename of the file deleted or renamed.
("",Base.FileEvent(true,false,false))
Is there a different method/function I can get the filename with, even when the file is deleted or renamed? Or even better, a way that archives this and is cross-platform-compatible? Any help appreciated.
EDIT: If you could give me an alternative that supports recursive monitoring, that would be even better.
In Linux, Julia 0.4.5 and 0.4.3 watch_file returns file name always. It is a very platform-dependent feature (like in Node.js https://nodejs.org/api/fs.html#fs_caveats) and only manual polling can be truly platform-independent solution.

Get last modified file without enumerating all files

In c#, given a folder path, is there a way to get the last modified file without getting all files?
I need to quickly find folders that have been updated after a certain time and if the file that was last modified is before the time, i want to skip the folder entirely.
I noticed that folder's last modified time does not get updated when one of its file get updated so this approach does't work.
No, this is why windows comes with indexing to speed up searching. The NTFS file system wasn't designed with fast searching in mind.
In any case you can monitor file changes which is not difficult to do. If it is possible to allow your program to run in the background and monitor changes then this would work. If you needed past history you could do an initial scan only once and then build up your hierarchy from their. As long as your program is always being ran then it should have a current snapshot and not have to do the slow scan.
You can also use the Window Search itself to find the files. If indexing is available then it's probably as fast as you'll get.
Try this.
DirectoryInfo di = new DirectoryInfo("strPath");
DateTime dt = di.LastWriteTime;
Then you should use
Directory.EnumerateFiles(strPath, "*.*", SearchOption.TopDirectoryOnly);
Then loop the above collection and get FileInfo() for each file.
I don't see a way how can you get the modified date of a file w/o getting reference to FileInfo() on that file.
I don't think FileInfo will get this file as far as I know.

Easiest way to have a true "file tasks" in ANT

I am still learning how to use ANT well, and I wanted to understand if there is some reasonable way to do file tasks in it, similar to Rake and Make:
http://martinfowler.com/articles/rake.html#FileTasks
"With a file you are referring to actual files rather than task names. So 'build/dev/rake.html' and 'dev/rake.xml' are actual files. The html file is the output of this task and the xml file is the input. You can think of a file task as telling the build system how to make the output file - indeed this is exactly the notion in make - you list the output files you want and tell make how to make them.
An important part of the file task is that it's not run unless you need to run it. The build system looks at the files and only runs the task if the output file does not exist or it's modification date is earlier than the input file. File tasks therefore work extremely well when you're thinking of things at a file by file basis."
So in other words, let's say I want to run a custom binary and I only want that binary to run if any of the files have changed. This is related to this question, but I don't want to run the binary at all, not only pass a part of the fileset (i.e. there is only one in the fileset and I don't want the tool to run at all).
The ideal solution would also not be a loooong thing, but rather could be easily applied to any target -- perhaps using some ANT JavaScript or custom task?
Use ant-contrib outofdate task. It has exactly the properties you are asking for. Here is ant-contrib website.
Here is a template on how to integrate it into your build:
<taskdef
resource="net/sf/antcontrib/antlib.xml"
>
<classpath>
<pathelement location="${ant-contrib.jar}"/>
</taskdef>
<outofdate>
<sourcefiles path="dev/rake.xml"/>
<targetfiles path="build/dev/rake.html"/>
<sequential>
... do your work here ...
... will only run if rake.html is older than rake.xml ...
</sequential>
</outofdate>

Resources