Custom output with capistrano 3 - capistrano3

I need to change output which is generated with sshkit formatters, and I can't install additional gems, but I can adjust my capistrano 3 configs. At first I tried just create new Formatter (I just copy paste pretty formatter, and made some output changes). like this https://gist.github.com/Dariusp/3e455fdb78b9f8636289
than set :format, :improvedformatter in deploy.rb file. And add
require_relative 'lib/improved_formatter'
to Capfile.
But I always get error "Abstract formatter should not be used directly, maybe you want SSHKit::Formatter::BlackHole", like I am trying use abstract formatter directly. if I try extend PrettyFormater, I get PrettyFormatter output, without my changes. It seems like always it execute parent class method. Its there any way how to create and set custom formatter in my capistrano configs ?

I ran into the exact same issue when I wanted to override the pretty formatter.
The problem was that I needed to also define the "<<" operator as this is defined as an alias in the base class and aliases are not inherited.
in deploy.rb:
set :format, :myformatter
in Capfile:
require 'lib/sshkit/formatters/myformatter'
in lib/sshkit/formatters/myformatter.rb:
module SSHKit
module Formatter
class MyFormatter < Pretty
def <<(obj)
write(obj)
end
def write(obj)
...
end
end
end
end

Related

How to read a text file from resources without javaClass

