How to get Chirpy to update mashed files when edits are made - visual-studio

I've just begun using Chirpy, and it's frigging amazing. One problem I'm having is that I'm unable to get it to update the mashed file(s) when an edit is made in one of the "sub" files.
IE: If I have a mashed file called "site.css" (via my js.chirp.config file) which contains "elements.css", "master.css", "misc.css" etc. And I make an edit to one of them (say, master.css), I want chirpy to kick in and redo the site.css with the new edits.
Is this at all possible?

Chirpy does this - just make sure your paths use backslashes rather than forward slashes.
<root>
<FileGroup Name="site.css">
<File Path="css\elements.css" />
<File Path="css\master.css" />
<File Path="css\misc.css" />
</FileGroup>
</root>
Chirpity chirp chirp chirp.

I have
<Folder Pattern="*.min.css" Minify="false" />
And with that wildcard in there, it doesnt run when min.css files are updated. I have to update the config and save for the mash to occur

Related

How To Reference Yaml File Relative to Launch File?

I have a launch file that is loading a yaml file:
<launch>
<rosparam command="load file="filename.yaml" />
<node pkg="my_package" type="my_package_node" name="my_package_node" />
</launch>
The filename.yaml file cannot be found unless I put a complete path: "/home/username/blah/blah/blah". Seeing as this launch file is used on multiple machines by different users and locations for the repository, I obviously cannot hard-code the path. So now what? How do I reference it relative to the location of the launch file?
we can set environment variable PWD for the specified node, eg we'd like to pass a rviz configuration file to rviz, the relative path can be like this:
<arg name="rviz_file" value="$(eval env('PWD')+'/config/showme.rviz')"/>
<node name="rviz" pkg="rviz" type="rviz" args="-d $(arg rviz_file)" required="true" />
Best answer I could find myself was to use $(find package_name) as a starting point:
<launch>
<rosparam command="load file="$(find package_name)/../../yamlFolder/filename.yaml" />
<node pkg="my_package" type="my_package_node" name="my_package_node" />
</launch>
Seems kinda silly though. No reference to the path relative to the launch file itself? Would definitely like a better answer.
If You are using ROS Packages, Launch Folders Are in the root folder of Package So $(find package) are actually one folder before your launch file
If your yaml file is in a ROS package, then I think using the find substitution arg as you do in your answer is the cleanest route. If it's someplace else, I would suggest leveraging environment variables with something like
<launch>
<arg name="yaml_path" default="$(optenv YAML_PATH)"/>
<arg if="$(eval yaml_path == '')" name="yaml_file" value="$(env HOME)/some_folder/filename.yaml" />
<arg unless="$(eval yaml_path == '')" name="yaml_file" value="$(arg yaml_path)/filename.yaml"/>
<rosparam command="load" file="$(arg yaml_file)"/>
</launch>
This kind of gives the best of all worlds. If you've set YAML_PATH as an environment variable (e.g. export YAML_PATH="$HOME/some_path" from terminal or in your bashrc) then the path for yaml_file will use it. If not, optenv will evaluate to an empty string and the arg yaml_file will be set to some default path relative to your home folder. AND, if you have a user that doesn't want to mess with the environment variables at all, they can still pass in a path manually by calling it like
roslaunch my_launch_file.launch yaml_path:=/home/my_name/my_preferred_folder

Why is there a need for a separate item in my MSBuild file?

There are many articles (like this and this) that show how to add files to be published, and they all say to add something like this to the publish profile (.pubxml):
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\Extra Files\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
Why is there a need for the new _CustomFiles item? Why not simply <FilesForPackagingFromProject Include="..\Extra Files\**\*">? I tried it, and for some reason this causes every file in the project to end up in the deployed Extra Files folder. Can someone explain me this behaviour please?
Since you are asking about why this is required, I will have to dive deep into what this code means to explain what you're seeing. <Message /> is our friend!
The meaning of %
Let's first look at what % means by using it in a <Message> task:
<ItemGroup>
<_CustomFiles Include="..\Extra Files\**\*" />
</ItemGroup>
<Message Text="File: %(_CustomFiles.Identity)" />
When you run this, you'll get the following output:
File: ..\Extra Files\file1.txt
File: ..\Extra Files\file2.txt
File: ..\Extra Files\file3.txt
...
File: ..\Extra Files\etc.txt
Basically, the Message task runs once for each item in the item group, because we used %.
What's in the item group?
Let's take a peek at the item group before we even make any changes to it. When this task begins, FilesForPackagingFromProject already has all of the files in them, with various metadata properties, including DestinationRelativePath. Let's see it by adding just this to our task:
<Message Text="File: %(FilesForPackagingFromProject.Identity) -> %(FilesForPackagingFromProject.DestinationRelativePath)" />
This outputs:
File: ..\obj\TempBuildDir\PrecompiledApp.config -> PrecompiledApp.config
File: ..\obj\TempBuildDir\Web.config -> Web.config
File: ..\obj\TempBuildDir\App_Themes\theme.css -> App_Themes\theme.css
...
It's important to realise that this item group is not empty to begin with. You are trying to add items to it.
The working code
When you have sub-elements in an element that has %, they apply once to each iteration, so let's now look at the working code:
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<Message Text="File: %(FilesForPackagingFromProject.Identity) -> %(FilesForPackagingFromProject.DestinationRelativePath)" />
For each item in _CustomFiles, we include it into the FilesForPackagingFromProject item group and set the DestinationRelativePath metadata property to the appropriate RecursiveDir/Filename values - basically the ones that apply for the current element being looked at. Let's look at what this outputs:
File: ..\obj\TempBuildDir\PrecompiledApp.config -> PrecompiledApp.config
File: ..\obj\TempBuildDir\Web.config -> Web.config
File: ..\obj\TempBuildDir\App_Themes\theme.css -> App_Themes\theme.css
...
File: ..\Extra Files\file1.txt -> Extra Files\file1.txt
File: ..\Extra Files\file2.txt -> Extra Files\file2.txt
File: ..\Extra Files\file3.txt -> Extra Files\file3.txt
...
File: ..\Extra Files\etc.txt -> Extra Files\etc.txt
Including just a single file
If you wanted to include just a single file, you can do so as follows:
<FilesForPackagingFromProject Include="..\Extra Files\file1.txt">
<DestinationRelativePath>Extra Files\file1.txt</DestinationRelativePath>
</FilesForPackagingFromProject>
This has no % to expand anywhere, so it does exactly what you would expect: it includes a single file into the output.
The broken code
Now let's try to include a single file, but without hard-coding the path and instead using the % expression from the original code:
<FilesForPackagingFromProject Include="..\Extra Files\file1.txt">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
<Message Text="File: %(FilesForPackagingFromProject.Identity) -> %(FilesForPackagingFromProject.DestinationRelativePath)" />
There are % here so things get expanded, but because this doesn't have a % in the item group element, the expansion works differently and things get pear-shaped:
File: ..\obj\TempBuildDir\PrecompiledApp.config -> PrecompiledApp.config
File: ..\obj\TempBuildDir\Web.config -> Web.config
File: ..\obj\TempBuildDir\App_Themes\theme.css -> App_Themes\theme.css
...
File: ..\Extra Files\file1.txt -> Extra Files\PrecompiledApp.config
File: ..\Extra Files\file1.txt -> Extra Files\Web.config
File: ..\Extra Files\file1.txt -> Extra Files\theme.css
So instead of adding file1.txt to the item group once, it iterates over the entire collection and adds file1.txt once for each file already in it. RecursiveDir is not set in this context, while Filename/Extension are the original filename of each file in the group.
Hopefully you can see now that this will create a file for each file in your entire deployment, but in a flat tree, and notably, the contents will be that of file1.txt rather than the original file.
When you include a wildcard instead of just one file, the same thing happens for every file matched by the wildcard.
How to fix this
Stick with the %(_CustomFiles) fix. Hopefully you will now see why it's necessary and how it does what it does. I do believe this is how you are supposed to do this: here's another question about it, with an answer that recommends this approach.

