1

I'm creating a Greasemonkey/UserScript script. Because of the Greasemonkey sandbox I have to keep everything in one file but at 5k+ lines, maintenance is beginning to become rather difficult.

So I want to split up the script in multiple files and then combine them again for testing and/or releasing. I'd also have to be able to add some logic: Releases are per language for example (I don't want to ship German translations for the English release etc:).

As per the Pragmatic Programmer Tip 8 Invest Regularly in Your Knowledge Portfolio I'd like to learn some language to do this for me. What would be a good choice to merge the files rapidly and easily: makefile? Perl? RequireJS? Visual Studio macro's (I use VS.NET to write the UserScript)? Something else?

Laoujin
  • 9,962
  • 7
  • 42
  • 69

2 Answers2

2

This is a bit of a late response, but if all you need to do is merge specific files, you should be able to do it from the command line with a batch script.

Something like:

@ECHO off
COPY file1.txt+file2.txt combined.txt
David M
  • 131
  • 8
0

I rolled my own solution with Autohotkey. I had better used something else but well here is the ahk source:

inputFile := "sourceFileName"
savePath := "C:\Temp\"
saveAs := "targetFileName"

workingDirectory = %A_WorkingDir%
SetWorkingDir, %A_ScriptDir%

ParseFile(fileName, indentCount)
{
    if not FileExist(fileName)
        MsgBox Couldn't find: %fileName%

    replacedFile =
    Loop, Read, %fileName%
    {
        replacedFile .= ParseLine(A_LoopReadLine, indentCount) . "`r"
    }
    StringTrimRight, replacedFile, replacedFile, 1
    return %replacedFile%
}

ParseLine(line, indentCount)
{
    found =
    FoundInclude := RegExMatch(line, "(^\s*)?//\<!--@@INCLUDE "".*"" INDENT=\d //--\>", found)
    if FoundInclude
    {
        ; //<!--@@INCLUDE "importit.txt" INDENT=X //-->
        toIncludeFileName := RegExReplace(found, "^\s*")
        StringMid, toIncludeFileName, toIncludeFileName, 18
        closingQuotePosition := InStr(toIncludeFileName, """")
        StringMid, newIndent, toIncludeFileName, closingQuotePosition + 9
        StringMid, newIndent, newIndent, 1, 1
        StringMid, toIncludeFileName, toIncludeFileName, 1, closingQuotePosition - 1

        If toIncludeFileName
        {
            toIncludeContent := ParseFile(toIncludeFileName, newIndent)
            StringReplace, line, line, %found%, %toIncludeContent%
        }
        else
        {
            StringReplace, line, line, %found%
        }
    }
    else if indentCount
    {
        Loop %indentCount%
        {
            ;line := "    " . line
            line := A_TAB . line
        }
    }

    return %line%
}

; Keep backups of merges?
IfExist, %savePath%%saveAs%
{
    backupCount := 0
    backupFileName = %savePath%%saveAs%
    while FileExist(backupFileName)
    {
        backupFileName = backup\%saveAs%%backupCount%
        backupCount++
    }
    FileMove, %savePath%%saveAs%, %backupFileName%
    FileCopy, %inputFile%, %backupFileName%_source
}

formattedOutput := ParseFile(inputFile, 0)
;fullFileName = %savePath%%SaveAs%
;MsgBox, %A_FileEncoding%
;file := FileOpen, fullFileName, "w"
FileEncoding, UTF-8-RAW
FileAppend, %formattedOutput%, %savePath%%SaveAs%

SetWorkingDir, workingDirectory

return

The sourceFileName looks like this:

function ready() {
    var version = "//<!--@@INCLUDE "version.txt" INDENT=0 //-->";

    // User config
    var user_data = {};
    //<!--@@INCLUDE "config\settings.js" INDENT=1 //-->

    ... more code ...
}

So the syntax for including a file is: //<!--@@INCLUDE "fileToInclude" INDENT=X //--> with X being the indent level.

Laoujin
  • 9,962
  • 7
  • 42
  • 69