Hello community,

here is the log from the commit of package obs-service-tar_scm for 
openSUSE:Factory checked in at 2016-07-12 23:52:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/obs-service-tar_scm (Old)
 and      /work/SRC/openSUSE:Factory/.obs-service-tar_scm.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "obs-service-tar_scm"

Changes:
--------
--- /work/SRC/openSUSE:Factory/obs-service-tar_scm/obs-service-tar_scm.changes  
2016-05-23 16:39:11.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.obs-service-tar_scm.new/obs-service-tar_scm.changes 
    2016-07-12 23:52:06.000000000 +0200
@@ -1,0 +2,47 @@
+Thu Jul  7 11:32:29 UTC 2016 - adr...@suse.de
+
+- update to official version 0.6.0
+  (latest package became official)
+
+-------------------------------------------------------------------
+Thu Jul 07 11:32:21 UTC 2016 - adr...@suse.de
+
+- Update to version 0.6.0.1467889501.49c9462:
+  + very first obs_scm implementation
+  + allow extracting of (spec) files
+  + allow to include local changes when using "obs_scm" service via local osc 
commands.
+  + make obsinfo parameter for tar service optional
+  + support filtering on creation of cpio archives
+  + - add debian provides
+  + - make cleaning message a debug message
+  + report error when specified revision got not found
+  + add snapcraft.yaml support
+  + merge upstream
+  + minor cleanup
+  + fix typo, wrong file name of new snapcraft.yaml
+  + fix some more merge regressions
+  + pep8 fixes/workarounds
+  + make yaml dependency optional for travis
+
+-------------------------------------------------------------------
+Fri Jul 01 08:12:40 UTC 2016 - adr...@suse.de
+
+- added snapcraft support via own service
+
+-------------------------------------------------------------------
+Wed Jun 29 06:06:18 UTC 2016 - adr...@suse.de
+
+- Update to version 0.6.0~pre.1467126663.ec976d1:
+  * Allow to manually specify a base for @TAG_OFFSET@
+  * - make cleaning message a debug message
+  * Honour "subdir" param for changesgenerate
+  * report error when specified revision got not found
+  * Extend fixture to create commits with a specific timestamp
+  * Use commit timestamp as mtime for files and directories in tarball
+  * Workaround bug in Mercurial localdate filter
+  * fix breakage from conflict of #63 and #85
+  * Provide test for git tag fetching
+  * Add ability to generate changes file when using svn
+  * add snapcraft.yaml support
+
+-------------------------------------------------------------------

Old:
----
  obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab.tar.gz

New:
----
  obs-service-tar_scm-0.6.0.1467889501.49c9462.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ obs-service-tar_scm.spec ++++++
--- /var/tmp/diff_new_pack.dBuyoa/_old  2016-07-12 23:52:07.000000000 +0200
+++ /var/tmp/diff_new_pack.dBuyoa/_new  2016-07-12 23:52:07.000000000 +0200
@@ -20,18 +20,18 @@
 %define seperate_build 0
 
 %if "%seperate_build" == "1"
-%define version_unconverted 0.6.0~pre.1461681073.57c0bab
+%define version_unconverted 0.6.0~pre.1467360725.f4aaf50
 
 Name:           obs-service-obs_scm
 %else
-%define version_unconverted 0.6.0~pre.1461681073.57c0bab
+%define version_unconverted 0.6.0~pre.1467360725.f4aaf50
 
 Name:           obs-service-%{service}
 #Obsoletes:      obs-service-obs_scm
 Provides:       obs-service-obs_scm = %version-%release
 %endif
 Provides:       obs-service-tar = %version-%release
-Version:        0.6.0~pre.1461681073.57c0bab
+Version:        0.6.0.1467889501.49c9462
 Release:        0
 Summary:        An OBS source service: checkout or update a tar ball from 
svn/git/hg
 License:        GPL-2.0+
@@ -45,11 +45,16 @@
 BuildRequires:  git-core
 BuildRequires:  mercurial
 BuildRequires:  python >= 2.6
+BuildRequires:  python-dateutil
 BuildRequires:  python-lxml
+BuildRequires:  python-mock
+BuildRequires:  python-yaml
 BuildRequires:  subversion
 Requires:       bzr
 Requires:       git-core
 Requires:       mercurial
+Requires:       python-dateutil
+Requires:       python-yaml
 Requires:       subversion
 %if 0%{?suse_version} < 1315
 Requires:       python-argparse

++++++ _service ++++++
--- /var/tmp/diff_new_pack.dBuyoa/_old  2016-07-12 23:52:07.000000000 +0200
+++ /var/tmp/diff_new_pack.dBuyoa/_new  2016-07-12 23:52:07.000000000 +0200
@@ -1,10 +1,10 @@
 <services>
   <service name="tar_scm" mode="disabled">
-    <param 
name="url">git://github.com/adrianschroeter/obs-service-tar_scm.git</param>
+    <param name="url">git://github.com/openSUSE/obs-service-tar_scm.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
     <param name="version">git-master</param>
-    <param name="versionformat">0.6.0~pre.%ct.%h</param>
+    <param name="versionformat">0.6.0.%ct.%h</param>
     <param name="revision">master</param>
     <param name="changesgenerate">enable</param>
   </service>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.dBuyoa/_old  2016-07-12 23:52:07.000000000 +0200
+++ /var/tmp/diff_new_pack.dBuyoa/_new  2016-07-12 23:52:07.000000000 +0200
@@ -1,4 +1,6 @@
 <servicedata>
 <service name="tar_scm">
             <param 
name="url">git://github.com/adrianschroeter/obs-service-tar_scm.git</param>
-          <param 
name="changesrevision">57c0bab02cbb6090d85f05e2b06ba9b1471176d9</param></service></servicedata>
\ No newline at end of file
+          <param 
name="changesrevision">f4aaf50fd98105daf0405a0d0f7824fbb723e1ac</param></service><service
 name="tar_scm">
+            <param 
name="url">git://github.com/openSUSE/obs-service-tar_scm.git</param>
+          <param 
name="changesrevision">49c9462599650ab6a6d122b9156c732187cf99ea</param></service></servicedata>
\ No newline at end of file

++++++ obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab.tar.gz -> 
obs-service-tar_scm-0.6.0.1467889501.49c9462.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/.travis.yml 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/.travis.yml
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/.travis.yml    
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/.travis.yml        
2016-07-07 13:32:21.000000000 +0200
@@ -5,5 +5,5 @@
 before_install:
   - sudo apt-get update -qq
   - sudo apt-get install -qq bzr git mercurial subversion
-install: pip install pep8 lxml
+install: pip install pep8 lxml mock python-dateutil
 script: make check
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/GNUmakefile 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/GNUmakefile
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/GNUmakefile    
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/GNUmakefile        
2016-07-07 13:32:21.000000000 +0200
@@ -55,7 +55,9 @@
        install -m 0644 tar_scm.rc $(DESTDIR)$(mycfgdir)/tar_scm
        ln -s tar_scm $(DESTDIR)$(mylibdir)/obs_scm
        ln -s tar_scm $(DESTDIR)$(mylibdir)/tar
+       ln -s tar_scm $(DESTDIR)$(mylibdir)/snapcraft
        install -m 0644 tar.service $(DESTDIR)$(mylibdir)/tar.service
