A Puppet module of my application must execute a script that comes with that application. The directory layout is well-known, but the absolute path (of src_root) is variable.
src_root/
my_script.sh <----+
.puppet/ |
modules/ |
my_module/ |
manifests/ | executes
init.pp --+
From where do you want to access the path of your environments?
If from a script, you can find it like so:
puppet config print| grep environmentpath
If from inside puppet, you have it in this variable: $::settings::environmentpath
Related
I am new to Bazel. I have a project which is built with Bazel.
But some of the source files are pre-codegened and then compile them with Bazel.
Now I can run the bash script standalone and run the bazel command:
.
|-- project
| |-- BUILD (will depend on temp_output:codegen)
| |-- scripts
| | |-- codegen.sh (read config.yaml and generate codegen.cpp/hpp and a BUILD.bazel)
| |-- config
| | |-- config.yaml
| |-- temp_output
| | |-- codegen.cpp (not existed before running codegen.sh)
| | |-- codegen.hpp (not existed before running codegen.sh)
| | |-- BAZEL.build (not existed before running codegen.sh)
|-- WORKSPACE
$ ./scripts/codegen.sh
$ bazel build :project
What are done in the codegen.sh:
Read the config.yaml where the contains some other WORKSPACE path and name.
Query the targets in that WORKSPACE.
Create cpp/hpp files to include some headers files.
Create a new BUILD file, adding the depends on those targets.
My goal is to embed the bash script in the bazel system. I tried with rule + action.run. But the failures are for:
sandbox directory is not readable nor writable.
input files cannot be found in sandbox.
Is there a fancy way to do this? Or any examples I can refer to?
The simple way to do this is with genrule. Something like this in project/BUILD:
genrule(
name = "run_codegen",
srcs = [
"codegen.sh",
"config.yaml",
],
outs = [
"codegen.cpp",
"codegen.hpp",
],
cmd = "$(location codegen.sh) --config $(location config.yaml) --cpp $(location codegen.cpp) --hpp $(location codegen.hpp)",
)
cc_library(
name = "codegen",
hdrs = [ "codegen.hpp" ],
srcs = [ "codegen.cpp" ],
)
Some things to note:
Using $(location) to get the paths for the input and output files. If the script uses relative paths, I'd modify it to take the paths as arguments, or write a wrapper script that creates a temporary directory and moves things to/from there based on flags. The only other reliable way to create paths is with "make" variables, but those are generally harder to work with and more brittle with respect to modifications to the genrule.
Not generating a BUILD file. You can only do this from a repository rule, and it gets significantly more complicated. I don't think you need to for this use case, just write the rule in project/BUILD.
If you want to embed this in a rule instead of using genrule for some reason, make sure you're using File.path to get all the paths to embed in the command. That's the equivalent of $(location). It's hard to be more specific about why your rule doesn't work without seeing a copy of it.
I have a directory structure of type
|--bringup-scripts
| |--prep.sh
|--scripts
| |--i2c0.func
| |--bit.func
The prep.sh looks like this :
#!/bin/bash
. ../scripts/i2c0.func
The i2c0.func looks like this :
#!/bin/sh
. ./bit.func
As there is a dependency of i2c0.func on bit.func ,If I run prep.sh from the bringup-scripts folder,it throws an error saying
./bit.func: No such file or directory
How should I resolve this?
What you could do is not using relativ paths, instead defining a starting point for all scripts in the prep.sh file like this:
#!/bin/bash
export ROOT_DIR="$(dirname $PWD)"
. $ROOT_DIR/scripts/i2c0.func
You have to include $ROOT_DIR as a prefix for every script in the scripts directory too, e.g.:
i2c0.func
#!/bin/sh
. $ROOT_DIR/scripts/bit.func
I don't know if there's a standard way to do this, but you could try changing i2c0.func like this:
#!/bin/sh
. ../scripts/bit.func
Though note prep.sh gets its caller's working directory, so it will only work when you run it from bringup-scripts/ or scripts/.
When running a folder traversal in groovy I only get one folder returned instead of the whole tree. So when I have this structure
D:
+- Test
+- Test2
+- Test3
An run this code
def dir = "D:/"
(dir as File).traverse(type: DIRECTORIES) { file ->
println file.path
}
I only get this output
D:\$RECYCLE.BIN
What's wrong here. The script runs as part of a Jenkins Pipeline
Additional Info (summary from my comments)
For testing purpose I run the script on a master on my local machine and jenkins is running under my user which has definitively access to all directories. Actually I only see the first item found i.e. $Recycle.BIN. When I add a D:\$A the corresponding output is D:\$A
When running the script in the jenkins script console, the **output is as expected* (all directories). Also the following call in the pipeline works fine and lists all directories
powershell ''' Get-ChildItem -Recurse -Name D:/ ''' }
I am currently working on getting automatic SCSS -> CSS conversion set up using PyCharm's File Watcher functionality. I am able to have the files output to another directory, but I cannot get them to do it relative to a specific directory. Currently, I have the following settings and relevant file tree:
Tree
|media/
|-c/
| |-css/
| |-folder/
| | |-file2.css
| --file.css
--src/
|-css/
|-folder/
| |-file2.scss
--file.scss
File Watcher Settings
Scope is the media/src/css/ directory and all subdirectories recursively
Arguments is --no-cache --update $FileName$:$ProjectFileDir$/media/c/$FileDirRelativeToProjectRoot$/$FileNameWithoutExtension$.css
Working directory is $ProjectFileDir$/media/src/css/
Output paths to refresh is $ProjectFileDir$/media/c/$FileDirRelativeToProjectRoot$/$FileNameWithoutExtension$.css
With these settings, when I update file2.scss, there is an error stating that media/c/media/src/css/folder does not exist, which is not where I want the file anyway.
The issue that I am having is that I would like to have all paths relative to the working directory root preserved (ie. media/src/css/folder -> media/c/css/folder, but all of my source SCSS files are under multiple folder levels from the project root and the tutorial only specifies how to maintain folder structure if you are compiling directly below the root, not a folder below the root. Does anyone know a way that my folder structure could be preserved so that anything under media/src/css would have the same relative output in media/c/css?
The CrazyCoder posted solution in another Question. It is hard to find, so I'm linking it. https://stackoverflow.com/a/15965088/2047157
Quoting:
The trick is to use $FileDirPathFromParent(dir)$ macro:
Suppose a Ruby project with the following structure...
project/
|-- data
| `-- data.yaml
|-- lib
| |-- project
| | `-- myclass.rb
| `-- project.rb
Within lib/project/myclass.rb, I load data/data.yaml as shown in the example below...
def MyClass
data = YAML::load(File.open('../../data/data.yaml'))
# Other stuff..
end
Within lib/project.rb, I include project/myclass.rb
If project.rb is run, the following error will be thrown...
Errno::ENOENT: No such file or directory - ../../data/data.yaml
In order to get around this, I have to update the file path used in myclass.rb so that it is relative to the root or the lib directory...
../data/data.yaml
Is there a better way to handle this?
You can load the data like this:
filename = File.join File.dirname(__FILE__), '..', '..', 'data', 'data.yaml'
data = YAML::load File.open filename
The way you are currently doing it is kind of bad because it imposes requirements on the user's current directory when he runs your code.
Alternatively, you can embed the YAML data at the end of your ruby file using the __END__ keyword.