Replace multiple lines while retaining spacing and indentation with Ruby - ruby

Background
I have the following snippet in a composer.json file:
"extra": {
"magento-force": "override"
}
Using Chef, I'd like use a ruby_block to replace this content with:
"extra": {
"magento-force": "override",
"patches-file": "m2-hotfixes/patches.json"
}
Question
What's the best way to achieve this using ruby so that I retain the proper indentation and spacing, etc? The gsub examples I have seen would result in everything on a single line which is not what I want. (E.g. if I searched for: /"magento-force/": /"override"/ and then replaced it with /"magento-force/": /"override"/, /"patches-file/": /"m2-hotfixes/patches.json/", I'd likely get something like:
"extra": {
"magento-force": "override", "patches-file": "m2-hotfixes/patches.json"
}

Turns out the best way to achieve the exact task I want is to use composer itself. Using this in an execute resource gets me exactly what I need:
config extra.patches-file m2-hotfixes/patches.json
That said, I won't consider this a pure answer to the question posed.

Related

Sort a property in HCL Block

I would like to move name property to the top of the block like this.
There are many resouce block in a file.
Before
resource "datadog_monitor" "A" {
enable_logs_sample = "true"
name = "name"
tags = ["env:dev"]
}
resource "datadog_monitor" "B" {
enable_logs_sample = "true"
name = "name"
tags = ["env:dev"]
}
After
resource "datadog_monitor" "A" {
name = "name"
enable_logs_sample = "true"
tags = ["env:dev"]
}
resource "datadog_monitor" "B" {
name = "name"
enable_logs_sample = "true"
tags = ["env:dev"]
}
OK, I think :help :global and the range/address mechanism is one of Vim's best and most underrated feature so it might deserve a detailed run down.
The core editing pattern is the same as in the commands I suggested in my previous answer to a similar question of yours:
on each line matching a specific regular expression pattern,
do something.
Note that it is a "pattern", not a one-off trick. You are not supposed to "learn" this answer by heart, or commit it to "muscle memory", or bookmark it for the next time you have the exact same problem. Instead, you are supposed to grok the logic behind it in a way that allows you to:
recognize a situation where it might come handy,
apply it without too much thinking.
So, in order to implement the editing pattern described above, we use the :global command, which works like this:
:[range]global/<pattern>/[range]<command>
where:
in range (optional, default is %),
mark each line matching <pattern>,
then execute <command> on range (optional, default is .).
Like lots of things in Vim, :global is conceptually cool but not necessarily useful on its own. The more familiar you are with ranges/addresses and the more Ex commands you know, the more useful it is.
In this specific case, ranges don't matter much but addresses and Ex commands do… and their sum makes problems like these solvable in, IMO, a pretty intuitive way.
Now, let's go back to our problem:
move every "name" line to the top of the block
and express it in terms that match our editing pattern:
mark every line matching name,
then move it below the closest line above matching resource.
Which is a simple:
:g/name/m?resource?
Of course, the exact regular expression patterns to use are context-dependent.
The trick is to internalize the patterns so that you already know how to use any new building block you might come upon.
There is really nothing even remotely god-like, here.

Error in VS Code [Unable to write into user settings. Please open the user settings to correct errors/warnings in it and try again.]

