Module dependencies: is it possible to set a mininum version? - module

Is it possible to add a minimum version to a module listed in the depend section of a META6.json file?

It uses the same syntax as the Version class. You can use, for instance, v1.0+, or, in META6.json, simply "1.0+"

To declare a dependency on Foo of version 1 or higher one would do the same as if one was asking zef to install Foo:ver<1.0+>:
zef install "Foo:ver<1.0+>"
"depends" : [
"Foo:ver<1.0+>"
]
Long form identities use version literals for api and ver attributes, and strings for any other (such as auth, file, name, etc). So to describe such a dependency you should write it the same way you would if you were useing it using the literal form :foo<...> ala use Test:ver<6.d+>. This is opposed to :foo(...) form which can run anything, e.g. use Test:ver(do { say 42; v6.d+ }), which would allow arbitrary code execution by just searching for dependencies and thus is not a valid way to describe something in a META6.json

Related

Use (scalar) variables in jsonschema to dynamically set attribute, e.g. title

I am using Google Cloud deployment manager to manage infrastructure as code (IAC) and they support providing schema files for describing IAC templates. Their support of jsonschema is a bit weird - the documentation is very brief but it suggests that they support the latest version of the schema plus they require title and description to be within an info object.
This is irritating because I use an HTML renderer for my schemas, which implements jsonschema and therefore, it requires title and description to be set as top-level properties.
To satisfy both, I need to duplicate, e.g.:
title: foo
description: bar
info:
title: foo
description: bar
I was hoping to just define title and description values once and then use some $ref: "#/$defs/title" magic but I don't think you can use this to dynamically set values like the title because this functionality is intended for schema parsers to fetch block content from elsewhere.
Is there any way I can avoid duplicating the values - beyond dynamically rendering my schema files which I do not want to do.
As far as I can tell, there is no way to use reference within json schema.
As a crude workaround you can use a script to add/replace placeholders:
#!/bin/bash
sed -i 's/\$title/title: foo/g' file.json
sed -i 's/\$desc/description: bar/g' file.json

Accessing resources of a dynamically loaded module

I can't find a way to correctly get access to resources of an installed distribution. For example, when a module is loaded dynamically:
require ::($module);
One way to get hold of its %?RESOURCES is to ask module to have a sub which would return this hash:
sub resources { %?RESOURCES }
But that adds extra to the boilerplate code.
Another way is to deep scan $*REPO and fetch module's distribution meta.
Are there any better options to achieve this task?
One way is to use $*REPO ( as you already mention ) along with the Distribution object that CompUnit::Repository provides as an interface to the META6 data and its mapping to a given data store / file system.
my $spec = CompUnit::DependencySpecification.new(:short-name<Zef>);
my $dist = $*REPO.resolve($spec).distribution;
say $dist.content("resources/$_").open.slurp for $dist.meta<resources>.list;
Note this only works for installed distributions at the moment, but would work for not-yet-installed distributions ( like -Ilib ) with https://github.com/rakudo/rakudo/pull/1812

Dynamic struct member names like in javascript in golang