+       install -m 0644 snapcraft.service 
$(DESTDIR)$(mylibdir)/snapcraft.service
        sed -e '/^===OBS_ONLY/,/^===/d' -e '/^===/d' tar_scm.service.in > 
$(DESTDIR)$(mylibdir)/tar_scm.service
        sed -e '/^===TAR_ONLY/,/^===/d' -e '/^===/d' tar_scm.service.in > 
$(DESTDIR)$(mylibdir)/obs_scm.service
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/debian/control 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/debian/control
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/debian/control 
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/debian/control     
2016-07-07 13:32:21.000000000 +0200
@@ -2,7 +2,7 @@
 Section: devel
 Priority: extra
 Maintainer: Daniel Gollub <dgol...@brocade.com>
-Build-Depends: debhelper (>= 8.0.0), bzr, git, mercurial, pep8, python (>= 
2.6), python-argparse | python (>= 2.7), python-unittest2, subversion
+Build-Depends: debhelper (>= 8.0.0), bzr, git, mercurial, pep8, python (>= 
2.6), python-argparse | python (>= 2.7), python-dateutil, python-unittest2, 
subversion
 Standards-Version: 3.9.3
 Homepage: https://github.com/openSUSE/obs-service-tar_scm
 X-Python-Version: >= 2.6
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/snapcraft 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/snapcraft
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/snapcraft      
1970-01-01 01:00:00.000000000 +0100
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/snapcraft  2016-07-12 
23:52:07.000000000 +0200
@@ -0,0 +1 @@
+symbolic link to tar_scm.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/snapcraft.service 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/snapcraft.service
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/snapcraft.service      
1970-01-01 01:00:00.000000000 +0100
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/snapcraft.service  
2016-07-07 13:32:21.000000000 +0200
@@ -0,0 +1,4 @@
+<service name="snapcraft">
+<summary>handle sources specified in snapcraft.yaml</summary>
+   <description>This service needs to be executed to download sources 
according to snapcraft.yaml file. It also patches the snapcraft tile to use 
local sources during build.</description>
+</service>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tar_scm.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tar_scm.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tar_scm.py     
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tar_scm.py 2016-07-07 
13:32:21.000000000 +0200
@@ -28,6 +28,14 @@
 import sys
 import tarfile
 import tempfile
+import dateutil.parser
+
+try:
+    # not possible to test this on travis atm
+    import yaml
+except ImportError:
+    pass
+
 from urlparse import urlparse
 
 DEFAULT_AUTHOR = 'opensuse-packag...@opensuse.org'
@@ -212,9 +220,11 @@
     if revision is None:
         revision = 'master'
 
+    found_revision = None
     revs = [x + revision for x in ['origin/', '']]
     for rev in revs:
         if git_ref_exists(clone_dir, rev):
+            found_revision = True
             if os.getenv('OSC_VERSION'):
                 stash_text = safe_run(['git', 'stash'], cwd=clone_dir)[1]
                 text = safe_run(['git', 'reset', '--hard', rev],
@@ -227,7 +237,8 @@
                                 cwd=clone_dir)[1]
             print text.rstrip()
             break
-    else:
+
+    if found_revision is None:
         sys.exit('%s: No such revision' % revision)
 
     # only update submodules if they have been enabled
@@ -262,7 +273,7 @@
 }
 
 
-def _calc_dir_to_clone_to(scm, url, out_dir):
+def _calc_dir_to_clone_to(scm, url, prefix, out_dir):
     # separate path from parameters etc.
     url_path = urlparse(url)[2].rstrip('/')
 
@@ -273,13 +284,17 @@
     url_path = url_path.rstrip('/')
 
     basename = os.path.basename(os.path.normpath(url_path))
+    basename = prefix + basename
     clone_dir = os.path.abspath(os.path.join(out_dir, basename))
     return clone_dir
 
 
 def fetch_upstream(scm, url, revision, out_dir, **kwargs):
     """Fetch sources from repository and checkout given revision."""
-    clone_dir = _calc_dir_to_clone_to(scm, url, out_dir)
+    clone_prefix = ""
+    if 'clone_prefix' in kwargs:
+        clone_prefix = kwargs['clone_prefix']
+    clone_dir = _calc_dir_to_clone_to(scm, url, clone_prefix, out_dir)
 
     if not os.path.isdir(clone_dir):
         # initial clone
