Groovy script for scriptrunner - regex

I am currently working on a Scriptrunner script that has the objectives of rejecting push if the user pushes a not freeze dependancies. The script itself is not really hard but I don't know how to use Scriptrunner well enough to make it work, any advices ?
I tried several ways to make my script work, here is the script as it is right now :
def regex = ".*requires\\(\"[^\\d|_|\\-](\\S)+/\\[(\\d)(\\.\\d)*\\]#(eca|exail)/stable\""
def fileName = "conanfile.py"
def file = new File(fileName)
if (file.exists()) {
file.readLines().each { line ->
if (line.startsWith("self.requires")) {
if (!(line =~ regex)) {
log.error("Error: Freeze your dependancies")
return false
}
}
}
// log.info("All 'self.requires' lines match the regex.")
return true
} else {
//log.error("Error: $fileName does not exist.")
return true
}
as you can see it is pretty simple, we check if there is a file named "conanfile.py", and read it to find a line starting with "self.requires" and compare the line with our Regex ( the double \ is because of groovy). I am quite lost on how to make it works on Scriptrunner.

Related

How to automatically go through and edit long txt files?

I have an issue: I've got some chat logs that are thousands of lines ong, and I'm trying to isolate the messages from one specific user. The log looks like this:
[dd-mm-yy hh:mm pm/am] Username
message
[dd-mm-yy hh:mm pm/am] Username
message
[dd-mm-yy hh:mm pm/am] Username
message
In my file, I want to only keep the messages (not the other information like day hour or their username) that one specific user has send, and delete everything else, so I can process the contents of those messages. Is there anything out there that can help me achieve it, because as you can see its a very tedious process to go through thousands of lines of logs doing this by hand.
I ended up writing a js script to do what I wanted since I couldnt find anything anywhere else, here it is:
const fs = require("fs");
const readline = require("readline");
async function processLineByLine() {
const fileStream = fs.createReadStream("./input.txt");
const rl = readline.createInterface({
input: fileStream,
crlfDelay: Infinity,
});
// Note: we use the crlfDelay option to recognize all instances of CR LF
// ('\r\n') in input.txt as a single line break.
let trigger = false;
for await (const line of rl) {
// Each line in input.txt will be successively available here as `line`.
console.log(`Line from file: ${line}`);
if (line.includes("YOU DID THIS TO MY BOI LIM#7483") == true) {
console.log("true");
trigger = true;
}
else if (trigger == true) {
console.log(`Line sent by user: ${line}`);
fs.appendFile("output.txt", line + " ", (err) => {
// throws an error, you could also catch it here
if (err) throw err;
// success case, the file was saved
console.log("line saved");
});
trigger = false;
}
}
}
processLineByLine();

Magento 2.3.3 dashboard keeps loading

I have installed latest version of magento in my localhost.
After login to admin panel dashboard keeps loading.
Here is the image-
Please help to solve this error.
First Go to magento root directory then :
vendor/magento/framework/view/element/tempalate/file/validator.php (dont exactly copy this url just follow this path)
open this file using any editor and change this line
$realPath = $this->fileDriver->getRealPath($path); //you can comment this out
with this one
$realPath = str_replace('\\','/',$this->fileDriver->getRealPath($path));
then goto to
app/etc/di.xml
and search for view_preprocessed
you will find a whole line like this :
Magento\Framework\App\View\Asset\MaterializationStrategy\Symlink
and change the Symlink with Copy
Magento 2.3
go to \lib\internal\Magento\Framework\View\Element\Template\File
go to the function isPathInDirectories and replace the function with following
protected function isPathInDirectories($path, $directories)
{
if (!is_array($directories)) {
$directories = (array)$directories;
}
//$realPath = $this->fileDriver->getRealPath($path);
$realPath = str_replace('\\','/',$this->fileDriver->getRealPath($path));
foreach ($directories as $directory) {
//$realDirectory = $this->fileDriver->getRealPath($directory);
$realDirectory = str_replace('\\','/',$this->fileDriver->getRealPath($directory));
if ($realDirectory && 0 === strpos($realPath, $realDirectory)) {
return true;
}
}
return false;
}
go to app/etc/di.xml then search for view_preprocessed
you will find a whole line like this :
Magento\Framework\App\View\Asset\MaterializationStrategy\Symlink and change to Magento\Framework\App\View\Asset\MaterializationStrategy\Copy
#1. go to vendor/magento/framework/View/Element/Template/File/Validator.php#
#2. go to the function isPathInDirectories and replace the function with following:#
protected function isPathInDirectories($path, $directories)
{
if (!is_array($directories)) {
$directories = (array)$directories;
}
//$realPath = $this->fileDriver->getRealPath($path);
$realPath = str_replace('\\','/',$this->fileDriver->getRealPath($path));
foreach ($directories as $directory) {
//$realDirectory = $this->fileDriver->getRealPath($directory);
$realDirectory = str_replace('\\','/',$this->fileDriver->getRealPath($directory));
if ($realDirectory && 0 === strpos($realPath, $realDirectory)) {
return true;
}
}
return false;
}
#3. go to app/etc/di.xml then search for view_preprocessed
you will find a whole line like this :
Magento\Framework\App\View\Asset\MaterializationStrategy\Symlink and change to
Magento\Framework\App\View\Asset\MaterializationStrategy\Copy #

