How to replace construction variables without executing the action in SCons? - scons

I have the following action:
act = SCons.Action.Action('$ACTIONVAR', 'Executing a dummy action')
env['EXTENSION'] = '.err'
env['ACTIONVAR'] = '${SOURCE.filebase}$EXTENSION'
I want to have the value of action var depending on different target and sources.
What I want to achieve could be similar to this:
obj = env.Execute(act('file.o', 'file.c'))
print 'Str: ' + str(obj) #this should print 'file.err'
Is it possible to get the value without executing the action ?

You are searching for the env.subst() method. Please check the MAN page for a description of its exact syntax and functionality.

Related

Where is my error with my join in acumatica?

I want to get all the attributes from my "Actual Item Inventry" (From Stock Items Form) so i have:
PXResultset<CSAnswers> res = PXSelectJoin<CSAnswers,
InnerJoin<InventoryItem,
On<CSAnswers.refNoteID, Equal<Current<InventoryItem.noteID>>>
>
>.Select(new PXGraph());
But, this returns me 0 rows.
Where is my error?
UPDATED:
My loop is like this:
foreach (PXResult<CSAnswers> record in res)
{
CSAnswers answers = (CSAnswers)record;
string refnoteid = answers.RefNoteID.ToString();
string value = answers.Value;
}
... but i can not go inside foreach.
Sorry for the English.
You should use an initialized graph rather than just "new PXGraph()" for the select. This can be as simple as "this" or "Base" depending on where this code is located. There are times that it is ok to initialize a new graph instance, but also times that it is not ok. Not knowing the context of your code sample, let's assume that "this" and "Base" were insufficient, and you need to initialize a new graph. If you need to work within another graph instance, this is how your code would look.
InventoryItemMaint graph = PXGraph<InventoryItemMaint>.CreateInstance<InventoryItemMaint>();
PXResultset<CSAnswers> res = PXSelectJoin<CSAnswers,
InnerJoin<InventoryItem, On<CSAnswers.refNoteID, Equal<Current<InventoryItem.noteID>>>>>
.Select(graph);
foreach (PXResult<CSAnswers> record in res)
{
CSAnswers answers = (CSAnswers)record;
string refnoteid = answers.RefNoteID.ToString();
string value = answers.Value;
}
However, since you should be initializing graph within a graph or graph extension, you should be able to use:
.Select(this) // To use the current graph containing this logic
or
.Select(Base) // To use the base graph that is being extended if in a graph extension
Since you are referring to:
Current<InventoryItem.noteID>
...but are using "new PXGraph()" then there is no "InventoryItem" to be in the current data cache of the generic base object PXGraph. Hence the need to reference a fully defined graph.
Another syntax for specifying exactly what value you want to pass in is to use a parameter like this:
var myNoteIdVariable = ...
InventoryItemMaint graph = PXGraph<InventoryItemMaint>.CreateInstance<InventoryItemMaint>();
PXResultset<CSAnswers> res = PXSelectJoin<CSAnswers,
InnerJoin<InventoryItem, On<CSAnswers.refNoteID, Equal<Required<InventoryItem.noteID>>>>>
.Select(graph, myNoteIdVariable);
foreach (PXResult<CSAnswers> record in res)
{
CSAnswers answers = (CSAnswers)record;
string refnoteid = answers.RefNoteID.ToString();
string value = answers.Value;
}
Notice the "Required" and the extra value in the Select() section. A quick and easy way to check if you have a value for your parameter is to use PXTrace to write to the Trace that you can check after refreshing the screen and performing whatever action would execute your code:
PXTrace.WriteInformation(myNoteIdVariable.ToString());
...to see if there is a value in myNoteIdVariable to retrieve a result set. Place that outside of the foreach block or you will only get a value in the trace when you actually get records... which is not happening in your case.
If you want to get deep into what SQL statements are being generated and executed, look for Request Profiler in the menus and enable SQL logging while you run a test. Then come back to check the results. (Remember to disable the SQL logging when done or you can generate a lot of unnecessary data.)

Wrapping Origen::Parameters define_params method

I would like to wrap the define_params method so the user can pass in an array versus a symbol, so binning configuration can be setup for multiple test insertions at once :
scan.define_binning [:ws1, :ws2] do |config|
config.chain.softbin = 'bbxxx'
config.chain.bin = 16
config.logic.softbin = 'bbxxx'
config.logic.bin = 5
end
How would you wrap around the define_params method?
Thanks!
You would be as well submitting an update to Origen to make define_params accept an array of parameter names, but to answer the question (note this is untested):
def define_binning(names, options = {}, &block)
Array(names).each do |name|
define_params(name, options.dup, &block)
end
end
That forces names to an array, then for each name it calls the define_params method with the same options/block.
options.dup is used in case the underlying method does something like options.delete(:blah) and this ensures that each call definitely gets the same set of options passed to it.

Is there a way to auto-fill arguments names?