@@ -347,7 +362,6 @@
     """
     (workdir, topdir) = os.path.split(repodir)
     extension = 'obscpio'
-    excludes = args.exclude
 
     cwd = os.getcwd()
     os.chdir(workdir)
@@ -361,7 +375,7 @@
 
     # transform glob patterns to regular expressions
     includes = r'|'.join([fnmatch.translate(x) for x in args.include])
-    excludes = r'|'.join([fnmatch.translate(x) for x in excludes]) or r'$.'
+    excludes = r'|'.join([fnmatch.translate(x) for x in args.exclude]) or r'$.'
 
     # add topdir without filtering for now
     for root, dirs, files in os.walk(topdir, topdown=False):
@@ -386,7 +400,7 @@
     ret_code = proc.wait()
     if ret_code != 0:
         sys.exit("creating the cpio archive failed!")
-    archivefile.flush()
+    archivefile.close()
 
     # write meta data
     metafile = open(os.path.join(args.outdir, basename + '.obsinfo'), "w")
@@ -395,13 +409,13 @@
     # metafile.write("git describe: " + + "\n")
     if commit:
         metafile.write("commit: " + commit + "\n")
-    metafile.flush()
+    metafile.close()
 
     os.chdir(cwd)
 
 
 def create_tar(repodir, outdir, dstname, extension='tar',
-               exclude=[], include=[], package_metadata=False):
+               exclude=[], include=[], package_metadata=False, timestamp=0):
     """Create a tarball of repodir in destination directory."""
     (workdir, topdir) = os.path.split(repodir)
 
@@ -439,6 +453,7 @@
         """Python 2.7 only: reset uid/gid to 0/0 (root)."""
         tarinfo.uid = tarinfo.gid = 0
         tarinfo.uname = tarinfo.gname = "root"
+        tarinfo.mtime = timestamp
         return tarinfo
 
     def tar_filter(tarinfo):
@@ -472,7 +487,7 @@
 
 def cleanup(dirs):
     """Cleaning temporary directories."""
-    logging.info("Cleaning: %s", ' '.join(dirs))
+    logging.debug("Cleaning: %s", ' '.join(dirs))
 
     for d in dirs:
         if not os.path.exists(d):
@@ -513,22 +528,24 @@
 
 def detect_version_tar(args, repodir):
     """Read former stored version."""
-    return read_from_obsinfo(args.obsinfo, "version")
+    return read_from_obsinfo(args['obsinfo'], "version")
 
 
 def detect_version_git(args, repodir):
     """Automatic detection of version number for checked-out GIT repository."""
-    versionformat = args.versionformat
+    parent_tag = args['parent_tag']
+    versionformat = args['versionformat']
     if versionformat is None:
         versionformat = '%ct.%h'
 
-    parent_tag = None
-    if re.match('.*@PARENT_TAG@.*', versionformat):
+    if not parent_tag:
         rc, output = run_cmd(['git', 'describe', '--tags', '--abbrev=0'],
                              repodir)
-        if not rc:
+        if rc == 0:
             # strip to remove newlines
             parent_tag = output.strip()
+    if re.match('.*@PARENT_TAG@.*', versionformat):
+        if parent_tag:
             versionformat = re.sub('@PARENT_TAG@', parent_tag, versionformat)
         else:
             sys.exit("\033[31mNo parent tag present for the checked out "
@@ -543,10 +560,11 @@
                 versionformat = re.sub('@TAG_OFFSET@', tag_offset,
                                        versionformat)
             else:
-                sys.exit(r'@TAG_OFFSET@ can not be expanded')
+                sys.exit("\033[31m@TAG_OFFSET@ can not be expanded: " +
+                         output + "\033[0m")
         else:
             sys.exit("\033[31m@TAG_OFFSET@ cannot be expanded, "
-                     "@PARENT_TAG@ is required.\033[0m")
+                     "as no parent tag was discovered.\033[0m")
 
     version = safe_run(['git', 'log', '-n1', '--date=short',
                         "--pretty=format:%s" % versionformat], repodir)[1]
@@ -555,7 +573,7 @@
 
 def detect_version_svn(args, repodir):
     """Automatic detection of version number for checked-out SVN repository."""
-    versionformat = args.versionformat
+    versionformat = args['versionformat']
     if versionformat is None:
         versionformat = '%r'
 
@@ -570,7 +588,8 @@
 
 def detect_version_hg(args, repodir):
     """Automatic detection of version number for checked-out HG repository."""
-    versionformat = args.versionformat
+    parent_tag = args['parent_tag']
+    versionformat = args['versionformat']
     if versionformat is None:
         versionformat = '{rev}'
 
@@ -609,7 +628,7 @@
 
 def detect_version_bzr(args, repodir):
     """Automatic detection of version number for checked-out BZR repository."""
-    versionformat = args.versionformat
+    versionformat = args['versionformat']
     if versionformat is None:
         versionformat = '%r'
 
@@ -624,14 +643,71 @@
         'svn': detect_version_svn,
         'hg':  detect_version_hg,
         'bzr': detect_version_bzr,
-        'tar': detect_version_tar,
+        'tar': detect_version_tar
     }
 
-    version = detect_version_commands[args.scm](args, repodir).strip()
+    version = detect_version_commands[args.scm](args.__dict__, repodir).strip()
     logging.debug("VERSION(auto): %s", version)
     return version
 
 
+def get_timestamp_tar(repodir):
+    return int(0)
+
+
+def get_timestamp_bzr(repodir):
+    log = safe_run(['bzr', 'log', '--limit=1', '--log-format=long'],
+                   repodir)[1]
+    match = re.search(r'timestamp:(.*)', log, re.MULTILINE)
+    if not match:
+        return 0
+    timestamp = dateutil.parser.parse(match.group(1).strip()).strftime("%s")
+    return int(timestamp)
+
+
+def get_timestamp_git(repodir):
+    d = {"parent_tag": None, "versionformat": "%ct"}
+    timestamp = detect_version_git(d, repodir)
+    return int(timestamp)
+
+
+def get_timestamp_hg(repodir):
+    d = {"parent_tag": None, "versionformat": "{date}"}
+    timestamp = detect_version_hg(d, repodir)
+    timestamp = re.sub(r'([0-9]+)\..*', r'\1', timestamp)
+    return int(timestamp)
+
+
+def get_timestamp_svn(repodir):
+    svn_info = safe_run(['svn', 'info', '-rHEAD'], repodir)[1]
+
+    match = re.search('Last Changed Date: (.*)', svn_info, re.MULTILINE)
+    if not match:
+        return 0
+
+    timestamp = match.group(1).strip()
+    timestamp = re.sub('\(.*\)', '', timestamp)
+    timestamp = dateutil.parser.parse(timestamp).strftime("%s")
+    return int(timestamp)
+
+
+def get_timestamp(args, clone_dir):
+    """Returns the commit timestamp for checked-out repository."""
+    get_timestamp_commands = {
+        'git': get_timestamp_git,
+        'svn': get_timestamp_svn,
+        'hg':  get_timestamp_hg,
+        'bzr': get_timestamp_bzr,
+        'tar': get_timestamp_tar
+    }
+
+    timestamp = get_timestamp_commands[args.scm](clone_dir)
+    logging.debug("COMMIT TIMESTAMP: %s (%s)", timestamp,
+                  datetime.datetime.fromtimestamp(timestamp).strftime(
+                      '%Y-%m-%d %H:%M:%S'))
+    return timestamp
+
+
 def get_repocache_hash(scm, url, subdir):
     """Calculate hash fingerprint for repository cache."""
     digest = hashlib.new('sha256')
@@ -834,33 +910,98 @@
     shutil.move(tmp_fp.name, changes_filename)
 
 
-def detect_changes_commands_git(repodir, changes):
+def _git_log_cmd(cmd_args, repodir, subdir):
+    """ Helper function to call 'git log' with args"""
+    cmd = ['git', 'log'] + cmd_args
+    if subdir:
+        cmd += ['--', subdir]
+    return safe_run(cmd, cwd=repodir)[1]
+
+
+def detect_changes_commands_git(repodir, subdir, changes):
     """Detect changes between GIT revisions."""
     last_rev = changes['revision']
 
     if last_rev is None:
-        last_rev = safe_run(['git', 'log', '-n1', '--pretty=format:%H',
-                             '--skip=10'], cwd=repodir)[1]
-    current_rev = safe_run(['git', 'log', '-n1', '--pretty=format:%H'],
-                           cwd=repodir)[1]
+        last_rev = _git_log_cmd(['-n1', '--pretty=format:%H', '--skip=10'],
+                                repodir, subdir)
+    current_rev = _git_log_cmd(['-n1', '--pretty=format:%H'], repodir, subdir)
 
     if last_rev == current_rev:
         logging.debug("No new commits, skipping changes file generation")
         return
 
-    logging.debug("Generating changes between %s and %s", last_rev,
-                  current_rev)
+    dbg_msg = "Generating changes between %s and %s" % (last_rev, current_rev)
+    if subdir:
+        dbg_msg += " (for subdir: %s)" % (subdir)
+    logging.debug(dbg_msg)
 
-    lines = safe_run(['git', 'log',
-                      '--reverse', '--no-merges', '--pretty=format:%s',
-                      "%s..%s" % (last_rev, current_rev)], repodir)[1]
+    lines = _git_log_cmd(['--reverse', '--no-merges', '--pretty=format:%s',
+                          "%s..%s" % (last_rev, current_rev)], repodir, subdir)
 
     changes['revision'] = current_rev
     changes['lines'] = lines.split('\n')
     return changes
 
 
-def detect_changes(scm, url, repodir, outdir):
+def detect_changes_commands_svn(repodir, subdir, changes):
+    """Detect changes between GIT revisions."""
+    last_rev = changes['revision']
+    first_run = False
+    if subdir:
+        repodir = os.path.join(repodir, subdir)
+
+    if last_rev is None:
+        last_rev = get_svn_rev(repodir, 10)
+        logging.debug("First run get log for initial release")
+        first_run = True
+
+    current_rev = get_svn_rev(repodir, 1)
+
+    if last_rev == current_rev:
+        logging.debug("No new commits, skipping changes file generation")
+        return
+
+    if not first_run:
+        # Increase last_rev by 1 so we dont get duplication of log messages
+        last_rev = int(last_rev) + 1
+
+    logging.debug("Generating changes between %s and %s", last_rev,
+                  current_rev)
+    lines = get_svn_log(repodir, last_rev, current_rev)
+
+    changes['revision'] = current_rev
+    changes['lines'] = lines
+    return changes
+
+
+def get_svn_log(repodir, revision1, revision2):
+    new_lines = []
+
+    xml_lines = safe_run(['svn', 'log', '-r%s:%s' % (revision1,
+                         revision2), '--xml'], repodir)[1]
+    lines = re.findall(r"<msg>.*?</msg>", xml_lines, re.S)
+
+    for line in lines:
+        line = line.replace("<msg>", "").replace("</msg>", "")
+        new_lines = new_lines + line.split("\n")
+
+    return new_lines
+
+
+def get_svn_rev(repodir, num_commits):
+    revisions = safe_run(['svn', 'log', '-l%d' % num_commits, '-q',
+                         '--incremental'], cwd=repodir)[1].split('\n')
+    # remove blank entry on end
+    revisions.pop()
+    # return last entry
+    revision = revisions[-1]
+    # retrieve the revision number and remove r
+    revision = re.search(r'^r[0-9]*', revision, re.M).group().replace("r", "")
+    return revision
+
+
+def detect_changes(scm, url, repodir, outdir, subdir):
     """Detect changes between revisions."""
     changes = read_changes_revision(url, os.getcwd(), outdir)
 
@@ -868,12 +1009,13 @@
 
     detect_changes_commands = {
         'git': detect_changes_commands_git,
+        'svn': detect_changes_commands_svn,
     }
 
     if scm not in detect_changes_commands:
         sys.exit("changesgenerate not supported with %s SCM" % scm)
 
-    changes = detect_changes_commands[scm](repodir, changes)
+    changes = detect_changes_commands[scm](repodir, subdir, changes)
     logging.debug("Detected changes:\n%s" % repr(changes))
     return changes
 
@@ -948,6 +1090,8 @@
                              'specified.')
     parser.add_argument('--versionprefix',
                         help='Specify a base version as prefix.')
+    parser.add_argument('--parent-tag',
+                        help='Override base commit for @TAG_OFFSET@')
     parser.add_argument('--revision',
                         help='Specify revision to package')
     parser.add_argument('--extract', action='append',
@@ -1063,6 +1207,43 @@
     if sys.argv[0].endswith("tar"):
         args.scm = "tar"
 
+    use_obs_scm = None
+    if sys.argv[0].endswith("obs_scm"):
+        use_obs_scm = True
+
+    if sys.argv[0].endswith("snapcraft"):
+        # we read the SCM config from snapcraft.yaml instead from _service file
+        f = open('snapcraft.yaml')
+        dataMap = yaml.safe_load(f)
+        f.close()
+        # run for each part an own task
+        for part in dataMap['parts'].keys():
+            args.filename = part
+            if 'source-type' not in dataMap['parts'][part].keys():
+                continue
+            pep8_1 = dataMap['parts'][part]['source-type']
+            pep8_2 = FETCH_UPSTREAM_COMMANDS.keys()
+            if pep8_1 not in pep8_2:
+                continue
+            # avoid conflicts with files
+            args.clone_prefix = "_obs_"
+            args.url = dataMap['parts'][part]['source']
+            dataMap['parts'][part]['source'] = part
+            args.scm = dataMap['parts'][part]['source-type']
+            del dataMap['parts'][part]['source-type']
+            singletask(True, args)
+
+        # write the new snapcraft.yaml file
+        # we prefix our own here to be sure to not overwrite user files, if he
+        # is using us in "disabled" mode
+        new_file = args.outdir + '/_service:snapcraft:snapcraft.yaml'
+        with open(new_file, 'w') as outfile:
+            outfile.write(yaml.dump(dataMap, default_flow_style=False))
+    else:
+        singletask(use_obs_scm, args)
+
+
+def singletask(use_obs_scm, args):
     FORMAT = "%(message)s"
     logging.basicConfig(format=FORMAT, stream=sys.stderr, level=logging.INFO)
     if args.verbose:
@@ -1073,8 +1254,8 @@
 
     repocachedir = get_repocachedir()
 
-    # construct repodir (the parent directory of the checkout)
     repodir = None
+    # construct repodir (the parent directory of the checkout)
     if repocachedir and os.path.isdir(os.path.join(repocachedir, 'repo')):
         repohash = get_repocache_hash(args.scm, args.url, args.subdir)
         logging.debug("HASH: %s", repohash)
@@ -1092,7 +1273,8 @@
     # special case when using osc and creating an obscpio, use current work
     # directory to allow the developer to work inside of the git repo and fetch
     # local changes
-    if sys.argv[0].endswith("obs_scm") and os.getenv('OSC_VERSION'):
+    if sys.argv[0].endswith("snapcraft") or \
+       (use_obs_scm and os.getenv('OSC_VERSION')):
         repodir = os.getcwd()
 
     if args.scm == "tar":
@@ -1118,14 +1300,16 @@
 
     version = get_version(args, clone_dir)
     changesversion = version
-    if version and not sys.argv[0].endswith("/tar"):
+    if version and not sys.argv[0].endswith("/tar") \
+       and not sys.argv[0].endswith("/snapcraft"):
         dstname += '-' + version
 
     logging.debug("DST: %s", dstname)
 
     changes = None
     if args.changesgenerate:
-        changes = detect_changes(args.scm, args.url, clone_dir, args.outdir)
+        changes = detect_changes(args.scm, args.url, clone_dir, args.outdir,
+                                 args.subdir)
 
     tar_dir = prep_tree_for_archive(clone_dir, args.subdir, args.outdir,
                                     dstname=dstname)
@@ -1133,7 +1317,7 @@
 
     extract_from_archive(tar_dir, args.extract, args.outdir)
 
-    if sys.argv[0].endswith("obs_scm"):
+    if use_obs_scm:
         commit = None
         if args.scm == "git":
             commit = safe_run(['git', 'rev-parse', 'HEAD'], clone_dir)[1]
@@ -1142,7 +1326,8 @@
         create_tar(tar_dir, args.outdir,
                    dstname=dstname, extension=args.extension,
                    exclude=args.exclude, include=args.include,
-                   package_metadata=args.package_meta)
+                   package_metadata=args.package_meta,
+                   timestamp=get_timestamp(args, clone_dir))
 
     if changes:
         changesauthor = get_changesauthor(args)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tar_scm.service.in 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tar_scm.service.in
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tar_scm.service.in     
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tar_scm.service.in 
2016-07-07 13:32:21.000000000 +0200
@@ -64,6 +64,12 @@
   <parameter name="versionprefix">
     <description>Specify a base version as prefix.</description>
   </parameter>
+  <parameter name="parent-tag">
+    <description>
+      This parameter allows overriding the tag that is being used for
+      computing @TAG_OFFSET@.
+    </description>
+  </parameter>
   <parameter name="revision">
     <description>
        Specify revision of source to check out.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/bzrfixtures.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/bzrfixtures.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/bzrfixtures.py   
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/bzrfixtures.py       
2016-07-07 13:32:21.000000000 +0200
@@ -30,3 +30,8 @@
     def record_rev(self, wd, rev_num):
         self.revs[rev_num] = str(rev_num)
         self.scmlogs.annotate("Recorded rev %d" % rev_num)
+
+    def get_committer_date(self):
+        '''There seems to be no way to create a commit with a given timestamp
+        set for Bazar.'''
+        return ''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/bzrtests.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/bzrtests.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/bzrtests.py      
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/bzrtests.py  
2016-07-07 13:32:21.000000000 +0200
@@ -36,3 +36,8 @@
         basename = self.basename(version='foo2')
         th = self.assertTarOnly(basename)
         self.assertTarMemberContains(th, basename + '/a', '2')
+
+    def assertDirentsMtime(self, entries):
+        '''Skip this test with bazaar because there seem to be no way to create
+        commits with a given timestamp.'''
+        return True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/fixtures.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/fixtures.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/fixtures.py      
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/fixtures.py  
2016-07-07 13:32:21.000000000 +0200
@@ -17,6 +17,9 @@
     subdir2 = 'subdir2'
     _next_commit_revs = {}
 
+    # the timestamp (in seconds since epoch ) that should be used for commits
+    COMMITTER_DATE = int(1234567890)
+
     def __init__(self, container_dir, scmlogs):
         self.container_dir = container_dir
         self.scmlogs       = scmlogs
@@ -46,7 +49,7 @@
         raise NotImplementedError(
             self.__class__.__name__ + " didn't implement init()")
 
-    def create_commits(self, num_commits, wd=None):
+    def create_commits(self, num_commits, wd=None, subdir=None):
         self.scmlogs.annotate("Creating %d commits ..." % num_commits)
         if num_commits == 0:
             return
@@ -57,7 +60,7 @@
         os.chdir(wd)
 
         for i in xrange(0, num_commits):
-            new_rev = self.create_commit(wd)
+            new_rev = self.create_commit(wd, subdir=subdir)
         self.record_rev(wd, new_rev)
 
         self.scmlogs.annotate("Created %d commits; now at %s" %
@@ -71,33 +74,39 @@
         self._next_commit_revs[wd] += 1
         return new_rev
 
-    def create_commit(self, wd):
+    def create_commit(self, wd, subdir=None):
         new_rev = self.next_commit_rev(wd)
-        newly_created = self.prep_commit(new_rev)
+        newly_created = self.prep_commit(new_rev, subdir=subdir)
         self.do_commit(wd, new_rev, newly_created)
         return new_rev
 
     def do_commit(self, wd, new_rev, newly_created):
         self.safe_run('add .')
-        self.safe_run('commit -m%d' % new_rev)
+        date = self.get_committer_date()
+        self.safe_run('commit -m%d %s' % (new_rev, date))
+
+    def get_committer_date(self):
+        return '--date="%s"' % str(self.COMMITTER_DATE)
 
-    def prep_commit(self, new_rev):
+    def prep_commit(self, new_rev, subdir=None):
         """
         Caller should ensure correct cwd.
         Returns list of newly created files.
         """
+        if not subdir:
+            subdir = self.subdir
         self.scmlogs.annotate("cwd is %s" % os.getcwd())
         newly_created = []
 
         if not os.path.exists('a'):
             newly_created.append('a')
 
-        if not os.path.exists(self.subdir):
-            os.mkdir(self.subdir)
+        if not os.path.exists(subdir):
+            os.mkdir(subdir)
             # This will take care of adding subdir/b too
-            newly_created.append(self.subdir)
+            newly_created.append(subdir)
 
-        for fn in ('a', self.subdir + '/b'):
+        for fn in ('a', subdir + '/b'):
             f = open(fn, 'w')
             f.write(str(new_rev))
             f.close()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/gitfixtures.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/gitfixtures.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/gitfixtures.py   
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/gitfixtures.py       
2016-07-07 13:32:21.000000000 +0200
@@ -26,6 +26,9 @@
         self.timestamps = {}
         self.sha1s      = {}
 
+        # Force the committer timestamp to our well known default
+        os.environ["GIT_COMMITTER_DATE"] = self.get_committer_date()
+
         self.create_commits(2)
 
     def run(self, cmd):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/gitsvntests.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/gitsvntests.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/gitsvntests.py   
1970-01-01 01:00:00.000000000 +0100
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/gitsvntests.py       
2016-07-07 13:32:21.000000000 +0200
@@ -0,0 +1,209 @@
+#!/usr/bin/env python2
+
+import os
+import textwrap
+import re
+
+from commontests import CommonTests
+from utils       import run_git, run_svn
+
+
+class GitSvnTests(CommonTests):
+
+    """Unit tests which are shared between git and svn."""
+
+    def test_changesgenerate_disabled(self):
+        self.tar_scm_std('--changesgenerate', 'disable')
+
+    def test_changesgenerate_no_servicedata(self):
+        self.tar_scm_std('--changesgenerate', 'enable')
+        self._check_servicedata()
+
+    def test_changesgenerate_corrupt_servicedata(self):
+        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
+            sd.write('this is not valid xml')
+        self.tar_scm_std('--changesgenerate', 'enable', should_succeed=False)
+
+    def test_changesgenerate_empty_servicedata_file(self):
+        sd = open(os.path.join(self.pkgdir, '_servicedata'), 'w')
+        sd.close()
+        self.tar_scm_std('--changesgenerate', 'enable')
+        self._check_servicedata()
+
+    def test_changesgenerate_empty_servicedata_element(self):
+        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
+            sd.write("<servicedata>\n</servicedata>\n")
+        self.tar_scm_std('--changesgenerate', 'enable')
+        self._check_servicedata()
+
+    def test_changesgenerate_no_changesrevision(self):
+        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
+            sd.write(textwrap.dedent("""\
+              <servicedata>
+                <service name="tar_scm">
+                  <param name="url">%s</param>
+                </service>
+              </servicedata>
+            """ % self.fixtures.repo_url))
+        self.tar_scm_std('--changesgenerate', 'enable')
+        self._check_servicedata()
+
+    def _write_changes_file(self):
+        contents = textwrap.dedent("""\
+          -------------------------------------------------------------------
+          Fri Oct  3 00:17:50 BST 2014 - %s
+
+          - 2
+
+          -------------------------------------------------------------------
+          Thu Sep 18 10:27:14 BST 2014 - %s
+
+          - 1
+        """ % (self.fixtures.user_email, self.fixtures.user_email))
+        with open(os.path.join(self.pkgdir, 'pkg.changes'), 'w') as f:
+            f.write(contents)
+        return contents
+
+    def test_changesgenerate_no_change_or_changes_file(self):
+        self._write_servicedata(2)
+        self.tar_scm_std('--changesgenerate', 'enable')
+        self._check_servicedata()
+
+    def test_changesgenerate_no_change_same_changes_file(self):
+        self._write_servicedata(2)
+        orig_changes = self._write_changes_file()
+        self.tar_scm_std('--changesgenerate', 'enable')
+        self._check_servicedata()
+
+    def test_changesgenerate_new_commit_no_changes_file(self):
+        self._write_servicedata(2)
+        self.fixtures.create_commits(1)
+        self.tar_scm_std('--changesgenerate', 'enable')
+        self._check_servicedata(revision=3)
+
+    def _new_change_entry_regexp(self, author, changes):
+        return textwrap.dedent("""\
+          ^-------------------------------------------------------------------
+          \w{3} \w{3} [ \d]\d \d\d:\d\d:\d\d [A-Z]{3} 20\d\d - %s
+
+          %s
+          """) % (author, changes)
+
+    def _check_changes(self, orig_changes, expected_changes_regexp):
+        new_changes_file = os.path.join(self.outdir, 'pkg.changes')
+        self.assertTrue(os.path.exists(new_changes_file))
+        with open(new_changes_file) as f:
+            new_changes = f.read()
+            self.assertNotEqual(orig_changes, new_changes)
+            print new_changes
+            expected_changes_regexp += "(.*)"
+            self.assertRegexpMatches(new_changes, expected_changes_regexp)
+            m = re.match(expected_changes_regexp, new_changes, re.DOTALL)
+            self.assertEqual(m.group(1), orig_changes)
+
+    def test_changesgenerate_new_commit_and_changes_file(self):
+        self._test_changesgenerate_new_commit_and_changes_file(
+            self.fixtures.user_email)
+
+    def test_changesgenerate_new_commit_and_changes_file_default_author(self):
+        self._test_changesgenerate_new_commit_and_changes_file()
+
+    def _write_servicedata(self, rev):
+        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
+            sd.write(textwrap.dedent("""\
+              <servicedata>
+                <service name="tar_scm">
+                  <param name="url">%s</param>
+                  <param name="changesrevision">%s</param>
+                </service>
+              </servicedata>
+            """ % (self.fixtures.repo_url, self.changesrevision(rev))))
+
+    def _test_changesgenerate_new_commit_and_changes_file(self, author=None):
+        self._write_servicedata(2)
+        orig_changes = self._write_changes_file()
+        self.fixtures.create_commits(3)
+        rev = 5
+
+        tar_scm_args = self.tar_scm_args()
+
+        if author is not None:
+            tar_scm_args += ['--changesauthor', self.fixtures.user_email]
+
+        self.tar_scm_std(*tar_scm_args)
+
+        self._check_servicedata(revision=rev, expected_dirents=3)
+
+        rev = self.changesrevision(rev, abbrev=True)
+
+        expected_author = author or 'opensuse-packag...@opensuse.org'
+        expected_changes_regexp = self._new_change_entry_regexp(
+            expected_author,
+            textwrap.dedent("""\
+              - Update to version 0.6.%s:
+                \* 3
+                \* 4
+                \* 5
+              """) % rev
+        )
+        self._check_changes(orig_changes, expected_changes_regexp)
+
+    def test_changesgenerate_new_commit_and_changes_file_no_version(self):
+        self._write_servicedata(2)
+        orig_changes = self._write_changes_file()
+        self.fixtures.create_commits(3)
+        rev = 5
+
+        tar_scm_args = [
+            '--changesgenerate', 'enable',
+            '--version', '',
+            '--changesauthor', self.fixtures.user_email
+        ]
+        self.tar_scm_std(*tar_scm_args)
+
+        self._check_servicedata(revision=rev, expected_dirents=3)
+
+        rev = self.changesrevision(rev, abbrev=True)
+        ver_regex = self.changesregex(rev)
+
+        expected_author = self.fixtures.user_email
+        expected_changes_regexp = self._new_change_entry_regexp(
+            expected_author,
+            textwrap.dedent("""\
+              - Update to version %s:
+                \* 3
+                \* 4
+                \* 5
+              """) % ver_regex
+        )
+        self._check_changes(orig_changes, expected_changes_regexp)
+
+    def test_changesgenerate_new_commit_and_changes_file_with_subdir(self):
+        self._write_servicedata(2)
+        orig_changes = self._write_changes_file()
+        self.fixtures.create_commits(3)
+        self.fixtures.create_commits(3, subdir='another_subdir')
+        rev = 8
+
+        tar_scm_args = self.tar_scm_args()
+
+        tar_scm_args += [
+            '--subdir', 'another_subdir',
+            '--changesauthor', self.fixtures.user_email,
+        ]
+
+        self.tar_scm_std(*tar_scm_args)
+
+        self._check_servicedata(revision=rev, expected_dirents=3)
+
+        expected_author = self.fixtures.user_email
+        expected_changes_regexp = self._new_change_entry_regexp(
+            expected_author,
+            textwrap.dedent("""\
+              - Update to version 0.6.%s:
+                \* 6
+                \* 7
+                \* 8
+              """) % self.changesrevision(rev, abbrev=True)
+        )
+        self._check_changes(orig_changes, expected_changes_regexp)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/gittests.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/gittests.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/gittests.py      
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/gittests.py  
2016-07-07 13:32:21.000000000 +0200
@@ -7,11 +7,12 @@
 import textwrap
 
 from githgtests  import GitHgTests
+from gitsvntests import GitSvnTests
 from gitfixtures import GitFixtures
 from utils       import run_git
 
 
-class GitTests(GitHgTests):
+class GitTests(GitHgTests, GitSvnTests):
 
     """Unit tests for 'tar_scm --scm git'.
 
