groovy sort alphabetically - sorting

I am updating a groovy script which build a test runner suite inside SoapUI. The scripts scan a folders and add test case for each file in each folders.
The problem I am trying to solve is that the script is using eachFileMatch() which does not have a consistent behavior between Windows and Unix file systems. I need to update the script so that files are listed alphabetically.
I am quite new to groovy so I don't know where to get started. Saw that a sort() method does exist but I am not sure I can use it on eachFileMatch.
Here's the code snippet I need to adapt :
new File(projectPathTest+"/nord").eachDir{dir->
log.info("Dir > "+dir);
operation = dir.name
def wsdlTestCase = testSuite.addNewTestCase( operation )
wsdlTestCase.setFailOnError(false)
dir.eachFileMatch(~/.*_request\.xml/){file->
// Need Alphabetically sorting here
log.info("File >> "+file)
addTestStep(operation, file, wsdlTestCase, projectPath, endPoint)
}
Any starting point to do it will the groovy approach would be really appreciated as for now i don't have time to delve into the groovy API.
Regards
}

You can collect the files in a TreeSet which will maintain their sort order and then iterate over the set to display or otherwise act on your collection of files.
TreeSet<File> files = new TreeSet<File>()
dir.eachFileMatch(~/.*_request\.xml/){file->
files << file
}
files.each { f->
// log or do whatever with the files in order
}
If you need this ordering over all the files, you will need to put the TreeSet outside of the eachDir closure.

Related

How to add generators that respect alphabetical orders

I created a generator it generates some files and adds some content into a file; I want it to also respect the alphabetical order of names in the file.
Example is: when I want to generate a new action I'll run rails g new_action drying_clothes. This will generate files with content and write into an existing file. This file has actions like:
Cooking Pottery Soaking.
If I currently run the generator the action/ name drying_clothes will be inserted after Soaking, how can I ensure it respects alphabetical order? Here's my code so far:
def add_action
inject_into_file 'app/actions.yml',
"#{file_name}\n
category: new\n"
end

Photoshop script .DS_Store

I'm using Photoshop script. I get files from folders. My problem is that when I get the files and place them in an array the array contains hidden files that are in the folder for example ".DS_Store". I can get around this by using:
if (folders[i] != "~/Downloads/start/.DS_Store"){}
But I would like to use something better as I sometimes look in lots of folders and don't know the "~/Downloads/start/" part.
I tried to use indexOf but Photoshop script does not allow indexOf. Does anybody know of a way to check if ".DS_Store" is in the string "~/Downloads/start/.DS_Store" that works in Photoshop script?
I see this answer but I don't know how to use it to test: Photoshop script to ignore .ds_store
For anyone else looking for a solution to this problem, rather than explicitly trying to skip hidden files like .DS_Store, you can use the Folder Object's getFiles() method and pass an expression to build an array of file types you actually want to open. A simple way to use this method is as follows:
// this expression will match strings that end with .jpg, .tif, or .psd and ignore the case
var fileTypes = new RegExp(/\.(jpg|tif|psd)$/i);
// declare our path
var myFolder = new Folder("~/Downloads/start/");
// create array of files utilizing the expression to filter file types
var myFiles = myFolder.getFiles(fileTypes);
// loop through all the files in our array and do something
for (i = 0; i < myFiles.length; i++) {
var fileToOpen = myFiles[i];
open(fileToOpen);
// do stuff...
}
For anybody looking I used the Polyfill found here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
indexOf() was added to the ECMA-262 standard in the 5th edition; as
such it may not be present in all browsers. You can work around this
by utilizing the following code at the beginning of your scripts. This
will allow you to use indexOf() when there is still no native support.
This algorithm matches the one specified in ECMA-262, 5th edition,
assuming TypeError and Math.abs() have their original values.

Perl efficiency in writing in file