Change some fields in a file

I need to analyses a file and change some fields.
Example:
<taskdef uri="xxxxxx" resource="/mnt/data/yyy.xml">
<classpath path="/mnt/data/test.jar"/>
</taskdef>
<target name="test"
description="this is a xml file">
<fileset dir="/tmp/data/output/test_1/" includes=all/>
In my case I need to find this part:
<fileset dir="/tmp/data/output/test_1/" includes=all/>
and change just the name (for example) test_1
At the end, save the file
In your comment you say you "cannot use libraries like Nogokiri to parse the file". So I can only guess you're not doing full XML parsing.
Assuming you do not have to parse XML you could just use Ruby's String.replace method on the line in question. Just iterate over the lines in the file until you get to the one in quesion and call replace. Here's some pseudocode.
open file
for each line
is this what I want to change
change line
save (new) file

How to rename and move the file on FTP once processed by camel?

I have several folders on my ftp:
/csv
/xml
/processed
/....
How can I rename and move each file once it has been processed from file.csv to file.done and move it to processed folder ?
I have tried many options like adding tons of parameters to "from" or add something into onCompletion or adding several more routes for just moving files.
All placeholders contain correct values and are processed by Spring.
<route>
<from uri="ftp://{{ftp.user}}#{{ftp.server}}/{{inbound.csv}}?password={{ftp.pass}}&binary=true&include=.*csv"/>
<onCompletion onCompleteOnly="true">
<to uri="ftp://{{ftp.user}}#{{ftp.server}}/{{outbound.csv}}?password={{ftp.pass}}&doneFileName=${file:name}.done"/>
</onCompletion>
<delay>
<constant>15000</constant>
</delay>
<unmarshal><csv/></unmarshal>
<to uri="bean:cSVHandler?method=process"/>
</route>
Please help.
Use the move option which will move/rename the file after its processed,
<from uri="ftp://{{ftp.user}}#{{ftp.server}}/{{inbound.csv}}
?password={{ftp.pass}}&binary=true&include=.*csv
&move=../processed"/>
Which will move the file into the ../processed directory.
See more details about the move option at http://camel.apache.org/file2
In case someone finds this post and does only want to rename the file, you can add
&move=${headers.CamelFileName}.old

PropertyGrid ValueEditor for a file name

I have the following rule definition:
<Rule ...>
<... />
<StringProperty Subtype="file" ...>
<StringProperty.ValueEditors>
<ValueEditor EditorType="DefaultStringPropertyEditor" DisplayName="<Edit...>"/>
<ValueEditor EditorType="DefaultFilePropertyEditor" DisplayName="<Browse...>"/>
</StringProperty.ValueEditors>
</StringProperty>
<... />
</Rule>
It adds the "<Edit...>" and "<Browse...>" options for editing a property, but the Browse dialog asks for an *.exe file, when I need to let user select a *.txt file. There is a combobox in the dialog that allows to choose "All files .", but really that's not an option.
I have tried to find a solution but this extensibility bit does not seem to be well documented.
I have finally found a way to do that, yet for VS2012 only. Putting a metadata piece named Filters with the filters string in the typical open file dialog format seems to do the trick now.
Example:
<ValueEditor EditorType="DefaultFilePropertyEditor" DisplayName="<Browse...>">
<ValueEditor.Metadata>
<NameValuePair Name="Filters" Value="Text (*.txt)|*.txt" />
</ValueEditor.Metadata>
</ValueEditor>

Resources