I'm using Swig as my template engine. I am unable to use safe to pass-through a string without additional escaping.
my_var = "<p>The new buyer can expect a minimal buyers PIP during transfer.</p>";
In the template:
{{ my_var|safe }}
I would expect the value of my_var to be passed through as-is. Instead, the following is output:
<p>The new buyer can expect a minimal buyers PIP during transfer.</p>
The key to this problem is that becomes .
How can this problem be resolved?
Related
So I'm using puppet3 and I have X.yaml and Y.yaml. X.yaml has profiles::resolv_conf::nameservers: [ '1.1.1.1', '8.8.8.8', '2.2.2.2' ]in it. I want to add that [ '1.1.1.1', '8.8.8.8', '2.2.2.2' ] as a value to the servers: which is in Y.yaml:
'dns_test':
plugin_type: 'dns_query'
options:
'servers': \['1.1.1.1', '8.8.8.8', "2.2.2.2"\]
'domains': \['google.com'\]
'record_type': 'A'
'timeout': 5
tags:
'input_source': 'dns_query'
By doing this I want to make sure that when someone change values in profiles::resolv_conf::nameservers: that value is changed in this telegraf plugin too.
I tried multiple solution but the one that was the closest was:
'dns_test':
plugin_type: 'dns_query'
options:
'servers': "%{hiera('profiles::resolv_conf::nameservers')}"
'domains': ['google.com']
'record_type': 'A'
'timeout': 5
tags: 'input_source': 'dns_query'
but problem is that puppet was adding extra " " to the value and final value in plugin conf was:
"["1.1.1.1", "2.2.2.2", "8.8.8.8"]" instead of ["1.1.1.1", "2.2.2.2", "8.8.8.8"]
TL;DR: You can't.
From the current docs and the Puppet documentation archive, I confirm that no version of the %{hiera} interpolation function or its replacement, %{lookup}, ever supported interpolating values other than strings. That's expressed in the current docs like so:
The lookup and hiera interpolation functions look up a key and return
the resulting value. The result of the lookup must be a string; any
other result causes an error.
(Emphasis added)
What you're looking for would be supported by Hiera 5's %{alias} function, provided that the data are available somewhere else in the same hierarchy (which is also a requirement for %{hiera}). Since you're stuck on Puppet 3, however, you're probably on Hiera 2, and certainly not later than Hiera 3.
"But wait!" You may say. "I'm getting a successful interpolation, but the data are just munged". Specifically, you wrote:
problem is that puppet was adding extra " " to the value and final value
Since %{hiera()} interpolates only strings, it is not surprising that you got a string value, given that you got a value at all. I do find it a bit surprising that Puppet did not throw an error, but I'm not prepared to comment further on that without a minimum reproducible example that demonstrates the behavior.
I'm trying to add helpful messages for arbitrary builds. If the build fails the user can, for example, install the package with different arguments.
My interface idea is to provide a function, build-with-message, that would be called with something like this:
build-with-message
''Building ${pkg.name}. Alternative invocations are: ..''
pkg
My implementation is based on builtins.seq
build-with-message = msg : pkg :
seq
(self.runCommand "issue-message" {} ''mkdir $out; echo ${msg}'')
pkg;
When I build a package with build-with-message I never see the message. My hunch is that seq evaluates the runCommand far enough to see that a set is returned and moves on to building the package. I tried with deepSeq as well, but a deepSeq build fails on runCommand. I also tried calling out some attributes from the runCommand, e.g.
(self.runCommand "issue-message" {} ''mkdir $out; echo ${msg}'').drvPath
(self.runCommand "issue-message" {} ''mkdir $out; echo ${msg}'').out
My thought being that calling for one of these would prompt the rest of the build. Perhaps I'm not calling the right attribute, but in any case the ones I've tried don't work.
So:
Is there a way to force the runCommand to build in the above scenario?
Is there already some builtin that just lets me issue messages on top of arbitrary builds?
Here's me answering my own question again, consider this a warning.
Solution:
I've in-lined some numbered comments to help with the explanation.
build-with-message = msg : pkg :
let runMsg /*1*/ = self.runCommand "issue-message"
{ version = toString currentTime; /*2*/ } ''
cat <<EOF
${msg}
EOF
echo 0 > $out /*3*/
'';
in seq (import runMsg /*4*/) pkg; /*5*/
Explanation:
runMsg is the derivation that issues the message.
Adding a version based on the current time ensures that the build of runMsg will not be in /nix/store. Otherwise, each unique message will only be issued for the first build.
After the message is printed, a 0 is saved to file as the output of the derivation.
The import loads runMsg--a derivation, and therefore serialized as the path $out. Import expects a nix expression, which in this case is just the number 0 (a valid nix expression).
Now, since the runMsg output will not be available until after it has been built, the seq command will build it (issuing the message) and then build pkg.
Discussion:
I take note of Robert Hensing's comment to my question--this may not be something Nix was not intended for. I'm not arguing against that. Moving on.
Notice that issuing a message like so will add a file to your nix store for every message issued. I don't know if the message build will be garbage collected while pkg is still installed, so there's the possibility of polluting the nix store if such a pattern is overused.
I also think it's really interesting that the result of the runMsg build was to install a nix expression. I suppose this opens the door to doing useful things.
I have task in VSTS release management that deletes files. I want to have the Contents come from a variable. I have created a variable but I can't figure out how to create a multi-line variable. So for example a variable that deletes the three types of files:
Variable Name= ExcludeFiles
Variable Value= "Lib" "bin\*.pdb" "bin\*.dll.config"
It's possible to use a variable with multiple logical lines as input to a multi-line task parameter, but it may not work for every task. This approach is tested on VSTS using the VS Test 2.x task, which I'll use as an example below. I expect it will work for most of the Microsoft-provided tasks.
Background
Tasks define a set of parameters via a JSON file. Each parameter has an internal name in addition to the display name shown in the UI. It's possible to see the internal parameter name using the "Link settings" button on a task (or by finding the task's source code).
In the "Link settings" dialog, the VS Test 2.x task has a "Setting to link" called "Test assemblies", which is a multi-line string. Looking at "Process parameter to link to this setting", we see the value "Parameters.testAssemblyVer2". testAssemblyVer2 is the name of the internal parameter.
When a task executes, it needs to obtain values for its parameters. Most tasks do this by searching the current environment variables for anything starting with "INPUT_". In the case of testAssemblyVer2, the task will look for an environment variable named INPUT_TESTASSEMBLYVER2.
Just before the task executes, we can turn a delimited variable value into an encoded multi-line value, and write it into the environment variable where it's picked up by the task.
Solution
First, define a variable, "Custom.TestAssemblies" with a semicolon-delimited value **\$(BuildConfiguration)\*.tests.dll;!**\obj\**. The semicolon will become the line split.
Next, add a PowerShell task to the build process just before the VS Test task. Configure it as an Inline script with one Argument "$(Custom.TestAssemblies)". Here, the double quotes are critical.
The inline script looks like this:
Param([String]$toMultiLine)
$newlineDelimited = $toMultiLine -replace ';', "%0D%0A"
Write-Host "##vso[task.setvariable variable=INPUT_TESTASSEMBLYVER2]$newlineDelimited"
That's it! The delimiters in the variable value are converted to URL-encoded CR/LF's, and the agent is instructed to update INPUT_TESTASSEMBLYVER2 with that value. The task picks up the value and parses it for '\n', which matches the embedded %0D%0A's.
Summary
Pick a delimiter like ; and use it to divide the parts of your variable value
Obtain the task's internal parameter name using "Link settings"
Insert a PowerShell task just before the target task and insert the code above, substituting the correct variable and task parameter names
If you set the variable system.debug to true, you'll generally see the various INPUT_ parameters and some of the parsing in the trace output. It depends on the implementation of the specific task.
This solution should work equally well for Build and Release sequences.
Multi-line variable is not supported, I submit a user voice here: Multiple lines variable in Build and Release.
Based on the source code of Delete Files task, it splits contents value by ‘\n’, but based on my test, add ‘\n’ to variable isn’t working (e.g. t1.txt \n t2.txt or t1.txt\nt2.txt).
You can custom build/release task per to the source code of Delete Files task or to do it with your logical and execute it through PowerShell/Command Line task.
Bash solution:
emailbody=$(echo "$output" | sed ':a;N;$!ba;s/\n/%0D%0A/g')
The PowerShell solution from Thomas F. Abraham solved my problem. This modification makes it a bit simpler, no input parameter needed:
$newline = "%0D%0A `t"
Write-Host "##vso[task.setvariable variable=LineBreak]$newline"
I also added a tab character so my next line would be indented. Then just refer to the variable $(LineBreak) where ever you want it.
Solution from Thomas also helped point us in right direction.
No issue loading multiline certificates/keys using "bash" task in azure pipeline with,
export CERTIFICATE=$(echo "$(CERTIFICATE_BASE64)" | base64 -d -w 0)
echo "##vso[task.setvariable variable=CERTIFICATE;]$(echo $CERTIFICATE)"
However trying same using "powershell" task in azure pipeline didn't work with,
$CERTIFICATE = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String("$(CERTIFICATE_BASE64)"))
$CERTIFICATE.Replace("`n","`r`n")
Write-Output "##vso[task.setvariable variable=CERTIFICATE;]$CERTIFICATE"
Swapping in the following did work,
$CERTIFICATE.Replace("`n","%0D%0A")
Solution from "Thomas F. Abraham" helped to write a yml template for the VsTest task:
#Note that it is tricky to specify the multiline-string for the VSTest task
#see 'https://github.com/MicrosoftDocs/azure-devops-docs/issues/1580'
#see 'https://stackoverflow.com/questions/44464976/vsts-release-multi-line-variable' for the solution used in this template
#we set the environment variable 'INPUT_TESTASSEMBLYVER2' instead of setting the input 'testAssemblyVer2' for the task !!!
parameters:
- name: testAssemblies
type: string
default: '**\*test*.dll,!**\*TestAdapter.dll,!**\obj\**'
- name: searchFolder
type: string
default: $(Build.Repository.Name)
- name: codeCoverageEnabled
type: boolean
default: false
steps:
- script: |
echo Paramater testAssemblies: ${{ parameters.testAssemblies }}
echo Paramater searchFolder: ${{ parameters.searchFolder }}
echo Paramater codeCoverageEnabled: ${{ parameters.codeCoverageEnabled }}
displayName: 'Parameters for VSTest'
- powershell: |
$newline = "%0D%0A"
$newlineDelimitedTestAssemblies = '${{ parameters.testAssemblies }}' -replace ',', $newline
Write-Host "##vso[task.setvariable variable=INPUT_TESTASSEMBLYVER2]$newlineDelimitedTestAssemblies"
displayName: 'Set INPUT_TESTASSEMBLYVER2 for VSTest task'
- task: VSTest#2
inputs:
testSelector: 'testAssemblies'
searchFolder: '${{ parameters.searchFolder }}'
vstestLocationMethod: 'location'
vstestLocation: 'C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\Extensions\TestPlatform'
codeCoverageEnabled: ${{ parameters.codeCoverageEnabled }}
displayName: 'Run VSTest VS2022'
Problem
I'm trying to filter a json JQ result to only show a substring of the original string. For example if a JQ filter grabed the value
4ffceab674ea8bb5ec421c612536696839bbaccecf64e851dfc270d795ee55d1
I want it to only return the first 10 characters 4ffceab674.
What I've tried
On the Official JQ website you can find an example that should give me what I need:
Command: jq '.[2:4]'
Input: "abcdefghi"
Output: "cd"
I've tried to test this out with a simple example in the unix terminal:
# this works fine, => "abcdefghi"
echo '"abcdefghi"' | jq '.'
# this doesn't work => jq: error: Cannot index string with object
echo '"abcdefghi"' | jq '.[2:4]'
So, it turns out most of these filters are not yet in the released version. For reference see issue #289
What you could do is download the latest development version and compile from source. See download page > From source on Linux
After that, if indexing still doesn't work for strings, you should, at least, be able to do explode, index, implode combination, which seems to have been your plan.
Looking at the jq-1.3 manual I suspect there isn't a solution using that version since it offers no primitives for extacting parts of a string.
(Really surprised this isn't answered anywhere online; couple posts over the past few years with a similar question, but never answered. Let's hope the Stackoverflow crew can come to the rescue)
Situation:
When using gettext to support application localization, one sometimes wishes to specify a 'domain' with dgettext('domain', 'some text string'). However, when running xgettext, all strings wrapped with dgettext(...) are spit out into one file (default: messages.po).
Given the following example:
dgettext('menus', 'login link');
dgettext('menus', 'account link');
dgettext('footer', 'copyright notice');
dgettext('footer', 'contact form');
is there any way to end up with
menus.po
footer.po
using an extractor such as xgettext?
PHP response desired, although I believe this should be applicable across all languages
The only way I've found to do this is to redefine gettext functions...
example:
function _menus ($str) {
return dgettext('menus', $str);
}
function _footer ($_str) {
return dgettext('footer', $str);
}
_menus('login link');
_menus('account link');
_footer('copyright notice');
_footer('contact form');
else, you only have to run following commands:
xgettext [usual options] -k --keyword=_menus:1 -d menus
xgettext [usual options] -k --keyword=_footer:1 -d footer
Bye!
I do not know how to put different contexts in different files, but I did find that xgettext can extract the domain names into msgctxt fields in the po file. For PHP this is not done by default. To enable this, use for example --keyword=dgettext:1c,2 (in poedit, add "dgettext:1c,2") to the keyword list.
See also:
http://developer.gnome.org/glib/2.28/glib-I18N.html
https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/xgettext-Invocation.html
Achieving this is best done through either code separation or the use of context disambiguation.
If you can separate your menu code from your footer code, then you can truly consider them different domains and extract them accordingly from known locations.
If modular separation is impossible and all the code lives together, then really you should be using context instead of domains. e.g.
translate( 'A string', 'myproject', 'some module' )
Where "myproject" is your domain and "some module" disambiguates the string.
However, reality doesn't always align with best practice, so if you can't refactor your code as Asevere suggests (and that is probably the best answer) then I have a massive hack to offer.
You could exploit the context flag mentioned in Boris's answer - We can repurpose this but only if we're not otherwise going to be using contexts.
I'll repeat that. This hack will only work if your code is not using contexts.
Some PHP holding two domains (including one string used in both) -
<?php // test.php
dgettext( 'abc', 'foo' );
dgettext( 'abc', 'bar' );
dgettext( 'xyz', 'bar' );
We can cheat, and take the domain argument as if we intended it to be the message context (msgctxt field). Extracting from the command line:
xgettext -LPHP --keyword=dgettext:1,2c -o - test.php \
| sed 's/CHARSET/utf-8/' \
> combined.pot
This generates a combined.pot file containing all the strings with our context hack. (note we also fixed the placeholder character set field which would break the next bit)
We can now filter out all messages of a given context into separate files using msggrep. Note we also trash the context field as we're not using it.
msggrep -J -e foo -o - combined.pot | sed '/^msgctxt/d' > foo.pot
msggrep -J -e bar -o - combined.pot | sed '/^msgctxt/d' > bar.pot
Improper, but it works.