#!/usr/bin/env python3

# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

import os, sys, codecs
from argparse import ArgumentParser
from subprocess import check_output
from io import StringIO
from xml.etree import ElementTree as et
from datetime import datetime
from sldr.ldml_merge import LdmlMerge, flattenlocale

def find_ldml(fname, dirs) :
    for d in dirs :
        f = os.path.join(d, fname)
        if os.path.exists(f) : return f
        f = os.path.join(d, fname[0].lower(), fname)
        if os.path.exists(f) : return f
    return None

parser = ArgumentParser()
parser.add_argument('this',help='File of interest')
parser.add_argument('base',help="Common ancestor, or file to use in git")
parser.add_argument('other',nargs='?',help='Another file of interest')
parser.add_argument('-o','--output',help="Output file")
parser.add_argument('-w','--winner',help="Clash win: other, this")
parser.add_argument('-d','--dirs',action='append',help='Directory to search for ldml files, repeatable')
parser.add_argument('-g','--git',action='store_true',help='Automatically work out what to do inside a git repo using sil:identity/@revid')
parser.add_argument('-c','--default',default='proposed',help="Default Change draft level")
parser.add_argument('-C','--copycomments',help="Assumes this file has comments stripped rather than deleted, and uses either 'base' or 'other' as source of comments")
parser.add_argument('-G','--nogeneration',action="store_true",help="Don't update the identity/generation element")
parser.add_argument('-v','--verbose',action="store_true",help="Be verbose")
args = parser.parse_args()

this = LdmlMerge(args.this, winner=args.winner)
if args.dirs :
    this = flattenlocale(this, dirs=args.dirs, rev='f', fname=args.this)

other = None
if args.git :
    idnode = this.find("./identity/special/sil:identity")
    revid = None
    if idnode is not None :
        revid = idnode.get('revid', None)
    if revid is not None :
        fpath = find_ldml(args.base, args.dirs)
        if fpath is None : raise SyntaxError("Bad base value: " + args.base + ", or search dirs: " + args.dirs)
        base_str = check_output(["git", "show", revid+":"+fpath])
        basefh = StringIO(base_str)
        base = flattenlocale(basefh, dirs=args.dirs, rev='f', fname=args.base)
        latestid = check_output(["git", "log", "-n", "1", '--pretty=format:%H', revid+"..", fpath])
        if latestid :
            other_str = check_output(["git", "show", latestid+":"+fpath])
            otherfh = StringIO(other_str)
            other = flattenlocale(otherfh, dirs=args.dirs, rev='f', fname=args.base)
else :
    base = LdmlMerge(args.base)
    if args.other :
        other = LdmlMerge(args.other)

if args.verbose:
    print(f"{args=}")
    print(f"{this.default_draft=} {base.default_draft=} {other.default_draft=}")
if this.merge(other, base, default=args.default, copycomments=args.copycomments) and not args.nogeneration :
    # update the date
    idnode = this.find("./identity/generation")
    if idnode is None :
        i = this.find("./identity")
        idnode = i.makeelement("generation", {})
        # idnode = et.SubElement(i, "generation")
    currdate = datetime.now()
    #currdate.microsecond = 0
    #idnode.set("date","$Date: " + currdate.isoformat() + " $")
sys.stdout = codecs.getwriter("UTF-8")(sys.stdout)
this.normalise()

if args.git :
    idnode = this.find("./identity/special/sil:identity")
    if idnode is not None :
        for k in ('uid', 'revid') :
            if k in idnode.attrib : del idnode.attrib[k]
    this = flattenlocale(this, rev='r', dirs=args.dirs, fname=args.this)

if not args.output :
    outfh = sys.stdout
else :
    outfh = codecs.open(args.output, "w", encoding="utf-8")

this.normalise(usedrafts=True)
this.serialize_xml(outfh.write)

if args.output :
    outfh.close()


22fa9956c3f04738ab6b61c13bde8b0fb7377d0c
<mask token>


def find_ldml(fname, dirs):
    for d in dirs:
        f = os.path.join(d, fname)
        if os.path.exists(f):
            return f
        f = os.path.join(d, fname[0].lower(), fname)
        if os.path.exists(f):
            return f
    return None


<mask token>

<mask token>


def find_ldml(fname, dirs):
    for d in dirs:
        f = os.path.join(d, fname)
        if os.path.exists(f):
            return f
        f = os.path.join(d, fname[0].lower(), fname)
        if os.path.exists(f):
            return f
    return None


<mask token>
parser.add_argument('this', help='File of interest')
parser.add_argument('base', help='Common ancestor, or file to use in git')
parser.add_argument('other', nargs='?', help='Another file of interest')
parser.add_argument('-o', '--output', help='Output file')
parser.add_argument('-w', '--winner', help='Clash win: other, this')
parser.add_argument('-d', '--dirs', action='append', help=
    'Directory to search for ldml files, repeatable')