While changing any setting in Visual Studio I'm getting an error like this:
Unable to write into user settings. Please open the user settings to correct errors/warnings in it and try again.
In the settings.json There is a problem as:
Expected Comma JsonC(514)
Error Code:
I suggest to validate your JSON in an online JSON validator like jsonlint for better info where the problem lies.
Also, as mentioned in this SO post and this SO post, that leading 0's on a number would also cause this kind of issue.
If you have a number, don't ever store it with leading zeroes. If you
have a value that needs to have a leading zero, don't treat it as a
number, but as a string. Store it with quotes around it.
Here is an example:
Invalid
{
"attribute": "// numeroConta",
"operator": "=",
"value": 0030152201
}
Valid
{
"attribute": "// numeroConta",
"operator": "=",
"value": "0030152201"
}
Please provide your settings.json if this is not the case.
One of the most common causes for this is presence of comments inside JSON file. While vscode itself loads config with json-with-comments format, the sync part fails and when you use the GUI to configure settings it fails to update the settings.json file, even if you will not see any error/warning reported on the file.
In my case, I had a comma at the end of the main curly brackets, but VS Code wasn't alerting to it specifically:
{
...
}, // <---
In my case I had to open settings.json and add , on the end of
{
"workbench.colorTheme": "Default Light+",
"workbench.colorCustomizations": {
"editorError.foreground": "#00000000",
"editorWarning.foreground": "#00000000",
"editorInfo.foreground": "#00000000"
},

Configure TinyMCE Tag Use (Strong->B, etc) (Django-tinymce)

So, I'm looking through the documentation, and unfortunately it stops short of offering any sort of explanation on how the normal TinyMCE format translates into the settings.py TINYMCE_DEFAULT_CONFIG dictionary.
Basically, I need to configure it so that bold is represented as b, not strong, and other similar changes.
Does anyone have a syntax example they could share for this?
So, it turns out, using:
django-tinymce4-lite
As my library, the way this is done is:
Try adjusting the formatting for inline to use the different element
If it's still persistent, add the element to the extended_valid_elements
Finally, if it really won't stop using strong and em, blacklist those tags
'formats': {
'bold':{'inline': 'b'},
'underline':{'inline': 'u'},
'italic':{'inline': 'i'},
}
and later:
extended_valid_elements:'u,b,i'
finally:
invalid_elements:'em strong'

Customize syntax highlighting colors of data types and variables for typescript in Visual Studio Code

I would like customize syntax highlighting colors for typescript.
I use Visual Studio Code 1.16 and custom theme (Actual) Obsidian.
I try use featues editor.tokenColorCustomizations.
Here is my custom user settings.
{
"editor.fontSize": 20,
"workbench.colorTheme": "(Actual) Obsidian",
"editor.tokenColorCustomizations": {
"functions": "#F1F1F1",
"keywords": "#8EC160",
"types": "#87CEEB",
"numbers": "#F1F1F1",
"variables": "#F1F1F1",
"textMateRules": [
]
}
}
I don’t know how can I select a change color of:
data types keywords (in the screenshot string, number, boolen)
variables (in the screenshot : filtredProducst)
in the screenshot: OnInit
You're on the right track.
As you've seen, editor.tokenColorCustomizations can be used to set broad classes of tokens like "keywords", etc. The exact set of things that can be customized this way does not appear to be documented, but you can refer to the source code for ITokenColorCustomizations.
Then there is the textMateRules section. This can be used to specify things that the "simple" method cannot. The documentation explains the basic idea, but a screenshot may help to illustrate:
First, use the command palette (Ctrl+Shift+P) to run "Developer: Inspect TM Scopes". This pops up a window that will show the sequence of scope labels for any token.
Edit 2020-07-24: As of VSCode 1.47 (and possibly a little earlier) the command is called "Developer: Inspect Editor Tokens and Scopes".
Next, add an entry to textMateRules where the scope specifier matches the stack of scope labels. The matching rules are somewhat complicated but mostly intuitive; you'll probably get it pretty quickly just by experimenting. Changes to the rules take effect as soon as you save settings.json.
Note: VSCode does not appear to completely or correctly implement the TextMate matching rules. It's close, but that's it. (Examples: VSCode does not implement exclusion with "-", and its resolution of "a c" versus "b c" seems incorrect.)
For the specific elements in your question:
Data types can be matched with support.type.primitive
filteredProducts can be matched with variable.other.property
OnInit can be matched with entity.other.inherited-class
Example (that just makes them all red):
"textMateRules": [
{
"scope": [
"support.type.primitive",
"variable.other.property",
"entity.other.inherited-class",
],
"settings": {
"foreground": "#F00",
},
},
],

How print or debug Chef attributes

I created a Chef cookbook with attributes, then tried to boostrap a code to node and pass additional attributes in addition and/or override the defaults.
Is it possible to print an attribute tree to see what attributes are loaded, and which are overridden?
To get the entire attribute tree from inside a converged Chef, as opposed to via knife from Chef Server, which is useless in a solo environment, in a useful form look at node.to_hash. More information is in "Chef::Node".
To get a pretty printed log you can use Chef's JSON library's pretty printer:
output="#{Chef::JSONCompat.to_json_pretty(node.to_hash)}"
log output
or write a file local to your client:
output="#{Chef::JSONCompat.to_json_pretty(node.to_hash)}"
file '/tmp/node.json' do
content output
end
Note that this is the converged node, so you won't get the default/override/etc. levels you can get with node.debug_value, but if you don't actually know the name/path of the attribute, or you need to loop over a number of attributes, this could be your friend.
You'll get a huge result that looks like this highly trimmed example:
{
"chef_type": "node",
"name": "node.example.com",
"chef_environment": "_default",
"build-essential": {
"compile_time": false
},
"homebrew": {
"owner": null,
"auto-update": true,
...
},
"recipe": [
"example"
],
"run_list": [
"recipe[example]"
]
}
"How do you create pretty json in CHEF (ruby)" had the pretty printer pointer.
You can use node.debug_value to show a single attribute. This will print out the value for that attribute at each level. However, doing this at each level for each attribute is harder (I'm not sure of a way to do it). Furthermore, because of the massive volume of attributes from ohai, I'm not sure you'd even want to do it.
If your chef run is completing correctly, you can do a knife node show -l <nodename> (that's a lower case L). That will show you the actual value, but it provides a huge volume of data, and doesn't tell you which values are default, normal, override, etc.
Forking the answer by #keen, this produces a more human readable output in YAML format.
output = node.to_yaml
file '/var/node.yaml' do
content output
end
At times, it might be easy to read the variables off a node, after they are provisioned.
knife node edit <hostname-here> -a

Resources