Why isn't my Rust code cding into the said directory? - rust

use std::{
env, io,
path::PathBuf,
process::{self, Command},
};
fn inner_main() -> io::Result<PathBuf> {
let exe = env::current_exe()?;
let dir = exe.parent().expect("Executable must be in some directory");
let dir = dir.join("nvs");
Ok(dir)
}
fn main() {
let path = inner_main().expect("Couldn't get path.");
let path = path.into_os_string().into_string().unwrap();
Command::new("cd")
.arg(&path)
.status()
.expect("Something went wrong.");
process::exit(0);
}
I grab the path that the binary is in, go into the parent directory so the binaries name is no longer in the path and then append "nvs" at the end of the path and then in main() I put the inner_main() function in a let and then redeclare the let as a string so I can cd into the directory.
Whenever it tries CDing into the nvs directory nothing happens and I know that the command runs because if I move the binary somewhere with no nvs file in it's same directory it runs saying it can't find that directory so my question is when it's in a directory with nvs why doesn't it actually cd into the said directory like it should?

You're attempting to run an external command called cd. Depending on your operating system, this either fails because there is no command called cd, or this does nothing other than test whether the directory exists and you have permission to access it. If a cd command exists, it runs in a subprocess of your program, and its change of directory does not affect your process.
To change to a different directory, you need to change the working directory of your own process. Call std::env::set_current_dir.
std::env::set_current_dir(&path).expect("Unable to change into [path to executable]/nvs");
// do stuff in …/nvs

Related

Node creating file 1 level up from the current path

I was using path.resolve but this command created a monster folder that can't be deleted called lib..
path.resolve(__dirname + "../assets/pic/" + `${fileName}.png`)
Question 1
What is the propper usage to create a folder 1 level up from the current path?
Question 2
How to remove the lib../assets/pic folder? Deleting the entire project or using git reset --hard, git stash doesn't work because Windows 10 says the folder doesn't exist.
Answer to Question 1:
tl;dr
const fs = require('fs')
const folderName1DirUp = '../SomeFolder'
try {
if (!fs.existsSync(folderName1DirUp)){
fs.mkdirSync(folderName1DirUp)
}
} catch (err) {
console.error(err)
}
The back story:
Two ways to reference the current folder in a Node.js script. You can use ./ or __dirname. Note in addition to ./ you can also use ../ which points to the parent folder.
The difference between the two.
__dirname in a Node script will return the path of the folder where the current JavaScript file resides.
./ will give you the current working directory (and ../ the parent). For ./ a call to process.cwd(). returns the same thing.
Initially the current working directory is the path of the folder where you ran the node command, but during the execution of your script it can change by calling process.chdir(...).
There is one place where ./ refers to the current file path which is in a require(...) call. There the ./, for convenience, refers to the JavaScript file path which lets you import other modules based on the folder structure.
Thus the call to fs.mkdirSync('../SomeFolder') with the given folder name makes a folder one level up from the current working directory.
Answer to Question 2:
From a PowerShell prompt Remove-Item './../Folder1UpToDelete' -Force The ./ is for the current folder. The ../ is for one folder up from the current. Finally the Folder1UpToDelete is the one folder up from the current that you want to delete. The -Force makes sure to delete all sub-folders/files under the folder you want deleted including hidden and/or read-only files.
To answer the first question, to create a path 1 level up, you can use path.join():
path.join(__dirname, "../assets/pics", `${fileName}.png`);
For the second question, if deleting it through the explorer doesn't work, you can try:
fs.rmdirSync("E:/path/to/broken/folder..");
Using Git Bash and running
cd /c/path/to/broken/
rmdir folder..

Where do I need to put file to be read by Rust?

When I was reading through the tutorial for Rust here (https://doc.rust-lang.org/book/ch09-02-recoverable-errors-with-result.html). I found this block of code:
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
It always displays an error: { code: 2, kind: NotFound, message: "The system cannot find the file specified." } even when I make a hello.txt at the root folder of the src, it fails to read it.
In another example here, I use cargo run to no success. The program still fails to read hello.txt file. I'm aware that the example uses rustc open.rs && ./open. Since I don't understand why is it suddenly use different compile method and what's it even mean... I just kinda skip it and try to use cargo run instead
Where do I need to put my file here so cargo run can read it ?
Also if I run the production code and need the program to read an external file, where do I need to put it ?
Here's my folder structure. Pretty simple since I just start to learn RUST.
Thank you in advance.
A file without a directory component in the name needs to be in the current working directory, i.e. the directory from which you start your executable or cargo run.
If you start cargo from an IDE, it might not be immediately apparent what directory it will use as the current directory. In that case, you can always find the current working directory by printing it explicitly:
fn main() {
println!("{}", std::env::current_dir().unwrap().display())
}

Using node-cmd module while handling Squirrel Events function

I'm building a desktop app for Windows using electron-packager and electron-squirrel-startup, I would like to execute some Windows cmd commands during the installation of my application. To do so I was planning to use node-cmd node module, but I doesn't really work inside the handleSquirrelEvents function. An example command like this:
function handleSquirrelEvent(application) {
const squirrelEvent = process.argv[1];
switch (squirrelEvent) {
case '--squirrel-install':
case '--squirrel-updated':
var cmd=require('node-cmd');
cmd.run('touch example.created.file');
}
};
Seems to work. A file example.created.file in my_app/node_module/node-cmd/example directory is created.
But any other code does not work. Even if I only change the name of the file to be "touched" nothing happens.
Ok, example.created.file already exists in this directory and I suspect that you can only use update.exe supported commands in case '--squirrel-updated' sections. So this will not work.

Resolving paths in a custom root directory and avoiding going in parent folders

Using path.resolve we can resolve paths using Node.js.
I want to have a directory containing files and other directories and so on. From the client I receive a path as string and I have to resolve it in this directory.
Because of security, I have to prevent the result path to be outside of the directory:
// This comes from the client
let filePath = "/../../../some-sensitive-data-from/disk";
/* Here I have to check if the path is inside of the directory */
path.resolve(ABSOLUTE_PATH_TO_MY_DIR + filePath);
How to prevent the access to parent directories of ABSOLUTE_PATH_TO_MY_DIR?
Obviously a solution would be to check if the final path is still inside of the ABSOLUTE_PATH_TO_MY_DIR path. But maybe there are other better solutions.

Require file somewhere in the directory node.js

I have a file that is required in many other files, that are on different folders, inside the main directory.
Is there a way to just require the filename without having to write the relative path, or the absolute path? Like require('the_file'). And without having to go to npm and install it?
Create a folder inside your main directory , put the_file.js inside and set the NODE_PATH variable to this folder.
Example :
Let's say you create a ./libs folder within your main directory, you can just use :
export NODE_PATH = /.../main/lib
after that, you can require any module inside this directory using just :
var thefile = require('the_file')
To not have to do that every time, you'd have to add the variable to your .bashrc (assuming you're running a Unix system).
Or you can set a global variable inside your app.js file and store the path of your 'the_file' in it like so :
global.rootPath = __dirname;
Then you can require from any of your files using :
var thefile = require(rootPath+'/the_file')
These are the most convenient methods for me, short of creating a private npm, but there are a few other alternatives that I discovered when looking up an answer to your question, have a look here : https://gist.github.com/branneman/8048520

Resources