parser.add_argument('-g', '--git', action='store_true', help=
    'Automatically work out what to do inside a git repo using sil:identity/@revid'
    )
parser.add_argument('-c', '--default', default='proposed', help=
    'Default Change draft level')
parser.add_argument('-C', '--copycomments', help=
    "Assumes this file has comments stripped rather than deleted, and uses either 'base' or 'other' as source of comments"
    )
parser.add_argument('-G', '--nogeneration', action='store_true', help=
    "Don't update the identity/generation element")
parser.add_argument('-v', '--verbose', action='store_true', help='Be verbose')
<mask token>
if args.dirs:
    this = flattenlocale(this, dirs=args.dirs, rev='f', fname=args.this)
<mask token>
if args.git:
    idnode = this.find('./identity/special/sil:identity')
    revid = None
    if idnode is not None:
        revid = idnode.get('revid', None)
    if revid is not None:
        fpath = find_ldml(args.base, args.dirs)
        if fpath is None:
            raise SyntaxError('Bad base value: ' + args.base +
                ', or search dirs: ' + args.dirs)
        base_str = check_output(['git', 'show', revid + ':' + fpath])
        basefh = StringIO(base_str)
        base = flattenlocale(basefh, dirs=args.dirs, rev='f', fname=args.base)
        latestid = check_output(['git', 'log', '-n', '1',
            '--pretty=format:%H', revid + '..', fpath])
        if latestid:
            other_str = check_output(['git', 'show', latestid + ':' + fpath])
            otherfh = StringIO(other_str)
            other = flattenlocale(otherfh, dirs=args.dirs, rev='f', fname=
                args.base)
else:
    base = LdmlMerge(args.base)
    if args.other:
        other = LdmlMerge(args.other)
if args.verbose:
    print(f'args={args!r}')
    print(
        f'this.default_draft={this.default_draft!r} base.default_draft={base.default_draft!r} other.default_draft={other.default_draft!r}'
        )
if this.merge(other, base, default=args.default, copycomments=args.copycomments
    ) and not args.nogeneration:
    idnode = this.find('./identity/generation')
    if idnode is None:
        i = this.find('./identity')
        idnode = i.makeelement('generation', {})
    currdate = datetime.now()
<mask token>
this.normalise()
if args.git:
    idnode = this.find('./identity/special/sil:identity')
    if idnode is not None:
        for k in ('uid', 'revid'):
            if k in idnode.attrib:
                del idnode.attrib[k]
    this = flattenlocale(this, rev='r', dirs=args.dirs, fname=args.this)
if not args.output:
    outfh = sys.stdout
else:
    outfh = codecs.open(args.output, 'w', encoding='utf-8')
this.normalise(usedrafts=True)
this.serialize_xml(outfh.write)
if args.output:
    outfh.close()

<mask token>


def find_ldml(fname, dirs):
    for d in dirs:
        f = os.path.join(d, fname)
        if os.path.exists(f):
            return f
        f = os.path.join(d, fname[0].lower(), fname)
        if os.path.exists(f):
            return f
    return None


parser = ArgumentParser()
parser.add_argument('this', help='File of interest')
parser.add_argument('base', help='Common ancestor, or file to use in git')
parser.add_argument('other', nargs='?', help='Another file of interest')
parser.add_argument('-o', '--output', help='Output file')
parser.add_argument('-w', '--winner', help='Clash win: other, this')
parser.add_argument('-d', '--dirs', action='append', help=
    'Directory to search for ldml files, repeatable')
parser.add_argument('-g', '--git', action='store_true', help=
    'Automatically work out what to do inside a git repo using sil:identity/@revid'
    )
parser.add_argument('-c', '--default', default='proposed', help=
    'Default Change draft level')
parser.add_argument('-C', '--copycomments', help=
    "Assumes this file has comments stripped rather than deleted, and uses either 'base' or 'other' as source of comments"
    )
parser.add_argument('-G', '--nogeneration', action='store_true', help=
    "Don't update the identity/generation element")
parser.add_argument('-v', '--verbose', action='store_true', help='Be verbose')
args = parser.parse_args()
this = LdmlMerge(args.this, winner=args.winner)
if args.dirs:
    this = flattenlocale(this, dirs=args.dirs, rev='f', fname=args.this)
