Get VCS info from pycbc_glue/generate_vcs_info.py and add build information.
    Substitute these into pycbc_glue/git_version.py.in to produce
    pycbc_glue/git_version.py.
490983
def write_build_info():
    
    date = branch = tag = author = committer = status = builder_name = build_date = ""
    id = "1.1.0"
    
    try:
        v = gvcsi.generate_git_version_info()
        id, date, branch, tag, author = v.id, v.date, b.branch, v.tag, v.author
        committer, status = v.committer, v.status

        # determine current time and treat it as the build time
        build_date = time.strftime('%Y-%m-%d %H:%M:%S +0000', time.gmtime())

        # determine builder
        retcode, builder_name = gvcsi.call_out(('git', 'config', 'user.name'))
        if retcode:
            builder_name = "Unknown User"
        retcode, builder_email = gvcsi.call_out(('git', 'config', 'user.email'))
        if retcode:
            builder_email = ""
        builder = "%s <%s>" % (builder_name, builder_email)
    except:
        pass

    sed_cmd = ('sed',
        '-e', 's/@ID@/%s/' % id,
        '-e', 's/@DATE@/%s/' % date,
        '-e', 's/@BRANCH@/%s/' % branch,
        '-e', 's/@TAG@/%s/' % tag,
        '-e', 's/@AUTHOR@/%s/' % author,
        '-e', 's/@COMMITTER@/%s/' % committer,
        '-e', 's/@STATUS@/%s/' % status,
        '-e', 's/@BUILDER@/%s/' % builder_name,
        '-e', 's/@BUILD_DATE@/%s/' % build_date,
        'misc/git_version.py.in')

    # FIXME: subprocess.check_call becomes available in Python 2.5
    sed_retcode = subprocess.call(sed_cmd,
        stdout=open('pycbc_glue/git_version.py', 'w'))
    if sed_retcode:
        raise gvcsi.GitInvocationError
    return id
604943
def get_versions():
    """"""
    # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
    # __file__, we can work backwards from there to the root. Some
    # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
    # case we can only use expanded keywords.

    cfg = get_config()
    verbose = cfg.verbose

    try:
        return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
                                          verbose)
    except NotThisMethod:
        pass

    root = os.path.realpath(__file__)

    root_dir = os.path.dirname(root)
    if os.path.isfile(os.path.join(root_dir, 'VERSION')):
        with open(os.path.join(root_dir, 'VERSION')) as vfile:
            version = vfile.readline().strip()

        return {
            "version": version,
            "full-revisionid": None,
            "dirty": None,
            "error": None,
            "date": None
        }

    try:
        # versionfile_source is the relative path from the top of the source
        # tree (where the .git directory might live) to this file. Invert
        # this to find the root from __file__.
        for i in cfg.versionfile_source.split('/'):
            root = os.path.dirname(root)
    except NameError:
        return {"version": "0+unknown", "full-revisionid": None,
                "dirty": None,
                "error": "unable to find root of source tree",
                "date": None}

    try:
        pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
        return render(pieces, cfg.style)
    except NotThisMethod:
        pass

    try:
        if cfg.parentdir_prefix:
            return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
    except NotThisMethod:
        pass

    return {"version": "0+unknown", "full-revisionid": None,
            "dirty": None,
            "error": "unable to compute version", "date": None}
250250
def vcs_init(self):
        """"""
        VCS(os.path.join(self.outdir, self.name), self.pkg_data)
854540
def build(self):
        
        # pylint: disable=len-as-condition
        if len(self.dutinformation) > 0 and (self.dutinformation.get(0).build is not None):
            return self.dutinformation.get(0).build.name
        return None
