How do I find the full directory for an IFile in Cake? - cakebuild

I'm writing a script to produce some artefacts from my build so I want to clean up unwanted files first. I'm using CleanDirectory(dirPath, predicate).
I'm finding it disturbingly hard to work out the directory for a file. If I use GetDirectoryName() that seems to just get me the immediate parent, not the full directory path.
Func<IFileSystemInfo, bool> predicate =
fileSystemInfo => {
// Dont filter out any directories
if (fileSystemInfo is IDirectory)
return false;
var path = fileSystemInfo.Path.FullPath;
var directory = ((DirectoryPath)path).GetDirectoryName();
...
}
Obviously I can use the .NET Framework System.IO classes to do this easily but then I get strings with the slashes in the wrong direction, and things do not smoothly inter-operate with Cake which uses POSIX paths.

OK I've worked out a solution. The key to IFileSystemInfo is to try and cast the Path to various derived types/interfaces, which then provide the functionality you are probably looking for. Example:
Func<IFileSystemInfo, bool> predicate =
fileSystemInfo => {
// Dont filter out any directories
if (fileSystemInfo is IDirectory)
return false;
// We can try and cast Path as an FilePath as know it's not a directory
var file = (FilePath) fileSystemInfo.Path;
if (file.FullPath.EndsWith("Help.xml", StringComparison.OrdinalIgnoreCase))
return false;
// GetDirectory() returns a Path of type DirectoryPath
var directory = file.GetDirectory().FullPath;
...
}

Related

How to list all local mp3 files on flutter2(null safety)?

The code should be working on flutter2, with android and ios(if possible)
Searching for files
Do you want to simplify your life? Use this package:
import 'package:glob/glob.dart';
Stream<File> search(Directory dir) {
return Glob("**.mp3")
.list(root: dir.path)
.where((entity) => entity is File)
.cast<File>();
}
Do you want to avoid adding a new dependency in your project? Manipulate the Directory itself:
Stream<File> search(Directory dir) {
return dir
.list(recursive: true)
.where((entity) => entity is File && entity.path.endsWith(".mp3"))
.cast<File>();
}
Defining the search scope
You'll also need a Directory where you'll search for MP3 files.
Is it the root directory (i.e. search ALL the files in the device)? Use this answer.
Is it another directory? Pick one from this package.
Usage
final Directory dir = /* the directory you obtained in the last section */;
await search(dir).forEach((file) => print(file));

How to get files from selected folder with GtkFileChooserButton?

I am making a GTK+3 App with GJS where users select a folder from a GtkFileChooserButton (action property set to select-folder). I want to find all image files in the given folder the user have selected, so I can display one of the images.
I tried this._fileChooserButton.get_files() and this._folderChooseButton.get_uris() but they only return one file, which is the path to the selected folder. Like this:
_init(application) {
this._folderChooseButton.connect('file-set', () => {
this._onFolderChosen();
});
}
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
// somehow get files from the folder here
this._image.set_from_file(files[1]);
}
From the API it is not really clear to me, how do I find out which image files are inside the user's selected directory (and subdirectories)?
OK, after help from patrick, georges and matthias at guadec, here is what I got.
The get_file() function I tried returns a GFile, which in this case is a folder (in UNIX, folders are also files). In order to get the files within the directory path, we need to call enumerate_children_async() on our GFile, returned by the get_file() function.
The enumate_children_async() function takes five parameters:
A comma-separated attribute list. In our case, since we want the identifiers of the children in the directory, we want to use the attribute called standard::name.
FileQueryInfoFlag: This allows to either follow or not follow symbolic links. In this case, we will use FileQueryInfoFlag.NONE which will not follow symbolic links.
io_priority: How high priority the IO operation should have (we will use GLib.PRIORITY_DEFAULT)
cancellable: A cancellable, which is a way to cancel this operation, in this case we will leave it as null.
callback: This is the function/code you want to run in response to the files having been retreived.
More info on this function is at GJS-Docs at GNOME.org
The enumerate_children_async() function returns a GFileEnumerator, which we can use to retreive a number of the files, by calling next_files_async(), which takes these arguments:
num_files: How many files you want to retreive. In your case, we use 1.
io_priority and cancellable (same as above).
callback: Where we can run a function or code to actually retreive the file.
Below, is the final code for doing this.
const { Gio, GLib, GObject, Gtk } = imports.gi; // import Gio and GLib API at top of your document.
_onFolderChosen() {
let folder = this._folderChooseButton.get_file();
let files = folder.enumerate_children_async(
'standard::name',
Gio.FileQueryInfoFlags.NONE,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
this._fileEnumerator = null;
try {
this._fileEnumerator = folder.enumerate_children_finish(result);
} catch (e) {
log('(Error) Could not retreive list of files! Error:' + e);
return;
}
this._readNextFile();
});
}
_readNextFile() {
if (!this._fileEnumerator)
return;
let fileInfo = null;
this._fileEnumerator.next_files_async(
1,
GLib.PRIORITY_DEFAULT,
null,
(source, result, data) => {
try {
fileInfo = this._fileEnumerator.next_files_finish(result);
} catch (e) {
log('Could not retreive the next file! Error:' + e);
return;
}
let file = fileInfo[0].get_name();
let filePath = GLib.build_filenamev([this._folderChooseButton.get_filename(), file]);
this._carousselImage.set_from_file(filePath);
});
}