other = None
if args.git:
    idnode = this.find('./identity/special/sil:identity')
    revid = None
    if idnode is not None:
        revid = idnode.get('revid', None)
    if revid is not None:
        fpath = find_ldml(args.base, args.dirs)
        if fpath is None:
            raise SyntaxError('Bad base value: ' + args.base +
                ', or search dirs: ' + args.dirs)
        base_str = check_output(['git', 'show', revid + ':' + fpath])
        basefh = StringIO(base_str)
        base = flattenlocale(basefh, dirs=args.dirs, rev='f', fname=args.base)
        latestid = check_output(['git', 'log', '-n', '1',
            '--pretty=format:%H', revid + '..', fpath])
        if latestid:
            other_str = check_output(['git', 'show', latestid + ':' + fpath])
            otherfh = StringIO(other_str)
            other = flattenlocale(otherfh, dirs=args.dirs, rev='f', fname=
                args.base)
else:
    base = LdmlMerge(args.base)
    if args.other:
        other = LdmlMerge(args.other)
if args.verbose:
    print(f'args={args!r}')
    print(
        f'this.default_draft={this.default_draft!r} base.default_draft={base.default_draft!r} other.default_draft={other.default_draft!r}'
        )
if this.merge(other, base, default=args.default, copycomments=args.copycomments
    ) and not args.nogeneration:
    idnode = this.find('./identity/generation')
    if idnode is None:
        i = this.find('./identity')
        idnode = i.makeelement('generation', {})
    currdate = datetime.now()
sys.stdout = codecs.getwriter('UTF-8')(sys.stdout)
this.normalise()
if args.git:
    idnode = this.find('./identity/special/sil:identity')
    if idnode is not None:
        for k in ('uid', 'revid'):
            if k in idnode.attrib:
                del idnode.attrib[k]
    this = flattenlocale(this, rev='r', dirs=args.dirs, fname=args.this)
if not args.output:
    outfh = sys.stdout
else:
    outfh = codecs.open(args.output, 'w', encoding='utf-8')
this.normalise(usedrafts=True)
this.serialize_xml(outfh.write)
if args.output:
    outfh.close()

import os, sys, codecs
from argparse import ArgumentParser
from subprocess import check_output
from io import StringIO
from xml.etree import ElementTree as et
from datetime import datetime
from sldr.ldml_merge import LdmlMerge, flattenlocale


def find_ldml(fname, dirs):
    for d in dirs:
        f = os.path.join(d, fname)
        if os.path.exists(f):
            return f
        f = os.path.join(d, fname[0].lower(), fname)
        if os.path.exists(f):
            return f
    return None


parser = ArgumentParser()
parser.add_argument('this', help='File of interest')
parser.add_argument('base', help='Common ancestor, or file to use in git')
parser.add_argument('other', nargs='?', help='Another file of interest')
parser.add_argument('-o', '--output', help='Output file')
parser.add_argument('-w', '--winner', help='Clash win: other, this')
parser.add_argument('-d', '--dirs', action='append', help=
    'Directory to search for ldml files, repeatable')
parser.add_argument('-g', '--git', action='store_true', help=
    'Automatically work out what to do inside a git repo using sil:identity/@revid'
    )
parser.add_argument('-c', '--default', default='proposed', help=
    'Default Change draft level')
parser.add_argument('-C', '--copycomments', help=
    "Assumes this file has comments stripped rather than deleted, and uses either 'base' or 'other' as source of comments"
    )
parser.add_argument('-G', '--nogeneration', action='store_true', help=
    "Don't update the identity/generation element")
parser.add_argument('-v', '--verbose', action='store_true', help='Be verbose')
args = parser.parse_args()
this = LdmlMerge(args.this, winner=args.winner)
if args.dirs:
    this = flattenlocale(this, dirs=args.dirs, rev='f', fname=args.this)
other = None
if args.git:
    idnode = this.find('./identity/special/sil:identity')
    revid = None
    if idnode is not None:
        revid = idnode.get('revid', None)
    if revid is not None:
        fpath = find_ldml(args.base, args.dirs)
        if fpath is None:
            raise SyntaxError('Bad base value: ' + args.base +
                ', or search dirs: ' + args.dirs)
        base_str = check_output(['git', 'show', revid + ':' + fpath])
        basefh = StringIO(base_str)
        base = flattenlocale(basefh, dirs=args.dirs, rev='f', fname=args.base)
        latestid = check_output(['git', 'log', '-n', '1',
            '--pretty=format:%H', revid + '..', fpath])
        if latestid:
            other_str = check_output(['git', 'show', latestid + ':' + fpath])
            otherfh = StringIO(other_str)
            other = flattenlocale(otherfh, dirs=args.dirs, rev='f', fname=
                args.base)
else:
    base = LdmlMerge(args.base)
    if args.other:
        other = LdmlMerge(args.other)
if args.verbose:
    print(f'args={args!r}')
    print(
        f'this.default_draft={this.default_draft!r} base.default_draft={base.default_draft!r} other.default_draft={other.default_draft!r}'
        )