286791
def generate(env):
    findIt('bcc32', env)
    """"""
    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
    for suffix in ['.c', '.cpp']:
        static_obj.add_action(suffix, SCons.Defaults.CAction)
        shared_obj.add_action(suffix, SCons.Defaults.ShCAction)
        static_obj.add_emitter(suffix, SCons.Defaults.StaticObjectEmitter)
        shared_obj.add_emitter(suffix, SCons.Defaults.SharedObjectEmitter)

    env['CC']        = 'bcc32'
    env['CCFLAGS']   = SCons.Util.CLVar('')
    env['CFLAGS']   = SCons.Util.CLVar('')
    env['CCCOM']     = '$CC -q $CFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES'
    env['SHCC']      = '$CC'
    env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
    env['SHCFLAGS'] = SCons.Util.CLVar('$CFLAGS')
    env['SHCCCOM']   = '$SHCC -WD $SHCFLAGS $SHCCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -c -o$TARGET $SOURCES'
    env['CPPDEFPREFIX']  = '-D'
    env['CPPDEFSUFFIX']  = ''
    env['INCPREFIX']  = '-I'
    env['INCSUFFIX']  = ''
    env['SHOBJSUFFIX'] = '.dll'
    env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 0
    env['CFILESUFFIX'] = '.cpp'
1050963
def get_vcs_info(path):
    """"""
    for info in SUPPORTED:
        vcs_path = osp.join(path, info['rootdir'])
        if osp.isdir(vcs_path):
            return info
1059337
def svn_versions_from_vcs(tag_prefix, root, verbose=False):
    

    if not os.path.exists(os.path.join(root, '.svn')):
        if verbose:
            print("no .svn in %s." % root)
        return {}

    current_module = sys.modules[__name__]

    # If we're running from _version.py .
    tag_url = getattr(current_module, 'svn_tag_url', None)
    
    # If we're running from versioneer.py .
    if tag_url is None:
        vcs_settings = getattr(current_module, 'vcs_settings', None)
        if vcs_settings is not None and \
           'svn' in vcs_settings and \
           'tag_url' in vcs_settings['svn']:
            tag_url = vcs_settings['svn']['tag_url']

    if tag_url is None:
        raise ValueError("Please define VCS-specific 'tag_url' setting for "
                         "'svn' within 'versioneer'.")

    svn_commands = ['svn']
    info_xml = run_command(svn_commands, ['ls', '--xml', tag_url], cwd=root)
# TODO(dustin): This should raise an EnvironmentError upon failure.
    if info_xml is None:
        print("Error accessing Subversion for latest version.")
        return {}

    (releases, latest_revision) = svn_parse_tag_xml(info_xml)

    release_info = releases[latest_revision]
    release_name = release_info['name']
    versions = { 'default': release_name, 
                 'version': release_name, 
                 'full': release_name }

# Examples of strings returned by Git.
#
#    versions["closest_tag"]
#    versions["distance"]
#    versions["short_revisionid"]
#    versions["dirty"]
#    versions["pep440"]
#    versions["describe"]
#    versions["default"]
#    versions["dash_dirty"]
#    versions["closest_tag_or_zero"]
#    versions["dash_distance"]

    return versions
33725
def build(self):
        
        pkg_security([self.name])
        self.error_uns()
        if self.FAULT:
            print("")
            self.msg.template(78)
            print("| Package {0} {1} {2} {3}".format(self.prgnam, self.red,
                                                     self.FAULT, self.endc))
            self.msg.template(78)
        else:
            sources = []
            if not os.path.exists(self.meta.build_path):
                os.makedirs(self.meta.build_path)
            if not os.path.exists(self._SOURCES):
                os.makedirs(self._SOURCES)
            os.chdir(self.meta.build_path)
            Download(self.meta.build_path, self.sbo_dwn.split(),
                     repo="sbo").start()
            Download(self._SOURCES, self.source_dwn, repo="sbo").start()
            script = self.sbo_dwn.split("/")[-1]
            for src in self.source_dwn:
                sources.append(src.split("/")[-1])
            BuildPackage(script, sources, self.meta.build_path,
                         auto=False).build()
            slack_package(self.prgnam)
