I'm making installer program using VMware InstallBuilder (previously named Bitrock InstallBuilder), and need to ensure the non-existence of some files in target directory. Here I describe its logic in Perl fake code:
sub validate_target_dir
{
my $target_dir = shift;
# find all candidate check files
foreach my $file ( glob( "$target_dir/*_vol0.dat" ) )
{
my $fname = basename($file);
# fail if has any data file other than myproduct
if ($fname ne "myproduct_vol0.dat") { return 0; }
}
return 1;
}
However I don't know how to implement similar logic in InstallBuilder, as its findFile action don't return multiple matching files (only the first one).
At current, I find a somewhat twisted way to do it: implement the function in a shell script. InstallBuilder allows you to unpack contents programmatically, so I can pack the script into the installer package and unpack&run it at needed time.
I still seek if there's possible way that purely implemented by InstallBuilder itself.
Related
I am trying to print the sub-file and sub directories of a Specific file. The case is, I will be giving the location of the root-folder directly.First it should print the files and directories of the root-folder,in-case of files , it should only print the name of the file and return .In-case of folders, it should print the folder name and traverse through that sub- folder and print the files and folders present in it . So the case is, if it is file then print the name of file and leave else if it is a folder present ,recursively traverse through the folder and print the contents inside and if you find sub-folder in this folder, again recursively traverse it till you find no folder present. I need to execute in shell-script language
I had writen the sample code for this in java. This is the code logic. I am trying the same logic in shellscript but whenever I call the function recursively,it runs a infinite loop in shell script
Java code :
import java.io.File;
import java.nio.file.Files;
public class Recursion
{
public static void fileRecursive(File root)
{
System.out.println(root.getName());
if(root.isFile())
{
return;
}
else
{
File[] files = root.listFiles();
for(File file : files)
{
fileRecursive(file);
}
}
}
public static void main(String args[])
{
File directoryPath = new File("/home/keshav/Main");
System.out.println("Root Folder : "+directoryPath.getName());
fileRecursive(directoryPath);
}
}
Shell-Script Code:
FileTraverse()
{
path=$dirname
if [ -f "$path" ];
then
return;
else
for dir in `ls $dirname`;
do
FileTraverse $dir
done
fi
}
echo "Enter Root directory name"
read dirname
FileTraverse $dirname
Analyzing your program, we can see:
You assign a value to the variable dirname only once (outside the function in the read statement), but never assign a new value for it. Every invocation of the function (including the recorsive ones) use the same value for this variable.
You call your function by passing a parameter, but you never actually use this parameter.
Solution: Inside the function do a
path=$1
as a first statement and in the function body, replace each occurance of dirname by path.
I have worked with ClearCase triggers in the past but it have been over ten years ago.
I want to make a pre-op trigger which prevents a delivery to a specific stream except for specific users.
I know I can use nusers to allow only certain users to bypass the trigger, but with the opkind do I specify deliver or deliver_start?
For identifying the specific stream, do I write a Perl script that checks for the name, or is there a way I can use the restriction-list or the inclusion-list?
This "Delivery preoperation trigger script" is an official example which could give you some clues on how to write your own (in Perl).
You can see in it how its gets the stream name
use Config;
my $PVOBTAG;
my $tempfile;
my $exit_value;
if ($Config{'osname'} eq 'MSWin32') {
$PVOBTAG = '\cyclone-pvob';
$tempfile = $ENV{TMP}."\\expreop.".$ENV{"CLEARCASE_PPID"}.".txt";
}
else {
$PVOBTAG = '';
}
my $STREAM = "stream:".$ENV{"CLEARCASE_STREAM"};
my $ATTYPE = "attype:deliver_in_progress\#$PVOBTAG";
print $STREAM."\n";
print $ATTYPE."\n";
I want to make use of functions to get the full path and directory name of a script.
For this I made two functions :
function _jb-get-script-path ()
{
#returns full path to current working directory
# + path to the script + name of the script file
return $PWD/${0#./*}
}
function _jb-get-script-dirname ()
{
return ${(_jb-get-script-path)##*/}
}
as $(_jb-get-script-path) should be replaced by the result of the function called.
However, I get an error: ${(_jb-get-script-path)##*/}: bad substitution
therefore i tried another way :
function _jb-get-script-path ()
{
return $PWD/${0#./*}
}
function _jb-get-script-dirname ()
{
local temp=$(_jb-get-script-path);
return ${temp##*/}
}
but in this case, the first functions causes an error : numeric argument required. I tried to run local temp=$(_jb-get-script-path $0) in case the $0 wasn't provided through function call (or i don't really know why) but it didn't change anything
I don't want to copy the content of the second fonction as i don't want to replicate code for no good reason.
If you know why those errors happen, I really would like to know why, and of course, if you have a better solution, i'd gladely hear it. But I'm really interessed in the resolution of this problem.
You need to use echo instead of return which is used for returning a numeric status:
_jb-get-script-path() {
#returns full path to current working directory
# + path to the script + name of the script file
echo "$PWD/${0#./*}"
}
_jb-get-script-dirname() {
local p="$(_jb-get-script-path)"
echo "${p##*/}"
}
_jb-get-script-dirname
Is there a shorter way to set multiple properties to the same value in Powershell in one command than this?
Example:
(gi "c:\test.txt").LastWriteTime = (gi "c:\test.txt").LastAccessTime = (gi "c:\test.txt").CreationTime = Get-date
I'm just curious if there is a way to shorten this syntax.
"CreationTime","LastWriteTime","LastAccessTime" |% {(gi test.txt).$_ = (get-date)}
I've used a slightly modified version of Mjolinor's answer to solve a problem I had of incorrect date on files that had just been downloaded from a remote source. I modified the code to make it cleaner to understand in case I have to come back to in the future (changed the short hand to full command names).
# Correct Access/Create/Write times on transferred files
ForEach( $File in $TransferList ) {
#("CreationTime","LastAccessTime","LastWriteTime") | ForEach {
$(Get-Item $File.Name).$_ = $File.Date
}
}
So the tt templates will regenerate every file whenever you save. Now, great, it generates files. However, I am making partial classes to extend other classes, but I only need the files that dont already exist for me generated. The ones that exist, I'd like to preserve. So far, I am finding not one solid solution googling the globe...
In my code below, the exception for finding existing files doesnt matter, because the template will start by deleting all files first. Then it regenerates.
It there a method like "onsave" that I can override?
// BEGIN CODE TO GENERATE EXTENSIONS
<#
foreach (EntityType entity in ItemCollection.GetItems<EntityType>().OrderBy(e => e.Name))
{
string fileName = entity.Name + ".Extension.cs";
string filePath = this.Host.TemplateFile.Substring(0,this.Host.TemplateFile.LastIndexOf(#"\"));
filePath = filePath + #"\Extensions\" + fileName;
if((File.Exists(filePath) && PreserveExistingExtensions == false) || !File.Exists(filePath))
{
fileManager.StartNewFile(fileName);
BeginNamespace(namespaceName, code);
bool entityHasNullableFKs = entity.NavigationProperties.Any(np => np.GetDependentProperties().Any(p=>ef.IsNullable(p)));
#>
<#=Accessibility.ForType(entity)#>
<#=code.SpaceAfter(code.AbstractOption(entity))#>partial class
<#=code.Escape(entity)#><#=code.StringBefore(" : ", code.Escape(entity.BaseType))#>
{
}
<#
EndNamespace(namespaceName);
}
}
fileManager.Process();
#>
I do something similar (partial classes) where I have one that is always generated, but the custom one will only be generated if it doesn't exist. This second one is created as starting class for customizations. I'll output two files like so:
MyClass.generated.cs
MyClass.cs
MyClass.cs will never be recreated, unless it doesn't exist. MyClass.generated.cs will always be recreated.
I use the T4toolbox to do this, Oleg Sych has actually made this quite easy.
You can check out some sample T4 Templates I built here. Specifically have a look at this one, it's a good example for generated partial classes where one needs to be created every time, and one is only created if it doesn't exist.
The main thing to look at is this line in the code:
var requestBaseMessageCustom = new MessageTemplate(rootNamespace, serviceName + "Request");
requestBaseMessageCustom.Output.File = "Messages/" + serviceName + "Request.cs";
requestBaseMessageCustom.Output.PreserveExistingFile = true;
requestBaseMessageCustom.Render();
Notice the property called PreserveExistingFile, that's the key.