Test if file exists and executed even at the time of submission

I implemented a feature that tests if my file already exists; whether an error message is displayed and a pop up Java script. Otherwise it does nothing.
Except that at the time of registration of my content. He still enters the loop and as the file is already uploaded it still displays the error message and so I can never create my content.
In advance, thank you for your help.
function bportal_tesst_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'document_node_form') {
$form['field_document_file']['und'][0]['#upload_validators']['custom_document_upload_validation'] = array();
}
return $form;
}
function custom_document_upload_validation($file) {
$filename = $file->filename;
$errors = array();
if (file_exists('/var/www/vhosts/BP/docroot/sites/default/files-private/documents/'.$filename)) {
print_r($filename);
$errors[] = t("The new file already exists. Please use a different name.");
drupal_add_js(drupal_get_path('module','bportal_tesst') . '/js/pop-in.js');
}
return $errors;
}

regex validating telephone number, but chops white space using perl

So I have an HTML field in a form that takes in a phone number. It validates it correctly when I use () or / or - however, if I put in say 555 123 4567, it returns 555. As always your help is greatly appreciates it.
Here is my code
my $userName=param("userName");
my $password=param("password");
my $phoneNumber=param("phoneNumber");
my $email=param("email");
my $onLoad=param("onLoad");
my $userNameReg = "[a-zA-Z0-9_]+";
my $passwordReg = "([a-zA-Z]*)([A-Z]+)([0-9]+)";
my $phoneNumberReg = "((\(?)([2-9]{1}[0-9]{2})(\/|-|\)|\s)?([2-9]{1}[0-9]{2})(\/|-|\s)?([0-9]{4}))";
my $emailReg = "([a-zA-Z0-9_]{2,})(#)([a-zA-Z0-9_]{2,})(.)(com|COM)";
if ($onLoad !=1)
{
#controlValue = ($userName, $password, $phoneNumber, $email);
#regex = ($userNameReg, $passwordReg, $phoneNumberReg, $emailReg);
#validated;
for ($i=0; $i<4; $i++)
{
$retVal= validatecontrols ($controlValue[$i], $regex[$i]);
if ($retVal)
{
$count++;
}
if (!$retVal)
{
$validated[$i]="*"
}
}
sub validatecontrols
{
my $ctrlVal = shift();
my $regexVal = shift();
if ($ctrlVal =~ /^$regexVal$/)
{
return 1;
}
return 0;
}
}
*html code is here*
I realize that this is part of an assignment, so you may be working under specific restraints. However, your attempt to abstract out your data validation is honestly just making things messy and harder to follow. It also ties you down to specifically regex tests, which may not actually be the best bet. As has already been said, email validation should be done via a module.
Also, for this phone validation, an easier solution is just to strip out anything that isn't a number, and then do your validation test. The below code demonstrates what I'm talking about:
my $userName = param("userName");
my $password = param("password");
my $phoneNumber = param("phoneNumber");
my $email = param("email");
my $onLoad = param("onLoad");
my $error = 0;
if ($onLoad !=1)
{
if ($username !~ /^[a-zA-Z0-9_]+$/) {
$username = '*';
$error++;
}
if ($password !~ /^[a-zA-Z]*[A-Z]+[0-9]+$/) {
$password = '*';
$error++;
}
(my $phoneNumOnly = $phoneNumber) =~ s/\D//g;
if ($phoneNumOnly !~ /^1?[2-9]{1}\d{2}[2-9]{1}\d{6}$/) {
$phoneNumber = '*';
$error++;
}
if ($email !~ /^\w{2,}\#\w{2,}\.com$/i) {
$email = '*';
$error++;
}
}
*html code is here*
That regex you're using looks a overly complicated. You have a lot of capturing groups in there, but I get the feeling you're mostly using them to define "OR" statements with the vertical bar. It's usually a lot easier to just use brackets for this purpose if you're only selecting single characters. Also, it's not a good idea to use\s for normal spaces, since this will actually match any whitespace character (tabs and newlines). Maybe try something like this:
(?:\(?[2-9]\d{2}\)?[-\/ ]?)?[2-9]\d{2}[-\/ ]?\d{4}