@@ -64,8 +65,32 @@
     def abbrev_sha1s(self, rev):
         return self.sha1s(rev)[0:7]
 
+    def changesrevision(self, rev, abbrev=False):
+        if abbrev:
+            return self.abbrev_sha1s('tag%d' % rev)
+        return self.sha1s('tag%d' % rev)
+
+    def changesregex(self, rev):
+        return '\d{10}.%s' % rev
+
+    def tar_scm_args(self):
+        scm_args = [
+            '--changesgenerate', 'enable',
+            '--versionformat', '0.6.%h',
+        ]
+        return scm_args
+
     # N.B. --versionformat gets tested thoroughly in githgtests.py
 
+    def test_parent_tag(self):
+        f = self.fixtures
+        f.create_commits(1)
+        base = f.get_metadata("%H")
+        f.create_commits(3)
+        self.tar_scm_std("--parent-tag", base,
+                         "--versionformat", "@TAG_OFFSET@")
+        self.assertTarOnly(self.basename(version="3"))
+
     def test_versionformat_parenttag(self):
         # the .1 to catch newlines at the end of PARENT_TAG
         self.tar_scm_std('--versionformat', "@PARENT_TAG@.1")
@@ -171,163 +196,16 @@
         sha1 = m.group(1)
         self.assertEqual(sha1, expected_sha1)
 
