Is there a way in rPATH's conary recipe to get the verison of an existing package - rpath

i am trying ...
loadRecipe('existingpackage')
class NewPackage(PackageRecipe):
name = 'newpackage-test'
p = existingpackage.version
print p
but getting error, that existingpackage is not defined

You got it right that loadRecipe needs the name of the package. But to access information from the recipe, you should use the class defined there, not the package name or the recipe filename. (That's also quite natural. Sometimes recipes can define more than one classes.)
For example, in a firefox plugin, I want the version of firefox, so that the plugin can be installed to the right place.
loadRecipe('firefox')
class FirefoxPackageSearch(PackageRecipe):
[snip]
def setup(r):
[snip]
r.macros.ff_version = '.'.join(FireFox.version.split('.')[:2])
I load the firefox recipe and use Firefox.version to get what I want.

since conary is just like (almost) coding in python:
p = .version
print 'your package's Version Number: ' + p
rhs = p.split("_",1)
print 'Latest Your Package's Changeset: ' + rhs[1]

Related

pg gem: 'Warning: no type cast defined for type "numeric" '

I'm having trouble getting typed results out of the pg gem.
require 'pg'
require_relative 'spec/fixtures/database'
client = PG.connect( DB[:pg] )
client.type_map_for_queries = PG::BasicTypeMapForQueries.new(client)
client.type_map_for_results = PG::BasicTypeMapForResults.new(client)
client.exec( %|select * from testme;| ) do |query|
query.each {|r| puts r.inspect }
end
This program gives the output:
Warning: no type cast defined for type "money" with oid 790. Please cast this type explicitly to TEXT to be safe for future changes.
Warning: no type cast defined for type "numeric" with oid 1700. Please cast this type explicitly to TEXT to be safe for future changes.
{"string"=>"thing", "logical"=>true, "cash"=>"£1.23", "reel"=>"2.34", "day"=>#<Date: 2015-12-31 ((2457388j,0s,0n),+0s,2299161j)>, "float"=>3.45}
So: booleans and floats and dates (and integers) get converted, but not numerics or the money type.
Can anyone tell me how to "cast the type explicitly", assuming that I don't want to hard-code a solution for each table?
Hijacking this thread, as after some digging I finally found a way to add a custom decoder/encoder, so posting an example below:
require 'ipaddr'
require 'pg'
class InetDecoder < PG::SimpleDecoder
def decode(string, tuple=nil, field=nil)
IPAddr.new(string)
end
end
class InetEncoder < PG::SimpleEncoder
def encode(ip_addr)
ip_addr.to_s
end
end
# 0 if for text format, can also be 1 for binary
PG::BasicTypeRegistry.register_type(0, 'inet', InetEncoder, InetDecoder)
Here's a catch all for those seeking to cast strings by default:
client = PG.connect( DB[:pg] )
map = PG::BasicTypeMapForResults.new(conn)
map.default_type_map = PG::TypeMapAllStrings.new
client.type_map_for_results = map
Got the same problem with a text-ish field. Solved by duplicating a coder and editing its OID.
text_coder = client.type_map_for_results.coders.find { |c| c.name == 'text' }
new_coder = text_coder.dup.tap { |c| c.oid = 19 } # oid from the warning
conn.type_map_for_results.add_coder(new_coder)
How I got there: it might interest the next guy, if the problem is similar but not identical.
I read other people online talking about type_map_for_results, but how they didn't know how to define a coder. Since it was a text field in my case, I decided to try cloning an existing one. I knew I could find a textual pre-set in a Rails app, so I opened a rails console and searched:
adapter = ActiveRecord::Base.connection
connection = adapter.instance_variable_get("#connection")
mapping = connection.type_map_for_results
cd mapping # my console of choice is `pry`
ls # spotted a likely getter named `coders`
cd coders # again
ls # spotted getter `name` and setter `oid=`
So I put together the code in the solution. Gave it a try, and it worked.
It had not been straightforward to find, so I decided to exit lurker mode and share it on SO. Thereby: thanks #Andreyy for bringing me in :)
[pry cd and ls]
Google the error message: "Warning: no type cast defined for type"
You can find it's source github.
Reding the class, I would guess lines from 150 to 214 could be consiredered
examples:
register_type 0, 'text', PG::TextEncoder::String
alias_type 0, 'varchar', 'text'
Since register_type and alias_type are class methods of PG::BasicTypeRegistry::CoderMap I would play with them just and see if anything changes:
PG::BasicTypeRegistry::CoderMap.alias_type 0, 'money', 'text'
PG::BasicTypeRegistry::CoderMap.alias_type 0, 'numeric', 'text'
Reading the comments in the class it seems that the coding/decoding of those and some other fields is not implemented.
You might consider using a higher level ORM library like AvtiveRecord which implements more types (money).

Chef attributes "no implicit conversion of String into Integer"

I'm writing a chef recipe which simply creates a database config file, but I'm stumped simply access the attributes. I have a few PHP applications being deployed to each instance, and OpsWorks uses the same recipes for everyone, so I have a few different settings in the attributes file.
attributes/database-settings.rb
# API
default[:api][:path] = 'app/config/database.php';
default[:api][:host] = 'test';
default[:api][:database] = 'test';
default[:api][:username] = 'test';
default[:api][:password] = 'test';
recipes/database-settings.rb
Chef::Log.info("Database settings!");
node[:deploy].each do |application, deploy|
if node.has_key?(application)
Chef::Log.info("Application: #{application}");
path = node["api"]["path"]; # ERROR HAPPENING HERE
Chef::Log.info("Path: #{path}");
template path do
source "database.erb"
mode 0440
variables({
:host => node["api"]["host"],
:database => node["api"]["database"],
:username => node["api"]["username"],
:password => node["api"]["password"]
})
end
end
end
The error I'm getting is no implicit conversion of String into Integer. I've tried creating and accessing the settings in every way I can think of, such as...
node[:api][:path] # no implicit conversion of Symbol into Integer
node['api']['path'] # no implicit conversion of String into Integer
node[:api].path # undefined method `path' for #<Chef::Node::ImmutableArray:0x007fa4a71086e8>
node[application][:path] # no implicit conversion of Symbol into Integer
I'm sure there's something very obvious I'm doing wrong here, but I've tried everything I can think of an I just can't seem to find any way of getting this to work?! Ideally I'd like to use a variable where I can "api", but using an if/else wouldn't be too terrible for 3 apps...
That is a common error seen when you try to access an object thinking it is a hash, but is actually an array. In fact, from one of your errors, it can be read that node["api"] is a Chef::Node::ImmutableArray.
Ok so the problem wasn't really that I was accessing the config wrongly, it was that the different attribute files were all being merged into a single config and I didn't realise this.
I had these config files...
attributes/database_settings.rb
default[:api][:path] = 'app/config/database.php';
default[:api][:username] = 'example';
attributes/writable_directories.rb
default[:api] = ['public/uploads', 'storage/cache'];
When I tried to access default[:api][:path] I was actually accessing the array of directories when seemed to override the database settings attributes. Moving these into default[:directories][:api] and default[:database][:api][:path] etc fixed this.
Note that you will also get this error if you accidentally enter a space between "node" and the items indexing it:
node[:foo][:bar]
will work, while
node [:foo][:bar]
will throw this exception. It can be hard to spot.

Substitution in a file name with reStructuredText (Sphinx)?

I want to create several files from a single template, which differ only by a variable name. For example :
(file1.rst):
.. |variable| replace:: 1
.. include template.rst
(template.rst) :
Variable |variable|
=====================
Image
-------
.. image:: ./images/|variable|-image.png
where of course I have an image called "./images/1-image.png". The substitution of "|variable|" by "1" works well in the title, but not in the image file name, and at compilation I get :
WARNING: image file not readable: ./images/|variable|-image.png
How can I get reST to make the substitution in the variable name too? (if this changes anything, am using Sphinx).
There are two problems here: a substitution problem, and a parsing order problem.
For the first problem, the substitution reference |variable| cannot have adjacent characters (besides whitespace or maybe _ for hyperlinking) or else it won't parse as a substitution reference, so you need to escape it:
./images/\ |variable|\ -image.png
However, the second problem is waiting around the corner. While I'm not certain of the details, it seems reST is unable to parse substitutions inside other directives. I think it first parses the image directive, which puts it in the document tree and thus out of reach of the substitution mechanism. Similarly, I don't think it's possible to use a substitution to insert content intended to be parsed (e.g. .. |img1| replace::`.. image:: images/1-image.png`). This is all speculative based on some tests and my incomplete comprehension of the official documentation, so someone more knowledgeable can correct what I've said here.
I think you're aware of the actual image substitution directive (as opposed to text substitution), but I don't think it attains the generality you're aiming for (you'll still need a separate directive for the image as from the |variable|), but in any case it looks like this:
.. |img1| image:: images/1-image.png
Since you're using Sphinx, you can try creating your own directive extension (see this answer for information), but it won't solve the substitutions-inside-markup problem.
You have to create a custom directive in this case as Sphinx doesn't allow you to substitute image paths. You can change Sphinx figure directive as follows and use it instead of the image directive.
from typing import Any, Dict, List, Tuple
from typing import cast
from docutils import nodes
from docutils.nodes import Node, make_id, system_message
from docutils.parsers.rst import directives
from docutils.parsers.rst.directives import images, html, tables
from sphinx import addnodes
from sphinx.directives import optional_int
from sphinx.domains.math import MathDomain
from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import set_source_info
if False:
# For type annotation
from sphinx.application import Sphinx
class CustomFigure(images.Figure):
"""The figure directive which applies `:name:` option to the figure node
instead of the image node.
"""
def run(self) -> List[Node]:
name = self.options.pop('name', None)
path = self.arguments[0] #path = ./images/variable-image.png
#replace 'variable' from th.e given value
self.argument[0] = path.replace("variable", "string substitution")
result = super().run()
if len(result) == 2 or isinstance(result[0], nodes.system_message):
return result
assert len(result) == 1
figure_node = cast(nodes.figure, result[0])
if name:
# set ``name`` to figure_node if given
self.options['name'] = name
self.add_name(figure_node)
# copy lineno from image node
if figure_node.line is None and len(figure_node) == 2:
caption = cast(nodes.caption, figure_node[1])
figure_node.line = caption.line
return [figure_node]
def setup(app: "Sphinx") -> Dict[str, Any]:
directives.register_directive('figure', Figure)
return {
'version': 'builtin',
'parallel_read_safe': True,
'parallel_write_safe': True,
}
You can add this CustomFigure.py directive in the conf.py of the project and use the customfigure directive across Sphinx project instead of the Image directive. Refer http://www.sphinx-doc.org/en/master/usage/extensions/index.html to add a custom directive to your Sphinx project.

How to modify the value of a variable whose name is given

I wish to have a method that takes in a string, and then updates a variable with the name of that string. This is an example of my attempt:
#other_class = OtherClass.new()
def change_variable(variable_string)
self.#other_class.send.variable_string += 1
end
I am getting the error:
syntax error, unexpected tIVAR
with the pointer just before 'send' in the method above. Does anyone have any suggestions to make this work?
You probably want instance_variable_set http://ruby-doc.org/core-2.0/Object.html#method-i-instance_variable_set
The syntax using your variables is I think:
other_var = ('#' + variable_string).to_sym
#other_class.instance_variable_set( other_var, #other_class.instance_variable_get( other_var ) + 1 )
The immediate syntatic error is that you're using self and # wrongly.
Either one is fine but not in conjunction with each other.
So in your case self.other_class.send... would be fine but then you cant declare it as #.
As would # be but then you cant do self.
These are meant to do different things and these are that
# is an instance variable and so is self but the difference is that using # calls the attribute other_class directly as to where self calls the method other_class.
So # is both a getter and setter in one so you can do
#other_class = my_milk_man as to where
self.other_class -> self.other_class (as getter),
self.other_class = my_milk_man -> self.other_class= (as setter).

Does anyone know how to stop T4 (tt) templates from regerating every single file? Is there a way to flag certain files?

So the tt templates will regenerate every file whenever you save. Now, great, it generates files. However, I am making partial classes to extend other classes, but I only need the files that dont already exist for me generated. The ones that exist, I'd like to preserve. So far, I am finding not one solid solution googling the globe...
In my code below, the exception for finding existing files doesnt matter, because the template will start by deleting all files first. Then it regenerates.
It there a method like "onsave" that I can override?
// BEGIN CODE TO GENERATE EXTENSIONS
<#
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
string fileName = entity.Name + ".Extension.cs";
string filePath = this.Host.TemplateFile.Substring(0,this.Host.TemplateFile.LastIndexOf(#"\"));
filePath = filePath + #"\Extensions\" + fileName;
if((File.Exists(filePath) && PreserveExistingExtensions == false) || !File.Exists(filePath))
{
fileManager.StartNewFile(fileName);
BeginNamespace(namespaceName, code);
bool entityHasNullableFKs = entity.NavigationProperties.Any(np => np.GetDependentProperties().Any(p=>ef.IsNullable(p)));
#>
<#=Accessibility.ForType(entity)#>
<#=code.SpaceAfter(code.AbstractOption(entity))#>partial class
<#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>
{
}
<#
EndNamespace(namespaceName);
}
}
fileManager.Process();
#>
I do something similar (partial classes) where I have one that is always generated, but the custom one will only be generated if it doesn't exist. This second one is created as starting class for customizations. I'll output two files like so:
MyClass.generated.cs
MyClass.cs
MyClass.cs will never be recreated, unless it doesn't exist. MyClass.generated.cs will always be recreated.
I use the T4toolbox to do this, Oleg Sych has actually made this quite easy.
You can check out some sample T4 Templates I built here. Specifically have a look at this one, it's a good example for generated partial classes where one needs to be created every time, and one is only created if it doesn't exist.
The main thing to look at is this line in the code:
var requestBaseMessageCustom = new MessageTemplate(rootNamespace, serviceName + "Request");
requestBaseMessageCustom.Output.File = "Messages/" + serviceName + "Request.cs";
requestBaseMessageCustom.Output.PreserveExistingFile = true;
requestBaseMessageCustom.Render();
Notice the property called PreserveExistingFile, that's the key.

Resources