git.xqm 3.93 KB
Newer Older
Thomas Friese's avatar
Thomas Friese committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
xquery version "3.1";

module namespace git="http://exist-db.org/apps/git/git";

import module namespace config="http://exist-db.org/apps/git/config" at "config.xqm";


declare variable $git:name := "eXistdb User";
declare variable $git:email := "eXistdb-user@existsolutions.com";
declare variable $git:commit-message := "commited through eXistdb";

declare function git:options( $repo-path as xs:string ) {
    let $options := <options><workingDir>{ $repo-path }</workingDir></options>
    return
        $options
};


declare function git:delete-file( $repo-path as xs:string, $app-root as xs:string, $collection as xs:string, $uri as xs:string ) {
    let $file-uri := $repo-path || "/" || $collection || "/" || $uri
    let $uri-elements := tokenize( $uri, "/" )
    let $path-elements := ( $app-root, $collection, subsequence( $uri-elements, 1, count( $uri-elements )-1 ))
    let $file := $uri-elements[last()]
    let $path := string-join( $path-elements, "/" )
    return(
        util:log( "INFO", $uri ),
        if( file:exists( $file-uri ))
        then
            file:delete( $file-uri )
        else
            util:log( "INFO", "file " || $file-uri || " not found" ),
        if( xmldb:touch( $path, $file ))
        then(
            xmldb:remove( $path, $file )
        )
        else
            util:log( "INFO", "resource " || $path || "/" || $file || " not found" )
    )
};

declare function git:clone( $source-url as xs:string, $repo-path as xs:string, $branch as xs:string ) {
    let $branch := if( $branch )
        then( $branch )
        else( "master" )
    return
        process:execute(( "git", "clone", $source-url, "-b", $branch, $repo-path ), ())
};

declare function git:pull( $repo-path as xs:string ) {
    process:execute(( "git", "pull" ), git:options( $repo-path ))
};

declare function git:sync-files( $repo-path as xs:string, $app-root as xs:string, $collection as xs:string ) {
    (: syncs files to disk :)
    if( $collection ) then
        file:sync( $app-root || "/" || $collection, $repo-path || "/" || $collection, ())
    else
        file:sync( $app-root, $repo-path, ())
};

declare function git:set-committer( $repo-path as xs:string, $name as xs:string, $email as xs:string ) {
    let $name :=
        if( $name ) then $name
        else $git:name
    let $email :=
        if( $email ) then $email
        else $git:email
    let $set-name := process:execute(( "git", "config", "user.name", "'" || $name || "'" ), git:options( $repo-path ))
    let $set-email := process:execute(( "git", "config", "user.email", "'" || $email || "'" ), git:options( $repo-path ))
    return(
        $set-name,
        $set-email
    )
};

declare function git:commit( $repo-path as xs:string, $name as xs:string, $email as xs:string, $message as xs:string, $collection as xs:string ) {
    let $name :=
        if( $name ) then $name
        else $git:name
    let $email :=
        if( $email ) then $email
        else $git:email
    let $message :=
        if( $message ) then $message
        else $git:email
    let $collection :=
        if( $collection ) then $collection
        else "."
    let $add := process:execute(( "git", "add", $collection || "/**" ), git:options( $repo-path ))
    let $commit := process:execute(( "git", "commit", "--quiet", "--no-gpg-sign", "--all",
                                        "--author='" || $name || " <" || $email || ">'",
                                        "--message='" || $message || "'"
                                    ), git:options( $repo-path ))
    return(
        $add,
        $commit
    )
};

declare function git:push( $name,  $email, $message, $repo-path, $app-root, $collection ) {
    util:log( "INFO", $collection ),
    git:pull( $repo-path ),
    git:sync-files( $repo-path, $app-root, $collection ),
    git:set-committer( $repo-path, $name,  $email ),
    git:commit( $repo-path, $name,  $email, $message, $collection ),
    process:execute(( "git", "push", "--quiet" ), git:options( $repo-path ))
};