8827
def deploy(version):
    
    NAME = "pathquery"
    git = Command("git").in_dir(DIR.project)
    version_file = DIR.project.joinpath("VERSION")
    old_version = version_file.bytes().decode('utf8')
    if version_file.bytes().decode("utf8") != version:
        DIR.project.joinpath("VERSION").write_text(version)
        git("add", "VERSION").run()
        git("commit", "-m", "RELEASE: Version {0} -> {1}".format(
            old_version,
            version
        )).run()
        git("push").run()
        git("tag", "-a", version, "-m", "Version {0}".format(version)).run()
        git("push", "origin", version).run()
    else:
        git("push").run()

    # Set __version__ variable in __init__.py, build sdist and put it back
    initpy = DIR.project.joinpath(NAME, "__init__.py")
    original_initpy_contents = initpy.bytes().decode('utf8')
    initpy.write_text(
        original_initpy_contents.replace("DEVELOPMENT_VERSION", version)
    )
    python("setup.py", "sdist").in_dir(DIR.project).run()
    initpy.write_text(original_initpy_contents)

    # Upload to pypi
    python(
        "-m", "twine", "upload", "dist/{0}-{1}.tar.gz".format(NAME, version)
    ).in_dir(DIR.project).run()
931930
def _build_result_metainfo(args):
        
        data = dict()
        if hasattr(args, "branch") and args.branch:
            data["build_branch"] = args.branch
        if hasattr(args, "commitId") and args.commitId:
            data["buildcommit"] = args.commitId
        if hasattr(args, "gitUrl") and args.gitUrl:
            data["build_git_url"] = args.gitUrl
        if hasattr(args, "buildUrl") and args.buildUrl:
            data["build_url"] = args.buildUrl
        if hasattr(args, "campaign") and args.campaign:
            data["campaign"] = args.campaign
        if hasattr(args, "jobId") and args.jobId:
            data["job_id"] = args.jobId
        if hasattr(args, "toolchain") and args.toolchain:
            data["toolchain"] = args.toolchain
        if hasattr(args, "buildDate") and args.buildDate:
            data["build_date"] = args.buildDate
        return data
344321
def get_git_info(git_folder, verbose=False):
    
    if verbose:
        print("detect GIT info by folder: '%s'" % git_folder)
    try:
        git_info = {
            "commitid": get_commit_id(git_folder),
            "branch": get_current_branch(git_folder),
            "git_path": get_git_file_path(git_folder),
            "url": get_remote_url(git_folder),
            "scm": "unknown",
            "scm_group": "unknown",
            "scm_path": "unknown",
            "scm_link": ""
        }
        if is_git_root_dirty(git_folder):
            git_info['dirty'] = True
    except Exception as err:  # pylint: disable=broad-except
        print("GitTool exception:")
        print(err)
        return {}

    if isinstance(git_info['url'], str):
        match = re.search(r"github\.com:(.*)\/(.*)", git_info['url'])
        if match:
            git_info["scm"] = "github.com"
            git_info["scm_path"] = match.group(2)
            git_info["scm_group"] = match.group(1)
            scm_link_end = " %s/%s" % (git_info["scm_group"],
                                       git_info["scm_path"].replace(".git", ""))
            git_info["scm_link"] = "https://github.com/" + scm_link_end
            git_info["scm_link"] += "/tree/%s/%s" % (git_info['commitid'], git_info["git_path"])

    if verbose:
        print("all git_info:")
        print(git_info)

    return git_info
1140227
def build(self):
        
        signed = bool(self.options() & Builder.Options.Signed)

        # remove previous build information
        buildpath = self.buildPath()
        if not buildpath:
            raise errors.InvalidBuildPath(buildpath)

        # setup the environment
        for key, value in self.environment().items():
            log.info('SET {0}={1}'.format(key, value))
            os.environ[key] = value

        if os.path.exists(buildpath):
            shutil.rmtree(buildpath)

        # generate the build path for the installer
        os.makedirs(buildpath)

        # create the output path
        outpath = self.outputPath()
        if not os.path.exists(outpath):
            os.makedirs(outpath)

        # copy license information
        src = self.licenseFile()
        if src and os.path.exists(src):
            targ = os.path.join(buildpath, 'license.txt')
            shutil.copyfile(src, targ)

        # generate revision information
        if self.options() & Builder.Options.GenerateRevision:
            self.generateRevision()

        # generate documentation information
        if self.options() & Builder.Options.GenerateDocs:
            self.generateDocumentation(buildpath)

        # generate setup file
        if self.options() & Builder.Options.GenerateSetupFile:
            setuppath = os.path.join(self.sourcePath(), '..')
            egg = (self.options() & Builder.Options.GenerateEgg) != 0
            self.generateSetupFile(setuppath, egg=egg)

        # generate executable information
        if self.options() & Builder.Options.GenerateExecutable:
            if not self.generateExecutable(signed=signed):
                return

        # generate zipfile information
        if self.options() & Builder.Options.GenerateZipFile:
            self.generateZipFile(self.outputPath())

        # generate installer information
        if self.options() & Builder.Options.GenerateInstaller:
            self.generateInstaller(buildpath, signed=signed)