-    def test_changesgenerate_disabled(self):
-        self.tar_scm_std('--changesgenerate', 'disable')
-
-    def test_changesgenerate_no_servicedata(self):
-        self.tar_scm_std('--changesgenerate', 'enable')
-        self._check_servicedata()
-
-    def test_changesgenerate_corrupt_servicedata(self):
-        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
-            sd.write('this is not valid xml')
-        self.tar_scm_std('--changesgenerate', 'enable', should_succeed=False)
-
-    def test_changesgenerate_empty_servicedata_file(self):
-        sd = open(os.path.join(self.pkgdir, '_servicedata'), 'w')
-        sd.close()
-        self.tar_scm_std('--changesgenerate', 'enable')
-        self._check_servicedata()
-
-    def test_changesgenerate_empty_servicedata_element(self):
-        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
-            sd.write("<servicedata>\n</servicedata>\n")
-        self.tar_scm_std('--changesgenerate', 'enable')
-        self._check_servicedata()
-
-    def test_changesgenerate_no_changesrevision(self):
-        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
-            sd.write(textwrap.dedent("""\
-              <servicedata>
-                <service name="tar_scm">
-                  <param name="url">%s</param>
-                </service>
-              </servicedata>
-            """ % self.fixtures.repo_url))
-        self.tar_scm_std('--changesgenerate', 'enable')
-        self._check_servicedata()
-
-    def _write_servicedata(self, rev):
-        sha1 = self.sha1s('tag%d' % rev)
-        with open(os.path.join(self.pkgdir, '_servicedata'), 'w') as sd:
-            sd.write(textwrap.dedent("""\
-              <servicedata>
-                <service name="tar_scm">
-                  <param name="url">%s</param>
-                  <param name="changesrevision">%s</param>
-                </service>
-              </servicedata>
-            """ % (self.fixtures.repo_url, sha1)))
-
-    def _write_changes_file(self):
-        contents = textwrap.dedent("""\
-          -------------------------------------------------------------------
-          Fri Oct  3 00:17:50 BST 2014 - %s
-
-          - 2
-
-          -------------------------------------------------------------------
-          Thu Sep 18 10:27:14 BST 2014 - %s
-
-          - 1
-        """ % (self.fixtures.user_email, self.fixtures.user_email))
-        with open(os.path.join(self.pkgdir, 'pkg.changes'), 'w') as f:
-            f.write(contents)
-        return contents
-
-    def test_changesgenerate_no_change_or_changes_file(self):
-        self._write_servicedata(2)
-        self.tar_scm_std('--changesgenerate', 'enable')
-        self._check_servicedata()
-
-    def test_changesgenerate_no_change_same_changes_file(self):
-        self._write_servicedata(2)
-        orig_changes = self._write_changes_file()
-        self.tar_scm_std('--changesgenerate', 'enable')
-        self._check_servicedata()
-
-    def test_changesgenerate_new_commit_no_changes_file(self):
-        self._write_servicedata(2)
-        self.fixtures.create_commits(1)
-        self.tar_scm_std('--changesgenerate', 'enable')
-        self._check_servicedata(revision=3)
-
-    def _test_changesgenerate_new_commit_and_changes_file(self, author=None):
-        self._write_servicedata(2)
-        orig_changes = self._write_changes_file()
-        self.fixtures.create_commits(3)
-
-        tar_scm_args = [
-            '--changesgenerate', 'enable',
-            '--versionformat', '0.6.%h',
-        ]
-        if author is not None:
-            tar_scm_args += ['--changesauthor', self.fixtures.user_email]
-        self.tar_scm_std(*tar_scm_args)
-
-        self._check_servicedata(revision=5, expected_dirents=3)
-
-        expected_author = author or 'opensuse-packag...@opensuse.org'
-        expected_changes_regexp = self._new_change_entry_regexp(
-            expected_author,
-            textwrap.dedent("""\
-              - Update to version 0.6.%s:
-                \* 3
-                \* 4
-                \* 5
-              """) % self.abbrev_sha1s('tag5')
-        )
-        self._check_changes(orig_changes, expected_changes_regexp)
-
-    def test_changesgenerate_new_commit_and_changes_file_no_version(self):
-        self._write_servicedata(2)
-        orig_changes = self._write_changes_file()
-        self.fixtures.create_commits(3)
-
-        tar_scm_args = [
-            '--changesgenerate', 'enable',
-            '--version', '',
-            '--changesauthor', self.fixtures.user_email
-        ]
-        self.tar_scm_std(*tar_scm_args)
-
-        self._check_servicedata(revision=5, expected_dirents=3)
-
-        expected_author = self.fixtures.user_email
-        expected_changes_regexp = self._new_change_entry_regexp(
-            expected_author,
-            textwrap.dedent("""\
-              - Update to version \d{10}.%s:
-                \* 3
-                \* 4
-                \* 5
-              """) % self.abbrev_sha1s('tag5')
-        )
-        self._check_changes(orig_changes, expected_changes_regexp)
-
-    def _new_change_entry_regexp(self, author, changes):
-        return textwrap.dedent("""\
-          ^-------------------------------------------------------------------
-          \w{3} \w{3} [ \d]\d \d\d:\d\d:\d\d [A-Z]{3} 20\d\d - %s
-
-          %s
-          """) % (author, changes)
-
-    def _check_changes(self, orig_changes, expected_changes_regexp):
-        new_changes_file = os.path.join(self.outdir, 'pkg.changes')
-        self.assertTrue(os.path.exists(new_changes_file))
-        with open(new_changes_file) as f:
-            new_changes = f.read()
-            self.assertNotEqual(orig_changes, new_changes)
-            print new_changes
-            expected_changes_regexp += "(.*)"
-            self.assertRegexpMatches(new_changes, expected_changes_regexp)
-            m = re.match(expected_changes_regexp, new_changes, re.DOTALL)
-            self.assertEqual(m.group(1), orig_changes)
-
-    def test_changesgenerate_new_commit_and_changes_file(self):
-        self._test_changesgenerate_new_commit_and_changes_file(
-            self.fixtures.user_email)
+    def test_updatecache_has_tag(self):
+        fix = self.fixtures
+        fix.create_commits(2)
+        self.tar_scm_std("--revision", 'tag2',
+                         "--versionformat", "@PARENT_TAG@")
+        self.assertTarOnly(self.basename(version="tag2"))
 