I need to read a text file with readLines() and I've already found this question, but the code in the answers always uses some variation of javaClass; it seems to work only inside a class, while I'm using just a simple Kotlin file with no declared classes. Writing it like this is correct syntax-wise but it looks really ugly and it always returns null, so it must be wrong:
val lines = object {}.javaClass.getResource("file.txt")?.toURI()?.toPath()?.readLines()
Of course I could just specify the raw path like this, but I wonder if there's a better way:
val lines = File("src/main/resources/file.txt").readLines()
Thanks to this answer for providing the correct way to read the file. Currently, reading files from resources without using javaClass or similar constructs doesn't seem to be possible.
// use this if you're inside a class
val lines = this::class.java.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
// use this otherwise
val lines = object {}.javaClass.getResourceAsStream("file.txt")?.bufferedReader()?.readLines()
According to other similar questions I've found, the second way might also work within a lambda but I haven't tested it. Notice the need for the ?. operator and the lines?.let {} syntax needed from this point onward, because getResourceAsStream() returns null if no resource is found with the given name.
Kotlin doesn't have its own means of getting a resource, so you have to use Java's method Class.getResource. You should not assume that the resource is a file (i.e. don't use toPath) as it could well be an entry in a jar, and not a file on the file system. To read a resource, it is easier to get the resource as an InputStream and then read lines from it:
val lines = this::class.java.getResourceAsStream("file.txt").bufferedReader().readLines()
I'm not sure if my response attempts to answer your exact question, but perhaps you could do something like this:
I'm guessing in the final use case, the file names would be dynamic - Not statically declared. In which case, if you have access to or know the path to the folder, you could do something like this:
// Create an extension function on the String class to retrieve a list of
// files available within a folder. Though I have not added a check here
// to validate this, a condition can be added to assert if the extension
// called is executed on a folder or not
fun String.getFilesInFolder(): Array<out File>? = with(File(this)) { return listFiles() }
// Call the extension function on the String folder path wherever required
fun retrieveFiles(): Array<out File>? = [PATH TO FOLDER].getFilesInFolder()
Once you have a reference to the List<out File> object, you could do something like this:
// Create an extension function to read
fun File.retrieveContent() = readLines()
// You can can further expand this use case to conditionally return
// readLines() or entire file data using a buffered reader or convert file
// content to a Data class through GSON/whatever.
// You can use Generic Constraints
// Refer this article for possibilities
// https://kotlinlang.org/docs/generics.html#generic-constraints
// Then simply call this extension function after retrieving files in the folder.
listOfFiles?.forEach { singleFile -> println(singleFile.retrieveContent()) }
In order to have the same url that work for both Jar or in local, the url (or path) needs to be a relative path from the repository root.
..meaning, the location of your file or folder from your src folder.
could be "/main/resources/your-folder/" or "/client/notes/somefile.md"
The url must be a relative path from the repository root.
it must be "src/main/resources/your-folder/" or "src/client/notes/somefile.md"
Now you get the drill, and luckily for Intellij Idea users, you can get the correct path with a right-click on the folder or file -> copy Path/Reference.. -> Path From Repository Root (this is it)
Last, paste it and do your thing.

Spring Annotations - Config with Array attributes

Currently have the following configuration and the application works as expected:
#CrossOrigin(origins = { "https://localhost:5000","http://localhost:5000"})
would like to change to something that can be configured in a properties file for different environments. I Can get to work with one Value but can't figure out a way for it to work with more than one. When a properties file is application-dev.properites has:
cors.client.urls=http://localhost:5000,https://localhost:5000
The appropriates values are not loaded with the following declaration:
#CrossOrigin(origins = {"${cors.client.urls}"})
When the properties file is just one value this declaration works as expected.
I know that I am missing something extremely basic.. Appreciate any help.
You can use SpringEL here as mentioned in Reading a List from properties file and load with spring annotation #Value
#CrossOrigin(origins = {#{'${cors.client.urls}'.split(',')}})

Use content of a tuple as variable session

I extracted from a previous response an Object of tuple with the following regex :
.check(regex(""""idSc":(.{1,8}),"pasTemps":."codePasTemps":(.),"""").ofType[(String,String)].findAll.saveAs ("OBJECTS1"))
So I get my object :
OBJECTS1 -> List((1657751,2), (1658105,2), (4557378,2), (1657750,1), (916,1), (917,2), (1658068,1), (1658069,2), (4557379,2), (1658082,1), (4557367,1), (4557368,1), (1660865,2), (1660866,2), (1658122,1), (921,1), (922,2), (923,2), (1660875,1), (1660876,2), (1660877,2), (1658300,1), (1658301,1), (1658302,1), (1658309,1), (1658310,1), (2996562,1), (4638455,1))
After that I did a Foreach and need to extract every couple to add them in next requests So we tried :
.foreach("${OBJECTS1}", "couple") {
exec(http("request_foreach47"
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
.headers(headers_27))
}
But I get the message : named 'couple' does not support index access
I also though that to use 2 regex on the couple to extract both part could work but I haven't found any way to use a regex on a session variable. (Even if its not needed for this case but possible im really interessed to learn how as it could be usefull)
If would be really thankfull if you could provided me help. (Im using Gatling 2 but can,'t use a more recent version as its for work and others scripts have been develloped with Gatling2)
each "couple" is a scala tuple which can't be indexed into like a collection. Fortunately the gatling EL has a function that handles tuples.
so instead of
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
you can use
.get("/ctr/web/api/seriegraph/bydates/${couple._1}/${couple._2}/1552863600000/1554191743799")

Travis CI is not case-sensitive by default?

I have a php project that has composer dependencies which are inherently tested in the code path of my unit tests. Here's my sample code:
<?php
// where FooBar is a composer package but I'm purposely typing it incorrectly here
use \fooBaR
public function appendNameToWords(array $words, $name)
{
$start = microtime(true);
$newWords = array_map(function($word){
return $word . $name;
}, $words);
// logs the diff between start and end time
FooBar::logTimer($start);
return $newWords;
}
My test is simply testing the method but of course executes the line FooBar::logTimer in my source code. The problem is I'm expecting my test to fail if I mistype the class FooBar to be fooBaR. Unfortunately, the travis build is passing...but i'm unclear why.
.travis.yml file:
language: php
php:
- 5.6
install: script/install
script:
- script/test
Any ideas on what could be wrong?
PHP is not case sensitive when it comes to class names. If your code declares a class named Foo, and this definition is executed, you can also instantiate any other case style, like foo or fOO.
PHP will preserve the case of the occurrence that triggers the autoload (i.e. the first time PHP encounters a class name), and if that case style does not match a case sensitive file name, using the class will fail.
I consider writing the class in the correct case style a problem that should not be tested with a unit test. It's a problem that cannot be solved in your own code - and it is basically not existing if you use a powerful IDE that knows all classes that can be used.
Additionally: Your question does not provide code that demonstrates the problem. And it contains code that probably does not do what you think it does.

GAE: Writing the API: a simple PATCH method (Python)

I have a google-cloud-endpoints, in the docs, I did'nt find how to write a PATCH method.
My request:
curl -XPATCH localhost:8080/_ah/api/hellogreeting/1 -d '{"message": "Hi"}'
My method handler looks like this:
from models import Greeting
from messages import GreetingMessage
#endpoints.method(ID_RESOURCE, Greeting,`
path='hellogreeting/{id}', http_method='PATCH',
name='greetings.patch')
def greetings_patch(self, request):
request.message, request.username
greeting = Greeting.get_by_id(request.id)
greeting.message = request.message # It's ok, cuz message exists in request
greeting.username = request.username # request.username is None. Writing the IF conditions in each string(checking on empty), I think it not beatifully.
greeting.put()
return GreetingMessage(message=greeting.message, username=greeting.username)
So, now in Greeting.username field will be None. And it's wrong.
Writing the IF conditions in each string(checking on empty), I think it not beatifully.
So, what is the best way for model updating partially?
I do not think there is one in Cloud Endpoints, but you can code yours easily like the example below.
You will need to decide how you want your patch to behave, in particular when it comes to attributes that are objects : should you also apply the patch on the object attribute (in which case use recursion) or should you just replace the original object attribute with the new one like in my example.
def apply_patch(origin, patch):
for name in dir( patch ):
if not name.startswith( '__' ):
setattr(origin,name,getattr(patch,name))

Resources