734602
def get_scm():
  
  # TODO(John Sirois): Extract a module/class to carry the bootstrap logic.
  global _SCM
  if not _SCM:
    from pants.scm.git import Git
    # We know about git, so attempt an auto-configure
    worktree = Git.detect_worktree()
    if worktree and os.path.isdir(worktree):
      git = Git(worktree=worktree)
      try:
        logger.debug('Detected git repository at {} on branch {}'.format(worktree, git.branch_name))
        set_scm(git)
      except git.LocalException as e:
        logger.info('Failed to load git repository at {}: {}'.format(worktree, e))
  return _SCM
1310486
def get_version():
    """"""
    import ast

    with open(os.path.join("cyvcf2", "__init__.py"), "r") as init_file:
      module = ast.parse(init_file.read())

    version = (ast.literal_eval(node.value) for node in ast.walk(module)
         if isinstance(node, ast.Assign)
         and node.targets[0].id == "__version__")
    try:
      return next(version)
    except StopIteration:
          raise ValueError("version could not be located")
433940
def generate(env):
    """"""
    static_obj, shared_obj = SCons.Tool.createObjBuilders(env)

    # TODO(batch):  shouldn't reach in to cmdgen this way; necessary
    # for now to bypass the checks in Builder.DictCmdGenerator.__call__()
    # and allow .cc and .cpp to be compiled in the same command line.
    static_obj.cmdgen.source_ext_match = False
    shared_obj.cmdgen.source_ext_match = False

    for suffix in CSuffixes:
        static_obj.add_action(suffix, CAction)
        shared_obj.add_action(suffix, ShCAction)
        static_obj.add_emitter(suffix, static_object_emitter)
        shared_obj.add_emitter(suffix, shared_object_emitter)

    for suffix in CXXSuffixes:
        static_obj.add_action(suffix, CXXAction)
        shared_obj.add_action(suffix, ShCXXAction)
        static_obj.add_emitter(suffix, static_object_emitter)
        shared_obj.add_emitter(suffix, shared_object_emitter)

    env['CCPDBFLAGS'] = SCons.Util.CLVar(['${(PDB and "/Z7") or ""}'])
    env['CCPCHFLAGS'] = SCons.Util.CLVar(['${(PCH and "/Yu%s \\\"/Fp%s\\\""%(PCHSTOP or "",File(PCH))) or ""}'])
    env['_MSVC_OUTPUT_FLAG'] = msvc_output_flag
    env['_CCCOMCOM']  = '$CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS $CCPCHFLAGS $CCPDBFLAGS'
    env['CC']         = 'cl'
    env['CCFLAGS']    = SCons.Util.CLVar('/nologo')
    env['CFLAGS']     = SCons.Util.CLVar('')
    env['CCCOM']      = '${TEMPFILE("$CC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CFLAGS $CCFLAGS $_CCCOMCOM","$CCCOMSTR")}'
    env['SHCC']       = '$CC'
    env['SHCCFLAGS']  = SCons.Util.CLVar('$CCFLAGS')
    env['SHCFLAGS']   = SCons.Util.CLVar('$CFLAGS')
    env['SHCCCOM']    = '${TEMPFILE("$SHCC $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCCCOMSTR")}'
    env['CXX']        = '$CC'
    env['CXXFLAGS']   = SCons.Util.CLVar('$( /TP $)')
    env['CXXCOM']     = '${TEMPFILE("$CXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $CXXFLAGS $CCFLAGS $_CCCOMCOM","$CXXCOMSTR")}'
    env['SHCXX']      = '$CXX'
    env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
    env['SHCXXCOM']   = '${TEMPFILE("$SHCXX $_MSVC_OUTPUT_FLAG /c $CHANGED_SOURCES $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM","$SHCXXCOMSTR")}'
    env['CPPDEFPREFIX']  = '/D'
    env['CPPDEFSUFFIX']  = ''
    env['INCPREFIX']  = '/I'
    env['INCSUFFIX']  = ''