Matlab: check if string has a correct file path syntax

I want to check if a string represents a full path of a file, like this:
p = 'C:\my\custom\path.txt'
The file does not exist, so commands like isdir and exist return false to me, but still the format of the string represents a valid path for my operating system, while the following one does not because it has an invalid character for the file name:
p = 'C:\my\custom\:path.txt'
So I'd like to know how to check if a string represents a valid file path without needing that the file actually exists.
You might want to use the regexp function with a regular expression to match Windows paths.
if isempty(regexp(p, '^(?:[a-zA-Z]\:|\\\\[\w\.]+\\[\w.$]+)\\(?:[\w]+\\)*\w([\w.])+$', 'once'))
// This is not a path
end
You can also let Matlab try for you:
if ~isdir(p)
[status, msg] = mkdir(p);
if status
isdir(p)
rmdir(p)
else
error(msg)
end
end
First, you check if the folder exists, if not you try to create it. If you succeed then you delete it, and if not you throw an error.
This is not recommended for checking many strings but has the advantage of being cross-platform.
function bool = isLegalPath(str)
bool = true;
try
java.io.File(str).toPath;
catch
bool = false;
end
end

Saving screenshots with protractor

I'm attempting to save a screenshot using a generic method in protractor. Two features, it creates the folder if it does not exist and it saves the file (with certain conditions).
export function WriteScreenShot(data: string, filename: string) {
let datetime = moment().format('YYYYMMDD-hhmmss');
filename = `../../../test-reports/${filename}.${datetime}.png`;
let path =filename.substring(0, filename.lastIndexOf('/'));
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
let stream = fs.createWriteStream(filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
}
This can be used by calling browser.takeScreenshot().then(png => WriteScreenShot(png, 'login/login-page')); Using this example call, a file will be created, I assumed, in the path relative where my WriteScreenShot method's file resides. But that does not appear to be the case.
For example, when I run my spec test in the spec's folder, the image gets saved in the correct place. But if I run it at the project root, an error is capture. Obviously, this has to do with my relative path reference. How do I capture the project's root directory and build from that so that I can run the test from any directory?
This is a classical directory access error. Let me just explain what is happening to your code -
let path =filename.substring(0, filename.lastIndexOf('/'));
The above line outputs to ../../../test-reports
fs.existsSync checks whether thispath exists or not -
case 1 :(postive flow) Your spec folder is in the same current working directory in which you are trying to create reports folder. When you run your test, the path exists, it generates the test-reports directory & screenshots and your code works fine.
case 2:(negative flow) When you try to run it from the root directory which is the current working directory now, fs.existsSync tries to check the path & the reports folder inside it. If it doesn't exist , fs.mkdirSync tries to create your directories but it would fail as it cannot create multiple directories.
You should be using native path module of nodejs to extract the path instead of using file substring and the mkdirp external module for creating multiple directories.
import * as path from 'path';
let {mkdirp} = require('mkdirp'); // npm i -D mkdirp
export function WriteScreenShot(data: string, filename: string) {
let datetime = moment().format('YYYYMMDD-hhmmss');
filename = `../../../test-reports/${filename}.${datetime}.png`;
let filePath = path.dirname(filename); // output: '../../..' (relative path)
// or
let filePath = path.resolve(__dirname); // output: 'your_root_dir_path' (absolute path)
// or
let filePath = path.resolve('.'); // output: 'your_root_dir_path' (absolute path)
if (!fs.existsSync(filePath )) {
mkdirp.sync(filePath); // creates multiple folders if they don't exist
}
let stream = fs.createWriteStream(filename);
stream.write(new Buffer(data, 'base64'));
stream.end();
}
If you are curious to know the difference btw mkdir & mkdir-p please read this SO thread.

Cannot distinguish file from folder

I am trying to list all the files contained in a directory UROP by using stat(). However, the directory does not contain only files, but also folders, which I want to search too. Therefore, I am using recursion to access the folders whose files I want to be listed.
However, the if conditions in my loop do not manage to distinguish a file from a directory, and all files appear as directories; the result is an infinite recursion The code is the following. Thank you in advance!
using namespace std;
bool analysis(const char dirn[],ofstream& outfile)
{
cout<<"New analysis;"<<endl;
struct stat s;
struct dirent *drnt = NULL;
DIR *dir=NULL;
dir=opendir(dirn);
while(drnt = readdir(dir)){
stat(drnt->d_name,&s);
if(s.st_mode&S_IFDIR){
if(analysis(drnt->d_name,outfile))
{
cout<<"Entered directory;"<<endl;
}
}
if(s.st_mode&S_IFREG){
cout<<"entered condition;"<<endl;
cout<<drnt->d_name<<endl;
}
}
return 1;
}
Instead of if(s.st_mode&S_IFDIR) and if(s.st_mode&S_IFREG),
try if (S_ISDIR(s.st_mode)) and if (S_ISREG(s.st_mode)).