Say I have following file structure of my application:
Data/prefs.ini
executable.exe
How can I open prefs.ini providing relative path to it from executable.exe is always the same (known at compile time)? Or how can I get absolute path of executable.exe? I need it to work on Linux, Mac and Windows.
There is an exact haxe API for that: Sys.executablePath() (doc)
To get a path relative to it:
import haxe.io.Path;
class Test {
static public function relToExe(path:String):String {
return Path.join([Path.directory(Sys.executablePath()), path]);
}
static function main() {
trace(relToExe("something"));
}
}
Related
Assume that in index.js we have the code
class TestClass {
testMethod() {
console.log('OK');
}
}
We want to write this modified code to output.js, for example:
export default class TestClass {
testMethod() {
console.log('OK');
}
}
Everybody of novices in Node.js can output some text contents with fs.writeFile. The subject in this question is which features are required when we want to generate JavaScript file from other JavaScript file. I suppose, before using fs, we need to preprocess the target JavaScript code. Is it enough to just stringify in, id if so, how to do it? Id Node.js provides some tools for this?
I want to use the library ebnf from NPM and create a bundle using rollup. Since the ebnf is installed to node_modules I also use the rollup plugin rollup-plugin-node-resolve.
The problem is that ebnf contains the code require('..') which - in my case - is resolved to dist in my case. Thus it seems .. is interpreted relative to the output file instead of being relative to the source file.
This is my rollup.config.js (taken from my test repo jneuendorf/rollup-broken-resolve):
import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'cjs'
},
// name: 'MyModule',
plugins: [
resolve(),
commonjs(),
]
}
Is this a problem in rollup-plugin-node-resolve or am I doing something wrong?
Since some of the external libraries needed will still be available only as Common.js modules, you could also convert them to ES-Modules:
"Since most packages in your node_modules folder are probably legacy CommonJS rather than JavaScript modules, you may need to use rollup-plugin-commonjs"
https://github.com/rollup/rollup-plugin-commonjs
"Convert CommonJS modules to ES6, so they can be included in a Rollup bundle"
Just in case someone searching this issue on how to make #rollup/plugin-node-resolve (previously was rollup-plugin-node-resolve) to work with relative path. I just found the solution:
function resolve(file, origin) {
// Your way to resolve local include path
}
function pathResolve(options) {
return {
resolveId: function(file, origin) {
// Your local include path must either starts with `./` or `../`
if (file.startsWith('./') || file.startsWith('../')) {
// Return an absolute include path
return resolve(file, origin);
}
return null; // Continue to the next plugins!
}
};
}
Here is how to combine it with #rollup/plugin-node-resolve:
import {nodeResolve} from '#rollup/plugin-node-resolve';
function pathResolve(options) { /* ... */ }
export default {
// ...
plugins: [pathResolve(), nodeResolve()]
};
I am trying to search a file recursively inside a directory hence cannot use findFiles.
I have seen the directories via manually login in to the slave but it cannot be recognized in the code below. When I use isDirectory() it says false hence later while using dir.listFiles() it return null.
Below is the code:
def recursiveFileSearch(File dir, filename, filesPath) {
File[] files = dir.listFiles() // It returns null here as it cannot recognize it as directory
echo "$files"
for (int i=0; i < files.size(); i++) {
if (files[i].isDirectory()) {
recursiveFileSearch(files[i], filename, filesPath)
} else {
if (files[i].getAbsolutePath().contains(filename)) {
filesPath.add(files[i].getAbsolutePath())
return filesPath
}
}
}
return filesPath
}
node('maven') {
git 'https://github.com/rupalibehera/t3d.git'
sh 'mvn clean install'
File currentDir = new File(pwd())
def isdir = currentDir.isDirectory()
println "isdir:${isdir}" // The output here is False
def isexist = currentDir.exists()
println "isexist:${isexist}" // The output here is False
def canread = currentDir.canRead()
println "canread:${canread}" // The output here is False
def filesPath = []
def openshiftYaml = recursiveFileSearch(currentDir, "openshift.yml", filesPath)
}
I am not sure what is going wrong here.
But below are some observations:
When I do File currentDir = new File("."), it returns / and starts reading complete root directory which I don't want and in that also it does not recognize WORKSPACE as directory
It executes well if I run it on Master node, but in my use case it will be always a slave.
I have also checked the permissions of directory the user has read/write/execute permissions.
Any pointers/help is appreciated
Generally, run a sh step to do whatever work you need. You may not use java.io.File or the like from Pipeline script. It does not run on the agent, and is also insecure, which is why any such attempt will be rejected when the sandbox mode is left on (the default).
you are running into the Using File in Pipeline Description problem. I know it all too well. File objects and NIO work fine for breaking up paths, but their isDirectory, exists and other methods run on master as a part of the Jenkinsfile and not on the node. So, all use on master looks great, because the files are in the workspace. All use on a node, fails.
In short, don't do that. Use fileExists(), pwd(), findFiles etc
If you created a shareLibrary and want to use unit tests on the code outside of Jenkins, then you can create a fascade which relies on the script object ('this' from a pipeline)
Class for shared lib
class PipelineUtils implements Serializable {
static def pipelineScript = null;
/**
* Setup this fascade with access to pipeline script methods
* #param jenkinsPipelineScript
* #return
*/
static initialize(def jenkinsPipelineScript) {
pipelineScript = jenkinsPipelineScript
}
/**
* Use pipelineScript object ('this' from pipeline) to access fileExists
* We cannot use Java File objects for detection as the pipeline script runs on master and uses delegation/serialization to
* get to the node. So, File.exists() will be false if the file was generated on the node and that node isn't master.
* https://support.cloudbees.com/hc/en-us/articles/230922128-Pipeline-Using-java-io-File-in-a-Pipeline-description
* #param target
* #return true if path exists
*/
static boolean exists(Path target) {
if (!pipelineScript) {
throw new Exception("PipelineUtils.initialize with pipeline script not called - access to pipeline 'this' required for access to file detection routines")
}
if (! target.parent) {
throw new Exception('Please use absolutePaths with ${env.WORKSPACE}/path-to-file')
}
return pipelineScript.fileExists(target.toAbsolutePath().toString())
}
/**
* Convert workspace relative path to absolute path
* #param path relative path
* #return node specific absolute path
*/
static def relativeWorkspaceToAbsolutePath(String path) {
Path pwd = Paths.get(pipelineScript.pwd())
return pwd.resolve(path).toAbsolutePath().toString()
}
static void echo(def message) {
pipelineScript.echo(message)
}
}
class for tests
class JenkinsStep {
static boolean fileExists(def path) {
return new File(path).exists()
}
static def pwd() {
return System.getProperty("user.dir")
}
static def echo(def message) {
println "${message}"
}
}
usage in jenkins
PipelineUtils.initialize(this)
println PipelineUtils.exists(".")
// calls jenkins fileExists()
usage in unit tests
PipelineUtils.initialize(new JenkinsStep())
println PipelineUtils.exists(".")
// calls File.exists
I found the answer,
for searching any file in your workspace from Jenkinsfile you can use findFiles step,
I did try this but I was passing the incorrect glob for the same. Now I just do
def files = findFiles(glob: '**/openshift.yml') \\ it returns the path of file
I am trying to compile a Haxe class without defining an entry point by using a build hxml file.
My folder structure looks like the following:
root
|
___src
|___Test.hx
|
___build.hxml
Test.hx has the following contents:
package foo;
class BarLib
{
public function new() {}
public function test() {
return "Hello from BarLib!";
}
}
build.hxml looks like this:
-cp src
--macro "include('foo')"
-js test.js
I then run haxe build.hxml from the root folder which creates the file test.js, but its contents is pretty much empty:
// Generated by Haxe 3.3.0
(function () { "use strict";
})();
It seems not to be able to locate the package foo.
What am I doing wrong?
You declare Test.hx to be part of the foo package, however, it's placed in a folder named src. If you move it to src/foo, Haxe produces the following output:
// Generated by Haxe 3.3.0
(function () { "use strict";
var foo_BarLib = function() {
};
foo_BarLib.prototype = {
test: function() {
return "Hello from BarLib!";
}
};
})();
It's also a bit unusual to have a file named Test.hx that doesn't actually define a type named Test. BarLib.hx might be a better name.
You can also use haxe -cp src foo.Test to compile a single class (and its references) without an entry point
I have an executable that is to be run as a Service in windows. Since the service runs as Local system, what should be the folder I should be writing any data the program uses. As currently, I use %LocalAppData% but when the exe runs as Service it points me to
C:\Windows\System32\config\systemprofile\AppData
I used following code:
std::string GetLocalAppDataPath()
{
HANDLE hfile;
TCHAR szPath[MAX_PATH];
if(SUCCEEDED(SHGetFolderPath(NULL,CSIDL_LOCAL_APPDATA,NULL,0, szPath)))
{
std::string path = boost::lexical_cast<std::string>(szPath);
boost::replace_all(path, "\\", "\\\\");
return path;
}
}
If I call the above code as:
std::string app_data_path = GetLocalAppDataPath();
std::string log_folder_path = app_data_path + "\\\\lpa\\\\output\\\\";
I get C:\WINDOWS\system32\config\systemprofile\AppData\Local\lpa\output\ instead of my own Local App Data Folder. So Should I be using other folder that LocalSystem can access.?
did you try this:
Get CSIDL_LOCAL_APPDATA path for any user on Windows