#    env.Append(OBJEMITTER = [static_object_emitter])
#    env.Append(SHOBJEMITTER = [shared_object_emitter])
    env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1

    env['RC'] = 'rc'
    env['RCFLAGS'] = SCons.Util.CLVar('')
    env['RCSUFFIXES']=['.rc','.rc2']
    env['RCCOM'] = '$RC $_CPPDEFFLAGS $_CPPINCFLAGS $RCFLAGS /fo$TARGET $SOURCES'
    env['BUILDERS']['RES'] = res_builder
    env['OBJPREFIX']      = ''
    env['OBJSUFFIX']      = '.obj'
    env['SHOBJPREFIX']    = '$OBJPREFIX'
    env['SHOBJSUFFIX']    = '$OBJSUFFIX'

    # Set-up ms tools paths
    msvc_setup_env_once(env)

    env['CFILESUFFIX'] = '.c'
    env['CXXFILESUFFIX'] = '.cc'

    msvc_set_PCHPDBFLAGS(env)


    env['PCHCOM'] = '$CXX /Fo${TARGETS[1]} $CXXFLAGS $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS /c $SOURCES /Yc$PCHSTOP /Fp${TARGETS[0]} $CCPDBFLAGS $PCHPDBFLAGS'
    env['BUILDERS']['PCH'] = pch_builder

    if 'ENV' not in env:
        env['ENV'] = {}
    if 'SystemRoot' not in env['ENV']:    # required for dlls in the winsxs folders
        env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
586347
def get_versions(default=DEFAULT, verbose=False):
    """"""


    # returns dict with two keys: 'version' and 'full'
    assert versionfile_source is not None, "please set versioneer.versionfile_source"
    assert tag_prefix is not None, "please set versioneer.tag_prefix"
    assert parentdir_prefix is not None, "please set versioneer.parentdir_prefix"
    assert VCS is not None, "please set versioneer.VCS"

    # I am in versioneer.py, which must live at the top of the source tree,
    # which we use to compute the root directory. py2exe/bbfreeze/non-CPython
    # don't have __file__, in which case we fall back to sys.argv[0] (which
    # ought to be the setup.py script). We prefer __file__ since that's more
    # robust in cases where setup.py was invoked in some weird way (e.g. pip)
    root = get_root()
    versionfile_abs = os.path.join(root, versionfile_source)

    # extract version from first of _version.py, VCS command (e.g. 'git
    # describe'), parentdir. This is meant to work for developers using a
    # source checkout, for users of a tarball created by 'setup.py sdist',
    # and for users of a tarball/zipball created by 'git archive' or github's
    # download-from-tag feature or the equivalent in other VCSes.

    # Try to get the version info from the VCS-specific replacement keywords.

    get_keywords_f = vcs_function(VCS, "get_keywords")
    versions_from_keywords_f = vcs_function(VCS, "versions_from_keywords")
    if get_keywords_f and versions_from_keywords_f:
        vcs_keywords = get_keywords_f(versionfile_abs)
        ver = versions_from_keywords_f(vcs_keywords, tag_prefix)
        if ver:
            if verbose: print("got version from expanded keyword %s" % ver)
            return ver

    # Try to get the version info from _version.py .

    ver = versions_from_file(versionfile_abs)
    if ver:
        if verbose: print("got version from file %s %s" % (versionfile_abs,ver))
        return ver

    # Try to get the version info from the VCS, directly.

    versions_from_vcs_f = vcs_function(VCS, "versions_from_vcs")
    if versions_from_vcs_f:
        ver = versions_from_vcs_f(tag_prefix, root, verbose)
        if ver:
            if verbose: print("got version from VCS %s" % ver)
            return ver

    # Try to get the version info from the directory's naming.

    ver = versions_from_parentdir(parentdir_prefix, root, verbose)
    if ver:
        if verbose: print("got version from parentdir %s" % ver)
        return ver

    if verbose: print("got version from default %s" % default)
    return default
