Ruby: Managing file paths within required classes - ruby

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.

Related

BAZEL + bash: execute bash/python script to do code generation and use them in bazel system

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.

Setting up Sphinx Autodoc with existing project

I'm am completely new to Sphinx and have watched hours of tutorials, but could not find the answer to my issue
I have a current project structure like the following
-project folder
|-sub folder 1
| |- sub folder 1.a
| | - ...
|-sub folder 2
| |- sub folder 2.a
| | - ...
|-sub folder 3
| |- sub folder 3.a
| | - ...
|- .py files
|...
|- conf.py
|- index.rst
|- Makefile
|- _build/
| |-doctrees/
| |-html/
| |...(all the html files generated by "make html")
I have included the following in my conf.py
extensions = ['autoapi.extension']
# Document Python Code
autoapi_type = 'python'
autoapi_dir = '../project folder'
inside each of the sub folders i have .py files that contain classes, functions, modules, members that all need to be documented. Is there a way that sphinx will parse through the current project folder and all of its subdirectories in search for .py files to autodoc? If so, how would I have to set up my index.rst and conf.py file to make this happen?
The error I am seeing is as follows:
Removing everything under '_build'...
Running Sphinx v1.8.5
making output directory...
Extension error:
You must configure an autoapi_dirs setting
Makefile:19: recipe for target 'html' failed
make: *** [html] Error 2
The error is explicit: You must configure an autoapi_dirs setting. You have a typo in your conf.py setting, omitting the "s" in your setting autoapi_dir. See configuration value of autoapi_dirs for autoapi.

How do I get my Puppet module's path?

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

Test with input files in rspec. How to organize?

I have the following structure:
MyProject --> Main folder of my project.
MyProject/my_class.rb
MyProject/inputs/input1.txt
MyProject/inputs/input2.txt
MyProject/rspec/spec_helper.rb
MyProject/rspec/my_class_spec.rb
What is an elegant way or most common way that I can make it so that I can use the input1.txt and input2.txt in my_class_spec.rb?
You can access content of input1.txt from my_class_spec.rb like this:
file1_content = File.read(File.expand_path '../../inputs/input1.txt', __FILE__)

Is it possible to have modular AsciiDoc book (that consists of few files)?

Considering that a book in DocBook format can be done in a "modular" fashion, I hoped I can do similar with AsciiDoc and split chapters and first-level sections in separate files. Unfortunately documentation does not say anything about this. The only possible solution I see so far is to write my own AsciiDoc preprocessor that will merge all "part"-files and generate the book.
Did someone solve this problem by now?
Two example ways from the asciidoc cheatsheet: http://powerman.name/doc/asciidoc
include::footer.txt[]
or
[source,perl]
----
include::script.pl[]
----
I have set up a book template that I use in all by book, you can find it here: asciidoc-book-template-with-rake-and-github
= Nome da disciplina
:doctype: book
:lang: pt-BR
:ascii-ids:
:showcomments:
:gitrepo: https://github.com/xxx/yyy
:code_dir: code
:image_dir: imagens
include::capitulos/prefacio.adoc[]
////
= Nome da Parte =
////
include::capitulos/cap1.adoc[]
include::capitulos/feedback.adoc[]
include::capitulos/cap2.adoc[]
include::capitulos/feedback.adoc[]
include::capitulos/cap3.adoc[]
include::capitulos/feedback.adoc[]
// ...
include::capitulos/glossario.adoc[]
include::capitulos/respostas.adoc[]
////
Always end files with a blank line to avoid include problems.
////
Note the blank lines between the include directives: they prevent the first and last lines of the included files from being adjoined. I don't split chapter on more files because when you include a file asciidoc takes the included file path to be the parent of new includes, look this tree:
.
|-- capitulos
| |-- cap1.adoc
| |-- cap2.adoc
| |-- cap3.adoc
| |-- code
| | `-- cap1
| | |-- helloworld.c
| | `-- Makefile
| |-- feedback.adoc
| |-- glossario.adoc
| |-- prefacio.adoc
| |-- respostas.adoc
| `-- symbols.adoc
|-- docinfo.xml
|-- livro.asc
`-- wip.adoc
When I'm at the file livro.adoc and I what to include feedback.adoc I will use include::capitulos/feedback.adoc[]
But if I'm at the file cap1.adoc you will have to use include::feedback.adoc[] (since they are at the same directory).
I think it's more easy to keep all includes in one same place, it works for me. I only include codes using the other way.
Here is another example in case anyone is looking how to do this.
Book Title Goes Here
====================
Author's Name
v1.1, 2012-11
:doctype: book
:icons:
:max-width: 45em
// Push titles down one level
:leveloffset: 1
include::chapter1.asciidoc[tabsize=4]
include::chapter2.asciidoc[]
include::chapter3.asciidoc[]
include::../../common/appendix/MigrationNotes.asciidoc[]
include::glossary.asciidoc[]
// Return to normal title levels
:leveloffset: 0
Index
=====
One option is covered in the user guide: https://asciidoc.org/userguide.html#X90
To paraphrase the user guide, create a top level wrapper document which uses include:: macros to add the desired content and :leveloffset: attributes to adjust the heading levels.
Another option would be to write a script that would cat all the part files together then pass the result to asciidoc using stdin. That might look something like cat part1.txt part2.txt part3.txt | asciidoc -. Please note that there appears to be issues sometimes when providing input via stdin. Also note extra line breaks may be needed at the end of each part file to prevent cat from affecting the formatting.

Resources