How to implement multi-part / sub commands in Spring Shell? - spring-shell

I am using Spring Shell 3.0.0 to implement a command line application. The application deals with several types of objects and has several commands for each type of object, for example:
list-foos
list-bars
describe-foo XYZ
To improve usability, I would like to change the syntax to
foo list
bar list
foo describe XYZ
I understand that commands can be grouped and am using this functionality, which improves the help text, but as far as I can tell doesn't do anything beyond that.
I could implement this as separate top level foo and bar commands that take the subcommand as a positional parameter, but am looking for a better way. For example, I'd like to be able to define each subcommand as its own method (e.g. using #ShellMethod) so it can have its own parameters, help text, availability, etc.
The documentation implies there is support for sub commands:
A command in a spring-shell structure is defined as an array of commands. This yields a structure
similar to the following example:
command1 sub1
command2 sub1 subsub1
command2 sub2 subsub1
command2 sub2 subsub2
But I haven't been able to figure out how to make this work. Curious if this is possible and if so how to set it up? Ideally, I'd like typing foo to show a list of subcommands, help foo to show help on those commands, etc.

Related

invoking TCL C API's inside tcl package procedures

I am using TCL-C API for my program.
and I read and created test program that is similar to this C++ example.
But I have a problem with this example. when I use this example in the shell (by loading it with load example.o) every input automatically invokes the interpreter of the API and run the command that is related to the input string.
But suppose that I want that the input will invoke tcl procedure that is inside a package required by me , this procedure will check the parameters and will print another message and only after this will invoke TCL-C API related function (kind of wrapper), In this case how can I do it?
I read somewhere that the symbol # is the symbol should be used for invoking external program but I just can't find where it was.
I will give a small example for make things more clear.
somepackage.tcl
proc dosomething { arg1 , arg2 , arg3 } {
# check args here #
set temp [ #invoke here TCL-C API function and set it's result in temp ]
return $temp
}
package provide ::somepackage 1.0
test.tcl
package require ::somepackage 1.0
load somefile.o # this is the object file which implements TCL-C API commands [doSomething 1 2 3 ]
...
But I have a problem with this example. when I use this example in the
shell (by loading it with load example.o) every input automatically
invokes the interpreter of the API and run the command that is related
to the input string.
Provided that you script snippets represent your actual implementation in an accurate manner, then the problem is that your Tcl proc named doSomething is replaced by the C-implemented Tcl command once your extension is loaded. Procedures and commands live in the same namespace(s). When the loading order were reversed, the problem would remain the same.
I read that everything is being evaluated by the tcl interperter so in
this case I should name the tcl name of the C wrap functions in
special way for example cFunc. But I am not sure about this.
This is correct. You have to organise the C-implemented commands and their scripted wrappers in a way that their names do not conflict with one another. Some (basic) options:
Use two different Tcl namespaces, with same named procedures
Apply some naming conventions to wrapper procs and commands (your cFunc hint)
If your API were provided as actual Itcl or TclOO objects, and the individual commands were the methods, you could use a subclass or a mixin to host refinements (using the super-reference, such as next in TclOO, to forward from the scripted refinement to the C implementations).
A hot-fix solution in your current setup, which is better replaced by some actual design, would be to rename or interp hide the conflicting commands:
load somefile.o
Hide the now available commands: interp hide {} doSomething
Define a scripted wrapper, calling the hidden original at some point:
For example:
proc doSomething {args} {
# argument checking
set temp [interp invokehidden {} doSomething {*}$args]
# result checking
return $temp
}

Snakemake: how maintain a snakelike instance value across multiple instances of the same invocation

I want to save some information within the python code that is part of my snake file, and have this information available to the python code in every instance that snakemake creates when it is running the workflow. But a separate run of the workflow should have its own separate instance of information.
For example, say I were to create a UUID in my python code, and then later use it in the python code. But I want the UUID to be the same one in all running instances of the workflow. Instead, a new UUID gets created each time an instance is started.
If I start snakemake twice at the same time, I would want each of the two runs to create their own UUID, but within each run, all instances created by the run would use the same UUID. How to do this? Is there an identifier somewhere in the snakemake object that remains the same within one run across all instances, but changes from run to run?
Here's an example that fails with a 'No rule to produce' error:
import uuid
ID = str(uuid.uuid4())
print("ID:", ID)
rule all:
output: ID
run: print("Hello world")
If instead of 'run' it uses 'shell', it works fine, so I assume that Snakemake is rerunning the snakefile code when it executes the "run" portion of the rule. How could this be modified to work, to retain the first UUID value instead of generating a second one? Also, why isn't the ID specified for output in the rule captured when the rule is first processed, without requiring a second invocation of the python code? Since it works with 'shell', the second invocation is not needed specifically for processing the "output" statement.
Indeed, when you use a run block, Snakemake will invoke itself to execute that job, meaning that it also reparses the Snakefile, generating a new UUID. The same will happen on the cluster. There are good technical reasons for doing it like this (performance, the Python GIL, restrictions with pickling, simplicity and robustness of the implementation).
I am not sure what exactly you want to achieve, but it might help to look at this: http://snakemake.readthedocs.io/en/stable/project_info/faq.html#i-want-to-pass-variables-between-rules-is-that-possible
I've found a method that seems to work: use the process group ID:
ID = str(os.getpgrp())
Multiple instances of the same pipeline have the same group ID. However, I'm not sure if this remains true on a cluster, probably not. In my case that didn't matter.

Dynamically create compiled binary with go

First sorry for perhaps a bad title - I imagine a lot of the difficulty I'm experiencing relates to not knowing the correct terminology for what I'm trying to achieve.
In Go, I wish to have a program which when run can dynamically create a secondary binary. To illustrate with a basic hello world example - in pseudo code since I don't know how to achieve it.
generator.go
-> Read in statement from statement.txt (i.e. "Hello World")
-> Insert this statement into the following program...
package main
import (
"fmt"
)
func main(){
fmt.Println([dynamic statement inserted here])
}
-> compile this code into subprogram
Whenever go run generator.go is executed a subprogram binary is created. Running this would output Hello World. Changing statement.txt to something else and executing go run generator.go again would once more create subprogram which when run would execute the new statement.
In summary
With Go, how can I create a program which can dynamically create a compiled child program as output.
Thanks.
So you have 2 sub-tasks which together do what you want:
Perform a text substitution to acquire the final source code.
Compile the final source code into executable binary.
1. Text substitution
The first can be easily done using the text/template package. You can either have the source templates as separate, individual files, or embedded in the main Go source (e.g. as consts).
You can build / parse the source code templates and get a Template with e.g. template.ParseFiles() or using template.New().Parse(). Once you have your template, assemble (e.g. load from file) the values you want to include in the source template and execute it e.g. with Template.Execute(). You have the final source now.
The text/template package gives you a powerful template engine which is capable to a lot more than just text substitution.
Note: There is also a Go parser implemented and available in the standard library at your disposal in the subpackages of go, but using the text/template package is much simpler and looks it's enough and perfectly fine for your case.
2. Compile
To compile the final source into an executable binary, you need the help of the compiler. You can use the os/exec package to invoke the compiler which will produce the binary. See the exec.Command() function to acquire a Cmd, and Cmd.Run() and Cmd.Start() to execute it.

How to tell whether CMake used initial value for an option?

Say I have an option "ENABLE_Foo" in CMake:
option(ENABLE_Foo "Tell cmake to enable the package Foo" ON)
I want to detect whether the user specified -DENABLE_Foo=ON or -DENABLE_Foo=OFF, or whether the specified initial value ON is being used.
The reason I want to tell whether the user turned the option on or whether it is turned on by default is because Foo requires an additional package and I want to cover these cases:
1) User did not specify a value for the option ENABLE_Foo:
a) Package Foo is found -> use Foo
b) Package Foo is not found -> silently turn off Foo
2) User specified a value for the option ENABLE_Foo:
a) User said -DENABLE_Foo=ON:
i) Package Foo is found -> use Foo
ii) Package Foo is not found -> fatal error message
b) User said -DENABLE_Foo=OFF -> don't use Foo and don't try to find it
If there is no way to tell whether the option value came from user input or from the initial value, are there other ways to achieve what I have outlined above?
If the user gives -DENABLE_Foo=ON on the command line, an entry for the respective option will be added to the CMake cache. While it is possible to inspect this value before invoking the option command, you cannot distinguish whether the value was originally set by the user on the command line, or by the option command itself on a previous CMake run.
Still, achieving the behavior you described is possible.
The main issue is that you cannot model the configuration options you want with just one flag. You are actually dealing with two different options.
The first is whether support for Foo is desired at all, the second is whether Foo is to be considered an optional or a mandatory dependency. Note that the value of the latter is irrelevant in case support for Foo is disabled. One way to handle this would be to remove the option completely in this case. This allows for the following approach:
if(REQUIRE_Foo)
# REQUIRE_Foo implies ENABLE_Foo
unset(ENABLE_Foo CACHE)
endif()
option(ENABLE_Foo "Tell cmake to enable support for package Foo" ON)
if(ENABLE_Foo)
option(REQUIRE_Foo "Abort the build if Foo is not found." OFF)
find_package(Foo) # assuming that FindFoo is a well-behaving find script,
# which will set Foo_FOUND appropriately
else()
unset(REQUIRE_Foo CACHE)
set(Foo_FOUND FALSE)
endif()
if(REQUIRE_Foo AND NOT Foo_FOUND)
message(FATAL_ERROR "Required library Foo could not be found")
endif()
In case the user wants to require Foo support (your case 2a) they would invoke CMake with -DREQUIRE_Foo=TRUE. In case they want to disable Foo completely (your case 2b) they would use -DENABLE_Foo=FALSE. If the user specifies nothing, you get the behavior from your case 1.
Assuming that the rest of the build system is already prepared to handle the case where Foo was not found (case 1b from your question), this should just work without further changes.
Note that even if you could detect whether the flag was set by the user, it would still be undesirable to implement the original behavior from your question.
Assuming we could detect it, the initial value of REQUIRE_Foo in the above code would be set to true if and only if ENABLE_Foo=ON was set on the command line. Doing this implicitly without also adding the REQUIRE_Foo to the set of configuration options is problematic. A user would experience different behaviors on CMake runs even though the build options are the same. You should avoid magical behavior like this. It will only confuse users and give you a hard time debugging failing CMake runs.
Always make build options that depend on configuration given by the user visible to the user.

Using String variable as an expression

Passing commands as variables. I am creating a POP3 client and was crunching through some code when I though of something interesting.
Is it possible to pass strings of vb code to an object so that the object will execute it. I am relatively familiar with vb.net's source code being converted to Intermediate language and then being thrown into a JIT virtual machine, but I was hoping there was a simple way to implement this idea.
I want to be able to use strings
Dim Command as string
Command = "If a + b > 0 then c = a + b" '<----syntactical sugar!
System.Compiler.Something.execute(command)
If anyone has any direction, or any correction to any of the above. I appreciate your time.
Rah!
As a start you may want to check out the open source FileHelpers project.
The Runtime.ClassBuilder class in that project creates a .Net class from text, which can then be used as a normal class.