608818
def build_update(self,
                     alias=None,
                     assigned_to=None,
                     blocks_add=None,
                     blocks_remove=None,
                     blocks_set=None,
                     depends_on_add=None,
                     depends_on_remove=None,
                     depends_on_set=None,
                     cc_add=None,
                     cc_remove=None,
                     is_cc_accessible=None,
                     comment=None,
                     comment_private=None,
                     component=None,
                     deadline=None,
                     dupe_of=None,
                     estimated_time=None,
                     groups_add=None,
                     groups_remove=None,
                     keywords_add=None,
                     keywords_remove=None,
                     keywords_set=None,
                     op_sys=None,
                     platform=None,
                     priority=None,
                     product=None,
                     qa_contact=None,
                     is_creator_accessible=None,
                     remaining_time=None,
                     reset_assigned_to=None,
                     reset_qa_contact=None,
                     resolution=None,
                     see_also_add=None,
                     see_also_remove=None,
                     severity=None,
                     status=None,
                     summary=None,
                     target_milestone=None,
                     target_release=None,
                     url=None,
                     version=None,
                     whiteboard=None,
                     work_time=None,
                     fixed_in=None,
                     qa_whiteboard=None,
                     devel_whiteboard=None,
                     internal_whiteboard=None,
                     sub_component=None,
                     flags=None,
                     comment_tags=None):
        
        ret = {}

        # These are only supported for rhbugzilla
        for key, val in [
            ("fixed_in", fixed_in),
            ("devel_whiteboard", devel_whiteboard),
            ("qa_whiteboard", qa_whiteboard),
            ("internal_whiteboard", internal_whiteboard),
            ("sub_component", sub_component),
        ]:
            if val is not None:
                raise ValueError("bugzilla instance does not support "
                                 "updating '%s'" % key)

        def s(key, val, convert=None):
            if val is None:
                return
            if convert:
                val = convert(val)
            ret[key] = val

        def add_dict(key, add, remove, _set=None, convert=None):
            if add is remove is _set is None:
                return

            def c(val):
                val = self._listify(val)
                if convert:
                    val = [convert(v) for v in val]
                return val

            newdict = {}
            if add is not None:
                newdict["add"] = c(add)
            if remove is not None:
                newdict["remove"] = c(remove)
            if _set is not None:
                newdict["set"] = c(_set)
            ret[key] = newdict


        s("alias", alias)
        s("assigned_to", assigned_to)
        s("is_cc_accessible", is_cc_accessible, bool)
        s("component", component)
        s("deadline", deadline)
        s("dupe_of", dupe_of, int)
        s("estimated_time", estimated_time, int)
        s("op_sys", op_sys)
        s("platform", platform)
        s("priority", priority)
        s("product", product)
        s("qa_contact", qa_contact)
        s("is_creator_accessible", is_creator_accessible, bool)
        s("remaining_time", remaining_time, float)
        s("reset_assigned_to", reset_assigned_to, bool)
        s("reset_qa_contact", reset_qa_contact, bool)
        s("resolution", resolution)
        s("severity", severity)
        s("status", status)
        s("summary", summary)
        s("target_milestone", target_milestone)
        s("target_release", target_release)
        s("url", url)
        s("version", version)
        s("whiteboard", whiteboard)
        s("work_time", work_time, float)
        s("flags", flags)
        s("comment_tags", comment_tags, self._listify)

        add_dict("blocks", blocks_add, blocks_remove, blocks_set,
                 convert=int)
        add_dict("depends_on", depends_on_add, depends_on_remove,
                 depends_on_set, convert=int)
        add_dict("cc", cc_add, cc_remove)
        add_dict("groups", groups_add, groups_remove)
        add_dict("keywords", keywords_add, keywords_remove, keywords_set)
        add_dict("see_also", see_also_add, see_also_remove)

        if comment is not None:
            ret["comment"] = {"comment": comment}
            if comment_private:
                ret["comment"]["is_private"] = comment_private

        return ret