-    def test_changesgenerate_new_commit_and_changes_file_default_author(self):
-        self._test_changesgenerate_new_commit_and_changes_file()
+        self.scmlogs.next('prepare-branch')
+        repo_path = fix.repo_path
+        os.chdir(repo_path)
+        fix.safe_run('checkout tag2')
+        fix.create_commits(3)
+        fix.safe_run('tag -a -m some_message detached_tag')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/hgfixtures.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/hgfixtures.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/hgfixtures.py    
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/hgfixtures.py        
2016-07-07 13:32:21.000000000 +0200
@@ -53,3 +53,6 @@
              self.timestamps[tag],
              self.sha1s[tag])
         )
+
+    def get_committer_date(self):
+        return '--date="%s"' % (str(self.COMMITTER_DATE) + " 0")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/hgtests.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/hgtests.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/hgtests.py       
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/hgtests.py   
2016-07-07 13:32:21.000000000 +0200
@@ -1,6 +1,7 @@
 #!/usr/bin/env python2
 
-import datetime
+from datetime import datetime
+import time
 
 from githgtests import GitHgTests
 from hgfixtures import HgFixtures
@@ -41,12 +42,25 @@
         version = "%s%s" % self.timestamps(self.rev(rev))
         return version.replace('-', '')
 
+    def current_utc_offset(self):
+        now = time.time()
+        offset = (datetime.fromtimestamp(now) -
+                  datetime.utcfromtimestamp(now))
+        # since total_seconds() isn't available in python 2.6 ...
+        return ((((offset.days * 24 * 3600) + offset.seconds) * 10 ** 6) +
+                offset.microseconds + 0.0) / 10 ** 6
+
     def dateYYYYMMDD(self, rev):