I am creating a database with some informations of files.
e.g: file_name | size | modify_date ...
I was thinking what is more efficient in this situation:
1) For each file get the info and print them in my file
foreach my $file ( #listOfFiles) {
my %temporary_hash = get_info_for_file($file); //store in a tempoarary hash
the informations for current file
print_info(%temporary_hash, $output_file); // print the information in my output file
}
2) Store the info for every file in a hash and print all the hash at once
foreach my $file( #listOfFiles){
store_info_in_hash( get_info_for_file($file), %hash); // for each file, store the
information in a global hash
}
print_all_info(%hash, $output_file); //after i have informations for each file
print the whole hash in my output file
You are wrong to consider efficiency before you have even got your program working
You should write your code as clearly as possible and debug it. Only then, if it is not running fast enough for your purpose, you should put your code through a profiler to discover the bottlenecks that are taking the most time
The two options you show will probably not be very different unless your files are enormous
Doing a benchmark test on the two options i got those results ( which, if I increase the information size for each file, will lead to even bigger differencies between the two).

Create a Jenkins Matrix Job with parameters based on files present in folder or shell script output

I am trying to create a Matrix Configuration job in Jenkins based on the files present in a directory on the host machine.
Effectively, if under the workspace directory we run $(ls *.properties) there are
a.properties
b.properties
c.properties
I want a Matrix configuration job to run using those 3 results as an axis property list.
I would prefer not to use a lightweight upstream task to collect the values and populate a property for the DynamicAxis plugin, but I have already tried this and can't figure out how to get the output of a bash script into one of the predefined properties anyway. At this point I'm happy for any suggestions on how this may be done.
There is the groovy axis plugin
This plugin allows to have scriptable axes for Matrix Jobs. Groovy is
the scripting language being used.
The script will have to return a list of strings and each of the
strings will be an element of the axis.
Which includes an example of exactly what you want
Define an axis whose values are the files in the root directory:
def dir = new File('/')
def result = []
dir.eachFile {
if (it.isFile()) {
result += it.canonicalPath
}
}
return result

Print all the files in a given folder and sub-folders without using recursion/stack

I recently had an interview with a reputable company for the position of Software Developer and this was one of the questions asked:
"Given the following methods:
List subDirectories(String directoryName){ ... };
List filesInDirectory(String directoryName) { ... };
As the names suggest, the first method returns a list of names of immediate sub-directories in the input directory ('directoryName') and the second method returns a list of names of all files in this folder.
Print all the files in the file system."
I thought about it and gave the interview a pretty obvious recursive solution. She then told me to do it without recursion. Since recursion makes use of the call stack, I told her I will use an auxillary stack instead, at which point point she told me not to use a stack either. Unfortunately, I wasn't able to come up with a solution. I did ask how it can be done without recursion/stack, but she wouldn't say.
How can this be done?
You want to use a queue and a BFS algorithm.
I guess some pseudo-code would be nice:
files = filesInDirectory("/")
foreach (file in files) {
fileQ.append(file)
}
dirQ = subDirectories("/")
while (dirQ != empty) {
dir = dirQ.pop
files = filesInDirectory(dir)
foreach (file in files) {
fileQ.append(file)
}
dirQ.append(subDirectories(dir))
}
while (fileQ != empty) {
print fileQ.pop
}
If I understood correctly, immediate sub-directories are only the directories in that folder. I mean if I=we have these three paths /home/user, /home/config and /home/user/u001, we can say that both user and config are immediate subdirectories of /home/, but u001 isn't. The same applies if user, and u001 are files (user is immediate while u001 isn't).
So you don't really need recursion or stack to return a list of immediate subdirectories or files.
EDIT: I thought that the OP wanted to implement the subDirectories() and filesInDirectories() functions.
So, you can do something like to print all files (kind of pseudocode):
List subd = subDirectories(current_dir);
List files = filesInDirectories(current_dir);
foreach (file in files) {
print file.name();
}
while (!subd.empty()) {
dir = subd.pop();
files = filesInDirectory(dir.name());
foreach (file in files) {
print file.name();
}
subd.append(subDirectories(dir.path()));
}
I think that what #lqs suggests is indeed an acceptable answer that she might have been looking for: store the full path in a variable, and append the directory name to it if you enter a subdirectory, and clip off the last directory name when you leave it. This way, your full path acts as the pointer to where you currently are in the file system.
Because the full path is always modified at the end, the full path behaves (not surprisingly) as your stack.
Interview questions aside, I think I would still pick a real stack over string manipulation though...

Resources