When I instantiate classes (or call methods) with a large number of parameters I'm always using named arguments. But it's tiring to type each argument name every time:
data class User(val id: String,
val name: String,
val age: Int)
val user = User(id = "1", name = "John", age = 99)
Can IDEA pre-fill parameters like this?
val user = User(
id = ,
name = ,
age =
)
There's a great plugin for that: https://plugins.jetbrains.com/plugin/10942-kotlin-fill-class
It autofills the constructor with some default parameters so you can override the ones you want ;)
This is the way:
Right click on the constructor method
Show Context Actions
Add names to call arguments
Profit
Though this is not actually generating the whole call template with all the parameter names, it might be helpful anyway.
Kotlin IDEA plugin 1.1.1 suggests the parameter names in auto completion as you start typing them. For the User constructor from the example, start typing:
val u = User(i
^
There should be a suggestion id =:
It is inserted if you press Enter or Tab. Then you can continue with the other arguments:
val u = User(id = "123", n
^
Here, name = should appear in suggestions, and so on.
Also, the parameters info popup should help you with it:
See the following requests:
IDEABKL-6690 Automatic code completion when choosing a signature
IDEABKL-5496 Auto-filling the actual Java call arguments
There is an experimental feature you can enable by adding java.completion.argument.live.template=true into Help | Edit Custom Properties.
If you already added all the params values in the constructor, Android studio will help you to do that.
Just click on the Object, in your case on User, then click on option + enter (on mac) and you will have add names to call arguments.
you can use Live template:
setting > Editor > Live Templates
choice code group and add by Green Plus 1.live Template
now you need fill items
Abbreviation is name for call template code.
in template type your code like it:
val user = User(
id = $arg1$,
name = $arg2$,
age = $arg3$
)
$arg1$ means where you can type new and jump by Tab
in code when you type Abbreviation name of your code, can selected and Code Generate there
GoodLuck

Filtering Haystack (SOLR) results by django_id

With Django/Haystack/SOLR, I'd like to be able to restrict the result of a search to those records within a particular range of django_ids. Getting these IDs is not a problem, but trying to filter by them produces some unexpected effects. The code looks like this (extraneous code trimmed for clarity):
def view_results(request,arg):
# django_ids list is first calculated using arg...
sqs = SearchQuerySet().facet('example_facet') # STEP_1
sqs = sqs.filter(django_id__in=django_ids) # STEP_2
view = search_view_factory(
view_class=SearchView,
template='search/search-results.html',
searchqueryset=sqs,
form_class=FacetedSearchForm
)
return view(request)
At the point marked STEP_1 I get all the database records. At STEP_2 the records are successfully narrowed down to the number I'd expect for that list of django_ids. The problem comes when the search results are displayed in cases where the user has specified a search term in the form. Rather than returning all records from STEP_2 which match the term, I get all records from STEP_2 plus all from STEP_1 which match the term.
Presumably, therefore, I need to override one/some of the methods in for SearchView in haystack/views.py, but what? Can anyone suggest a means of achieving what is required here?
After a bit more thought, I found a way around this. In the code above, the problem was occurring in the view = search_view_factory... line, so I needed to create my own SearchView class and override the get_results(self) method in order to apply the filtering after the search has been run with the user's search terms. The result is code along these lines:
class MySearchView(SearchView):
def get_results(self):
search = self.form.search()
# The ID I need for the database search is at the end of the URL,
# but this may have some search parameters on and need cleaning up.
view_id = self.request.path.split("/")[-1]
view_query = MyView.objects.filter(id=view_id.split("&")[0])
# At this point the django_ids of the required objects can be found.
if len(view_query) > 0:
view_item = view_query.__getitem__(0)
django_ids = []
for thing in view_item.things.all():
django_ids.append(thing.id)
search = search.filter_and(django_id__in=django_ids)
return search
Using search.filter_and rather than search.filter at the end was another thing which turned out to be essential, but which didn't do what I needed when the filtering was being performed before getting to the SearchView.

How to get the name of the current layout?

symfony getLayout does not seem to work when layout is set via view.yml. Is there anyway to get this within the controller's action class method
I recently needed this. You can do it but you just need to return the entire view.yml contents as an array:
$view_array = sfViewConfigHandler::getConfiguration(array(sfConfig::get('sf_app_config_dir').'/‌​view.yml'));
Just adjust the relative path from sf_app_config_dir (or use another marker) to get what you need.
It's not a trivial task. The view.yml, is not in the "scope" of the action.
Maybe, you can use setLayout in your action rather then in view.yml.
if you can't, for some reasons... you can try this method to reach datas in view.yml:
Is it possible to get a value from view.yml in an action
Execute the following code in the action. It works for both cases, layout set in the action or in the view.yml.
$controller = $this->getContext()->getController();
$view = $controller->getView($this->getModuleName(), $this->getActionName(), 'Success'); // viewName == 'Success' (default)
$layout_name = $view->getDecoratorTemplate(); // e.g expected: layout.php
Let us know if it works for you.

Resources