I am writing a multi-lang website.
I read the language info from users cookies, and I have several translation modules such as en.go gr.go etc.
The modules are of type map[string]string.The problem here is in javascript I can do something like lang[cookies.lang]["whatever message"].'But go does not support accessing struct members in this way.
I could make switch case ormap[string]map[string]string` and map all possible languages, but this is much extra work.
So is there any way golang provides some way to access members like js brackets notation?
Not: There was a similar question on the stack, and somebody wrote to use "reflect" package, but I could not quite understand how it works and failed to reproduce by myself works and failed to reproduce by myself.
One possible route would be to use a map[string]map[string]string.
You could then have a base package in which you declare your base translation variable and in your translation modules, you can use an init function to populate the relevant sub-map. It's essentially optional if you want to do this as separate packages or just separate files (doing it as packages means you have better compile-time control of what languages to include, doing it as files is probably less confusing).
If you go the packages root, I suggest the following structure:
translation/base This is where you export from
translation/<language> These are "import only" packages
Then, in translation/base:
package "base"
var Lang map[string]map[string]string
And in each language-specific package:
package "<language code>"
import "language/base"
var code = "<langcode>"
func init() {
d := map[string]string{}
d[<phrase1>] = "your translation here"
d[<phrase2>] = "another translation here"
// Do this for all the translations
base.Lang[code] = d
}
Then you can use this from your main program:
package "..."
import (
"language/base"
_ "language/lang1" // We are only interested in side-effects
_ "language/lang2" // Same here...
)
Not using separate packages is (almost) the same. You simply ensure that all the files are in the same package and you can skip the package prefix for the Lang variable.
A toy example on the Go Playground, with all the "fiddly" bits inlined.

How do I write a robust structural search template to report Mockito times(1)/Times(1) passed to verify in IntelliJ IDEA?

In my project Mockito.times(1) is often used when verifying mocks:
verify(mock, times(1)).call();
This is redundant since Mockito uses implicit times(1) for verify(Object), thus the following code does exactly what the code above does:
verify(mock).call();
So I'm going to write an a structural search drive inspection to report such cases (let's say, named something like Mockito.times(1) is redundant). As I'm not an expert in IntelliJ IDEA structural search, my first attempt was:
Mockito.times(1)
Obviously, this is not a good seach template because it ignores the call-site. Let's say, I find it useful for the following code and I would not like the inspection to trigger:
VerificationMode times = Mockito.times(1);
// ^ unwanted "Mockito.times(1) is redundant"
So now I would like to define the context where I would like the inspection to trigger. Now the inspection search template becomes:
Mockito.verify($mock$, Mockito.times(1))
Great! Now code like verify(mock, times(1)).call() is reported fine (if times was statically imported from org.mockito.Mockito). But there is also one thing. Mockito.times actually comes from its VerificationModeFactory class where such verification modes are grouped, so the following line is ignored by the inspection:
verify(mockSupplier, VerificationModeFactory.times(1)).get();
My another attempt to fix this one was something like:
Mockito.verify($mock$, $times$(1))
where:
$mock$ is still a default template variable;
$times$ is a variable with Text/regexp set to times, Whole words only and Value is read are set to true, and Expression type (regexp) is set to (Times|VerificationMode) -- at least this is the way I believed it should work.
Can't make it work. Why is Times also included to the regexp? This is the real implementation of *.times(int), so, ideally, the following line should be reported too:
verify(mockSupplier, new Times(1)).get();
Of course, I could create all three inspection templates, but is it possible to create such a template using single search template and what am I missing when configuring the $times$ variable?
(I'm using IntelliJ IDEA Community Edition 2016.1.1)
Try the following search query:
Mockito.verify($mock$, $Qualifier$.times(1))
With $Qualifier$ text/regexp VerificationModeFactory|Mockito and occurrences count 0,1 (to find it when statically imported also).
To also match new Times(1) you can use the following query:
Mockito.verify($mock$, $times$)
With $times$ text/regexp .*times\s*\(\s*1\s*\) and uncheck the Case sensitive checkbox.

Is there a way to specify an Ivy dependency using a dynamic revision but restricting the status?

Is it possible for me to declare a dependency using a dynamic revision while restricting the status of the retrieved artifact? For example, I want to define a version range, something like "[1.0,1.1[", but I don't want artifacts with a status of integration, only milestone or release. So I want version 1.0.5 if it has a status of "release" even if there's a version 1.0.6 with a status of "integration."
I know about latest.status, but that's not really what I want: I need to define an upper and lower limit on the revision.
Maybe the solution is to define your own version-matcher see http://ant.apache.org/ivy/history/latest-milestone/settings/version-matchers.html
I used it (in ivysettings.xml) to make this:
<!-- Matcher for build with given build number
It assumes the version number is on the form
#.#__.# where the lastet '.#' is the build number. -->
<version-matchers usedefaults="true">
<pattern-vm>
<match revision="build_number" pattern="[\d\.]+\.${buildnumber}" args="buildnumber" matcher="regexp"/>
</pattern-vm>
</version-matchers>
You can call it in you build script by setting the revision attribute like 'revision="build_number(${prop.buildnumber})"'
Thanks for asking this question, rsteele. I had a similar question and here is the solution I am using. It works if your range corresponds to sub-revisions:
The easiest way to present this is with an example:
<dependency org="com.acme" name="wigdet" branch="1" rev="latest.milestone">
1/ivy-1.0.xml: status="integration"
1/ivy-1.1.xml: status="milestone"
1/ivy-1.2.xml: status="integration"
The dependency resolves to 1.1.
This works for me but I am not entirely happy with it and I hope someone can point out a better way or poke holes in it:
branch seems appropriate because com.acme actually has a branch in version control which corresponds to version 1.
on the other hand branch seems inappropriate because "1" is part of the revision, and perhaps branch is more useful in other ways.
this doesn't solve the more general problem posed by rsteele.