-        dateobj = datetime.date.fromtimestamp(self.timestamps(rev)[0])
+        # mercurial has a bug in the localdate filter that makes it apply
+        # the current offset from UTC to historic timestamps for timezones
+        # that have daylight savings enabled
+        dateobj = datetime.utcfromtimestamp(self.timestamps(rev)[0] +
+                                            self.current_utc_offset())
         return dateobj.strftime("%4Y%02m%02d")
 
     def dateYYYYMMDDHHMMSS(self, rev):
-        dateobj = datetime.datetime.fromtimestamp(self.timestamps(rev)[0])
+        dateobj = datetime.utcfromtimestamp(self.timestamps(rev)[0] +
+                                            self.current_utc_offset())
         return dateobj.strftime("%4Y%02m%02dT%02H%02M%02S")
 
     def test_fetch_upstream(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/svnfixtures.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/svnfixtures.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/svnfixtures.py   
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/svnfixtures.py       
2016-07-07 13:32:21.000000000 +0200
@@ -1,9 +1,11 @@
 #!/usr/bin/env python2
 
 import os
+import stat
 
 from fixtures import Fixtures
 from utils    import mkfreshdir, quietrun, run_svn
+from datetime import datetime
 
 
 class SvnFixtures(Fixtures):
@@ -13,8 +15,13 @@
     svn tests use this class in order to have something to test against.
     """
 
+    SVN_COMMITTER_DATE = datetime.utcfromtimestamp(
+        Fixtures.COMMITTER_DATE).isoformat() + ".000000Z"
+
     def init(self):
         self.wd_path = self.container_dir + '/wd'
+        self.user_name  = 'test'
+        self.user_email = 't...@test.com'
 
         self.create_repo()
         self.checkout_repo()
@@ -28,6 +35,13 @@
 
     def create_repo(self):
         quietrun('svnadmin create ' + self.repo_path)
+        # allow revprop changes to explicitly set svn:date
+        hook = self.repo_path + '/hooks/pre-revprop-change'
+        f = open(hook, 'w')
+        f.write("#!/bin/sh\nexit 0;\n")
+        f.close()
+        st = os.stat(hook)
+        os.chmod(hook, st.st_mode | stat.S_IEXEC)
         print "created repo", self.repo_path
 
     def checkout_repo(self):
@@ -41,6 +55,8 @@
                 self.safe_run('add ' + new)
                 self.added[new] = True
         self.safe_run('commit -m%d' % new_rev)
+        self.safe_run('propset svn:date --revprop -r HEAD %s' %
+                      self.SVN_COMMITTER_DATE)
         return new_rev
 
     def get_metadata(self, formatstr):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/svntests.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/svntests.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/svntests.py      
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/svntests.py  
2016-07-07 13:32:21.000000000 +0200
@@ -1,11 +1,15 @@
 #!/usr/bin/env python2
 
-from commontests import CommonTests
+import os
+import re
+import textwrap
+
+from gitsvntests import GitSvnTests
 from svnfixtures import SvnFixtures
 from utils       import run_svn
 
 
-class SvnTests(CommonTests):
+class SvnTests(GitSvnTests):
 
     """Unit tests for 'tar_scm --scm svn'.
 
@@ -22,6 +26,19 @@
     def default_version(self):
         return self.rev(2)
 
+    def changesrevision(self, rev, abbrev=False):
+        return rev
+
+    def changesregex(self, rev):
+        return rev
+
+    def tar_scm_args(self):
+        scm_args = [
+            '--changesgenerate', 'enable',
+            '--versionformat', '0.6.%r',
+        ]
+        return scm_args
+
     def test_versionformat_rev(self):
         self.tar_scm_std('--versionformat', 'myrev%r.svn')
         self.assertTarOnly(self.basename(version='myrev2.svn'))
@@ -36,3 +53,19 @@
         basename = self.basename(version='foo2')
         th = self.assertTarOnly(basename)
         self.assertTarMemberContains(th, basename + '/a', '2')
+
+    def _check_servicedata(self, expected_dirents=2, revision=2):
+        dirents = self.assertNumDirents(self.outdir, expected_dirents)
+        self.assertTrue('_servicedata' in dirents,
+                        '_servicedata in %s' % repr(dirents))
+        sd = open(os.path.join(self.outdir, '_servicedata')).read()
+        expected = """\
+          <servicedata>
+            <service name="tar_scm">
+              <param name="url">%s</param>
+              <param name="changesrevision">([0-9].*)</param>
+            </service>
+          </servicedata>""" % self.fixtures.repo_url
+        (expected, count) = re.subn('\s{2,}', '\s*', expected)
+        m = re.match(expected, sd)
+        self.assertTrue(m, "\n'%s'\n!~ /%s/" % (sd, expected))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/testassertions.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/testassertions.py
--- 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/testassertions.py    
    2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/testassertions.py    
2016-07-07 13:32:21.000000000 +0200
@@ -3,6 +3,7 @@
 import os
 from pprint import pprint, pformat
 import re
+import sys
 import tarfile
 import unittest
 
@@ -65,16 +66,29 @@
         self.assertEqual(expected, got, msg)
         return th, tarents
 
+    def assertDirentsMtime(self, entries):
+        '''This test is disabled on Python 2.6 because tarfile is not able to
+        directly change the mtime for an entry in the tarball.'''
+        if sys.hexversion < 0x02070000:
+            return
+        for i in range(0, len(entries)):
+            self.assertEqual(entries[i].mtime, 1234567890)
+
+    def assertDirents(self, entries, top):
+        self.assertEqual(entries[0].name, top)
+        self.assertEqual(entries[1].name, top + '/a')
+        self.assertEqual(entries[2].name, top + '/c')
+        self.assertDirentsMtime(entries)
+
     def assertSubdirDirents(self, entries, top):
         self.assertEqual(entries[0].name, top)
         self.assertEqual(entries[1].name, top + '/b')
+        self.assertDirentsMtime(entries)
 
     def assertStandardTar(self, tar, top):
         th, entries = self.assertNumTarEnts(tar, 5)
         entries.sort(lambda x, y: cmp(x.name, y.name))
-        self.assertEqual(entries[0].name, top)
-        self.assertEqual(entries[1].name, top + '/a')
-        self.assertEqual(entries[2].name, top + '/c')
+        self.assertDirents(entries[:3], top)
         self.assertSubdirDirents(entries[3:], top + '/subdir')
         return th
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/unittestcases.py 
new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/unittestcases.py
--- old/obs-service-tar_scm-0.6.0~pre.1461681073.57c0bab/tests/unittestcases.py 
2016-04-28 00:54:15.000000000 +0200
+++ new/obs-service-tar_scm-0.6.0.1467889501.49c9462/tests/unittestcases.py     
2016-07-07 13:32:21.000000000 +0200
@@ -3,8 +3,10 @@
 import unittest
 import sys
 import os
+from mock import patch
 
 from tar_scm import _calc_dir_to_clone_to
+from tar_scm import _git_log_cmd
 
 
 class UnitTestCases(unittest.TestCase):
@@ -22,5 +24,21 @@
         ]
 
         for cd in clone_dirs:
-            clone_dir = _calc_dir_to_clone_to(scm, cd, outdir)
+            clone_dir = _calc_dir_to_clone_to(scm, cd, "", outdir)
             self.assertEqual(clone_dir, os.path.join(outdir, 'repo'))
+
+    @patch('tar_scm.safe_run')
+    def test__git_log_cmd_with_args(self, safe_run_mock):
+        new_cmd = _git_log_cmd(['-n1'], None, '')
+        safe_run_mock.assert_called_once_with(['git', 'log', '-n1'], cwd=None)
+
+    @patch('tar_scm.safe_run')
+    def test__git_log_cmd_without_args(self, safe_run_mock):
+        new_cmd = _git_log_cmd([], None, '')
+        safe_run_mock.assert_called_once_with(['git', 'log'], cwd=None)
+
+    @patch('tar_scm.safe_run')
+    def test__git_log_cmd_with_subdir(self, safe_run_mock):
+        new_cmd = _git_log_cmd(['-n1'], None, 'subdir')
+        safe_run_mock.assert_called_once_with(['git', 'log', '-n1',
+                                               '--', 'subdir'], cwd=None)


Reply via email to