Git tips: Removing MadCap attributes/imported files

This forum is for all Flare issues related to using Source Control.
Post Reply
KayJay
Propeller Head
Posts: 23
Joined: Tue Nov 29, 2016 7:19 am

Git tips: Removing MadCap attributes/imported files

Post by KayJay »

I wanted to share a few tricks relating about how I use git with my Flare projects (I don't use the integration with git as I prefer to manage it independently).
This usually works OK, though I've developed a few scripts to manage Flare weirdness.

Disclaimer:
I use the gitbash shell on Windows 7 to do this, and the commands here all use the standard functionality that comes with the windows gitbash installer, except for the python scripts, which use python3 (you will need to add python to your PATH variable).

Clean/smudge filters:
When you open a file in Flare, it writes some attributes to the header of the XML with information about the window size etc. These aren't relevant to source control, so luckily you can write some simple filters that get rid of these.

In your .gitattributes file (in the root of the repo), add:

Code: Select all

*.htm filter=ignoremcheaderattrs
*.flsnp filter=ignoremcheaderatts
In your .gitconfig file, add:

Code: Select all

[filter "ignoremcheaderattrs"]
	smudge = sed \"s/\\sMadCap:\\(lastBlockDepth\\|lastHeight\\|lastWidth\\)=\\\"[0-9]*\\\"//g\"
	clean = sed \"s/\\sMadCap:\\(lastBlockDepth\\|lastHeight\\|lastWidth\\)=\\\"[0-9]*\\\"//g\"
You can read more about clean and smudge filters here and about adding them to an existing repo here.

Ignoring files imported with global project linking:
One problem with global project linking is that while you can see from within Flare that the files are linked and that changes happen somewhere else, git doesn't know about these and will prompt you to commit them. Luckily the names and paths of imported files are saved, so you can use this script to add the paths to your .gitignore (Note: still under development so use carefully!).

Code: Select all

#!python
"""
Script to take a flare import file and make a gitignore here including all the generated files
Argument: an expression(s) that indentifies one or more folder(s), 
The script then targest all the .flimpfl files there
And puts the gitignore in the current directory
"""
import xml.etree.ElementTree as ET
import sys
import glob
import os, os.path

# get the folder(s) to be targeted relative folder/linux expression as argv
folders = sys.argv[1:]

# find import files in directory
impfiles_nested = [glob.glob(folder + '/' +'*.flimpfl') for folder in folders]
impfiles = [item for sublist in impfiles_nested for item in sublist]

print("Files to ignore imports from:", impfiles)
if not len(impfiles) > 0:
	print('No import files found in ', folder + os.sep+ '*.flimpfl')
	exit()

# add a string specifying where the output of this script begins
startstring = "#start of generated files"
oldgit = os.path.join(os.getcwd(), '.gitignore')
newgit = os.path.join(os.getcwd(), 'new.gitignore')

with open(newgit, 'w+') as gi, open(oldgit, 'r') as old:
	# copy the original content of your .gitignore
	for line in old.readlines():
		if not line.startswith(startstring):
			gi.write(line)
		else:
			break
	gi.write('\n'+startstring+'\n')
	for impf in impfiles:
		# write the path given in //GeneratedFiles/Url[@Source] to .gitignore (replacing prev.content)
		gi.write("# generated .gitignore with Flare's global import files from {}\n".format(impf))
		# for each imported file, parse 
		tree = ET.parse(impf)
		root = tree.getroot()
		# find all the generated files
		genfiles = [f.get('Source') for f in root.findall('GeneratedFiles/Url')]
		for f in genfiles:
			# write the relative path unix-wise of the rel path to ignored file from import file
			gi.write(os.path.relpath(os.path.join(os.path.dirname(impf), f)).replace('\\', '/'))
			gi.write('\n')
	gi.write('#end of generated files')

assert os.path.getsize(newgit) > 0
os.remove(oldgit)
os.rename(newgit, oldgit)
To run this script, go to some directory that is a parent of the imported files, then run

Code: Select all

python [name_of_the_script].py [path_to_subdirectory_that_has_import_files] [more paths if needed]
Your .gitignore file in your current working directory has the imported files added to it, taking into account the relative paths of the imported files. Just don't manually add any more expressions in the .gitignore file under the imported files or they will get overwritten.
This still has some quirks - I still need to work on making a hook so this works automatically and am not sure how the .gitignore file itself should be committed - maybe with a clean and smudge filter to remove these generated file paths.

Of course, using git with global project linking has a glaring TODO - when you checkout a different branch, the globally linked files are not affected/updated. It would be great if MadCap would provide a command-line friendly way to re-perform project imports so we could set this up as a hook. In the future I might try to write this myself in Python based on the import files.
wclass
Propellus Maximus
Posts: 1238
Joined: Mon Feb 27, 2006 5:56 am
Location: Melbourne, Australia

Re: Git tips: Removing MadCap attributes/imported files

Post by wclass »

<looking for a LIKE button>
Thanks for this - interesting stuff.
Margaret Hassall - Melbourne
chrispitude
Propeller Head
Posts: 58
Joined: Thu Mar 23, 2017 12:23 pm

Re: Git tips: Removing MadCap attributes/imported files

Post by chrispitude »

Can the header filtering stuff be done when binding a project to Git from within Flare?

Edit: I filed an enhancement request for a native option to suppress these in topic files.
Post Reply