if this.merge(other, base, default=args.default, copycomments=args.copycomments
    ) and not args.nogeneration:
    idnode = this.find('./identity/generation')
    if idnode is None:
        i = this.find('./identity')
        idnode = i.makeelement('generation', {})
    currdate = datetime.now()
sys.stdout = codecs.getwriter('UTF-8')(sys.stdout)
this.normalise()
if args.git:
    idnode = this.find('./identity/special/sil:identity')
    if idnode is not None:
        for k in ('uid', 'revid'):
            if k in idnode.attrib:
                del idnode.attrib[k]
    this = flattenlocale(this, rev='r', dirs=args.dirs, fname=args.this)
if not args.output:
    outfh = sys.stdout
else:
    outfh = codecs.open(args.output, 'w', encoding='utf-8')
this.normalise(usedrafts=True)
this.serialize_xml(outfh.write)
if args.output:
    outfh.close()

#!/usr/bin/env python3

# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

import os, sys, codecs
from argparse import ArgumentParser
from subprocess import check_output
from io import StringIO
from xml.etree import ElementTree as et
from datetime import datetime
from sldr.ldml_merge import LdmlMerge, flattenlocale

def find_ldml(fname, dirs) :
    for d in dirs :
        f = os.path.join(d, fname)
        if os.path.exists(f) : return f
        f = os.path.join(d, fname[0].lower(), fname)
        if os.path.exists(f) : return f
    return None

parser = ArgumentParser()
parser.add_argument('this',help='File of interest')
parser.add_argument('base',help="Common ancestor, or file to use in git")
parser.add_argument('other',nargs='?',help='Another file of interest')
parser.add_argument('-o','--output',help="Output file")
parser.add_argument('-w','--winner',help="Clash win: other, this")
parser.add_argument('-d','--dirs',action='append',help='Directory to search for ldml files, repeatable')
parser.add_argument('-g','--git',action='store_true',help='Automatically work out what to do inside a git repo using sil:identity/@revid')
parser.add_argument('-c','--default',default='proposed',help="Default Change draft level")
parser.add_argument('-C','--copycomments',help="Assumes this file has comments stripped rather than deleted, and uses either 'base' or 'other' as source of comments")
parser.add_argument('-G','--nogeneration',action="store_true",help="Don't update the identity/generation element")
parser.add_argument('-v','--verbose',action="store_true",help="Be verbose")
args = parser.parse_args()

this = LdmlMerge(args.this, winner=args.winner)
if args.dirs :
    this = flattenlocale(this, dirs=args.dirs, rev='f', fname=args.this)

other = None
if args.git :
    idnode = this.find("./identity/special/sil:identity")
    revid = None
    if idnode is not None :
        revid = idnode.get('revid', None)
    if revid is not None :
        fpath = find_ldml(args.base, args.dirs)
        if fpath is None : raise SyntaxError("Bad base value: " + args.base + ", or search dirs: " + args.dirs)
        base_str = check_output(["git", "show", revid+":"+fpath])
        basefh = StringIO(base_str)
        base = flattenlocale(basefh, dirs=args.dirs, rev='f', fname=args.base)
        latestid = check_output(["git", "log", "-n", "1", '--pretty=format:%H', revid+"..", fpath])
        if latestid :
            other_str = check_output(["git", "show", latestid+":"+fpath])
            otherfh = StringIO(other_str)
            other = flattenlocale(otherfh, dirs=args.dirs, rev='f', fname=args.base)
else :
    base = LdmlMerge(args.base)
    if args.other :
        other = LdmlMerge(args.other)

if args.verbose:
    print(f"{args=}")
    print(f"{this.default_draft=} {base.default_draft=} {other.default_draft=}")
if this.merge(other, base, default=args.default, copycomments=args.copycomments) and not args.nogeneration :
    # update the date
    idnode = this.find("./identity/generation")
    if idnode is None :
        i = this.find("./identity")
        idnode = i.makeelement("generation", {})
        # idnode = et.SubElement(i, "generation")
    currdate = datetime.now()
    #currdate.microsecond = 0
    #idnode.set("date","$Date: " + currdate.isoformat() + " $")
sys.stdout = codecs.getwriter("UTF-8")(sys.stdout)
this.normalise()

if args.git :
    idnode = this.find("./identity/special/sil:identity")
    if idnode is not None :
        for k in ('uid', 'revid') :
            if k in idnode.attrib : del idnode.attrib[k]
    this = flattenlocale(this, rev='r', dirs=args.dirs, fname=args.this)

if not args.output :
    outfh = sys.stdout
else :
    outfh = codecs.open(args.output, "w", encoding="utf-8")

this.normalise(usedrafts=True)
this.serialize_xml(outfh.write)

if args.output :
    outfh.close()