Need the Groovy way to do partial file substitutions

I have a file that I need to modify. The part I need to modify (not the entire file), is similar to the properties shown below. The problem is that I only need to replace part of the "value", the "ConfigurablePart" if you will. I receive this file so can not control it's format.
alpha.beta.gamma.1 = constantPart1ConfigurablePart1
alpha.beta.gamma.2 = constantPart2ConfigurablePart2
alpha.beta.gamma.3 = constantPart3ConfigurablePart3
I made this work this way, though I know it is really bad!
def updateFile(String pattern, String updatedValue) {
def myFile = new File(".", "inputs/fileInherited.txt")
StringBuffer updatedFileText = new StringBuffer()
def ls = System.getProperty('line.separator')
myFile.eachLine{ line ->
def regex = Pattern.compile(/$pattern/)
def m = (line =~ regex)
if (m.matches()) {
def buf = new StringBuffer(line)
buf.replace(m.start(1), m.end(1), updatedValue)
line = buf.toString()
}
println line
updatedFileText.append(line).append(ls)
}
myFile.write(updatedFileText.toString())
}
The passed in pattern is required to contain a group that is substituted in the StringBuffer. Does anyone know how this should really be done in Groovy?
EDIT -- to define the expected output
The file that contains the example lines needs to be updated such that the "ConfigurablePart" of each line is replaced with the updated text provided. For my ugly solution, I would need to call the method 3 times, once to replace ConfigurablePart1, once for ConfigurablePart2, and finally for ConfigurablePart3. There is likely a better approach to this too!!!
*UPDATED -- Answer that did what I really needed *
In case others ever hit a similar issue, the groovy code improvements I asked about are best reflected in the accepted answer. However, for my problem that did not quite solve my issues. As I needed to substitute only a portion of the matched lines, I needed to use back-references and groups. The only way I could make this work was to define a three-part regEx like:
(.*)(matchThisPart)(.*)
Once that was done, I was able to use:
it.replaceAdd(~/$pattern/, "\$1$replacement\$3")
Thanks to both replies - each helped me out a lot!
It can be made more verbose with the use of closure as args. Here is how this can be done:
//abc.txt
abc.item.1 = someDummyItem1
abc.item.2 = someDummyItem2
abc.item.3 = someDummyItem3
alpha.beta.gamma.1 = constantPart1ConfigurablePart1
alpha.beta.gamma.2 = constantPart2ConfigurablePart2
alpha.beta.gamma.3 = constantPart3ConfigurablePart3
abc.item.4 = someDummyItem4
abc.item.5 = someDummyItem5
abc.item.6 = someDummyItem6
Groovy Code:-
//Replace the pattern in file and write to file sequentially.
def replacePatternInFile(file, Closure replaceText) {
file.write(replaceText(file.text))
}
def file = new File('abc.txt')
def patternToFind = ~/ConfigurablePart/
def patternToReplace = 'NewItem'
//Call the method
replacePatternInFile(file){
it.replaceAll(patternToFind, patternToReplace)
}
println file.getText()
//Prints:
abc.item.1 = someDummyItem1
abc.item.2 = someDummyItem2
abc.item.3 = someDummyItem3
alpha.beta.gamma.1 = constantPart1NewItem1
alpha.beta.gamma.2 = constantPart2NewItem2
alpha.beta.gamma.3 = constantPart3NewItem3
abc.item.4 = someDummyItem4
abc.item.5 = someDummyItem5
abc.item.6 = someDummyItem6
Confirm file abc.txt. I have not used the method updateFile() as done by you, but you can very well parameterize as below:-
def updateFile(file, patternToFind, patternToReplace){
replacePatternInFile(file){
it.replaceAll(patternToFind, patternToReplace)
}
}
For a quick answer I'd just go this route:
patterns = [pattern1 : constantPart1ConfigurablePart1,
pattern2 : constantPart2ConfigurablePart2,
pattern3 : constantPart3ConfigurablePart3]
def myFile = new File(".", "inputs/fileInherited.txt")
StringBuffer updatedFileText = new StringBuffer()
def ls = System.getProperty('line.separator')
myFile.eachLine{ line ->
patterns.each { pattern, replacement ->
line = line.replaceAll(pattern, replacement)
}
println line
updatedFileText.append(line).append(ls)
}
myFile.write(updatedFileText.toString())