Example #1
0
def main():
    from functools import partial as func_partial
    from argparse import ArgumentParser, SUPPRESS

    parser = ArgumentParser()
    addarg = parser.add_argument
    addflag = func_partial(addarg, action="store_true")
    addarg("version",
           metavar="VERSION",
           nargs=1,
           help="the version to be released")
    addflag("-s",
            "--dsymbols",
            dest="debug_symbols",
            help="generate debug symbols for debug builds")
    addflag("-d", "--docs", dest="docs", help="generate documentation")
    addflag("-n", "--no-bin", dest="no_binaries", help="don't compile code")
    addflag("--7z", dest="_7z", help="create a 7z archive")
    addflag("--gz", dest="tar_gz", help="create a tar.gz archive")
    addflag("--bz2", dest="tar_bz2", help="create a tar.bz2 archive")
    addflag("--zip", dest="zip", help="create a zip archive")
    addflag("--deb", dest="deb", help="create deb files")
    addflag("--pdf", dest="pdf", help="create a PDF document")
    addflag("--chm", dest="chm", help=SUPPRESS)  # "create a CHM file"
    addflag("-m",
            dest="copy_modified",
            help="copy modified files from the (git) working directory")
    addflag("--ldc", dest="ldc", help="use ldc instead of dmd")
    addarg("--src",
           dest="src",
           metavar="SRC",
           help="use SRC folder instead of checking out code with git")
    addarg("--cmp-exe",
           dest="cmp_exe",
           metavar="EXE_PATH",
           help="specify EXE_PATH if dmd/ldc is not in your PATH")
    addarg("--builddir",
           dest="builddir",
           metavar="DIR",
           help="where to build the release and archives (default is build/)")
    addarg(
        "--winpath",
        dest="winpath",
        metavar="P",
        help="permanently append P to PATH in the Windows (or wine's) registry. "
        "Exits the script.")
    addarg("--debm", dest="deb_mntnr", metavar="MTR",
           help=SUPPRESS)  # Sets the maintainer info of the package.
    addarg("--debnum", dest="deb_num", metavar="NUM", default=1,
           help=SUPPRESS)  # Sets the package number.

    options = args = parser.parse_args(sys.uargv[1:])

    if options.winpath != None:
        from env_path import append2PATH
        append2PATH(options.winpath)
        return

    change_cwd(__file__)

    # Validate the version argument.
    m = re.match(r"^((\d)\.(\d{3})(?:-(\w+))?)(?:\+(\w+))?$", args.version)
    if not m:
        parser.error("invalid VERSION format: /\d.\d\d\d(-\w+)?/ E.g.: 1.123")
    # The version of DIL to be built.
    class Version(unicode):
        def __new__(cls, parts):
            v = unicode.__new__(cls, parts[0])
            v.MAJ, v.MIN, SFX, BSFX = parts[1:]
            v.SFX = SFX or ''
            v.BINSFX = BSFX or ''
            return v

    VERSION = Version(m.groups())

    # Pick a compiler for compiling DIL.
    CmdClass = (DMDCommand, LDCCommand)[options.ldc]
    COMPILER = Path(options.cmp_exe or CmdClass.exe)
    COMPILER.CmdClass = CmdClass
    if not COMPILER.exists and not locate_command(COMPILER):
        parser.error("The executable '%s' could not be located." % COMPILER)

    # Path to DIL's root folder.
    DIL = dil_path()

    # Build folder.
    BUILDROOT = Path(options.builddir or "build") / ("dil_" + VERSION)
    # Destination of distributable files.
    DEST = dil_path(BUILDROOT / "dil", dilconf=False)
    DEST.DOC = doc_path(DEST.DOC)

    # Temporary directory, deleted in the end.
    TMP = BUILDROOT / "tmp"
    # The list of module files (with info) that have been processed.
    MODLIST = TMP / "modules.txt"
    # The source files that need to be compiled and documentation generated for.
    FILES = []
    # The folders and files which were produced by a build.
    PRODUCED = []

    sw, sw_all = StopWatch(), StopWatch()

    # Check out a new working copy.
    BUILDROOT.rm().mkdir()  # First remove the whole folder and recreate it.
    if options.src != None:
        # Use the source folder specified by the user.
        src = Path(options.src)
        if not src.exists:
            parser.error("the given SRC path (%s) doesn't exist" % src)
        #if src.ext in ('zip', 'gz', 'bz2'):
        # TODO:
        src.copy(DEST)
    else:
        if not locate_command('git'):
            parser.error("'git' is not in your PATH; specify --src instead")
        if not locate_command('tar'):
            parser.error("program 'tar' is not in your PATH")
        # Use git to checkout a clean copy.
        DEST.mkdir()
        TARFILE = DEST / "dil.tar"
        call_proc("git", "archive", "-o", TARFILE, "HEAD")
        call_proc("tar", "-xf", TARFILE.name, cwd=DEST)
        TARFILE.rm()
        if options.copy_modified:
            modified_files = call_read("git", "ls-files", "-m")[:-1]
            if modified_files != "":
                for f in modified_files.split("\n"):
                    Path(f).copy(DEST / f)
    # Create other directories not available in a clean checkout.
    DOC = DEST.DOC
    Paths(DOC.HTMLSRC, DOC.CSS, DOC.IMG, DOC.JS, TMP).mkdirs()

    # Rebuild the path object for kandil. (Images are globbed.)
    DEST.KANDIL = kandil_path(DEST / "kandil")

    print("== Copying files ==")
    copy_files(DEST)

    # Find the source code files.
    FILES = find_dil_source_files(DEST.SRC)

    # Update the version info.
    update_VERSION(DEST.SRC / "dil" / "Version.d", VERSION)
    write_VERSION(VERSION, DEST)

    if options.docs:
        build_dil_if_inexistant(DIL.EXE)

        print("== Generating documentation ==")
        DOC_FILES = DEST.DATA / ("macros_dil.ddoc", "dilconf.d") + FILES
        versions = ["DDoc"]
        generate_docs(DIL.EXE,
                      DEST.DOC,
                      MODLIST,
                      DOC_FILES,
                      versions,
                      options=['-v', '-i', '-hl', '--kandil'])

    if options.pdf:
        write_PDF(DEST, DEST.DOC, VERSION, TMP)
    #if options.chm:
    #write_CHM(DEST, DEST.DOC, VERSION, TMP)

    TARGETS = [Targets[n] for n in ("Lin32", "Lin64", "Win32")]

    if not options.no_binaries:
        BINS = build_binaries(TARGETS, COMPILER, VERSION.MAJ, FILES, DEST)
        for bin in BINS:
            (DIL.DATA / "dilconf.d").copy(bin.folder)

    PRODUCED += [(DEST.abspath, sw.stop())]

    # Remove unneeded directories.
    options.docs or DEST.DOC.rm()

    # Build archives.
    assert DEST[-1] != Path.sep
    create_archives(options, DEST.name, DEST.name, DEST.folder)

    if options.deb and not options.no_binaries:
        MTR = get_MAINTAINER(options.deb_mntnr)
        NUM = int(options.deb_num)
        # Make an archive for each architecture.
        SRC = Path(DEST)
        SRC.DATA = DEST.DATA
        SRC.DOC = DEST.DOC
        LINUX_BINS = [bin for bin in BINS if bin.target.islin]
        for arch in ("i386", "amd64"):
            # Gather the binaries that belong to arch.
            SRC.BINS = [bin for bin in LINUX_BINS if bin.target.arch == arch]
            sw.start()
            DEB = make_deb_package(SRC, DEST.folder, VERSION, arch, DEST, MTR,
                                   NUM)
            PRODUCED += [(DEB.abspath, sw.stop())]

    if not options.no_binaries:
        # Make an arch-independent folder.
        NOARCH = TMP / "dil_noarch"
        DEST.copy(NOARCH)
        (NOARCH / ("linux", "windows")).rm()

        # Linux:
        for bits in (32, 64):
            BIN = DEST / "linux" / "bin%d" % bits
            if not BIN.exists: continue
            SRC = (TMP / "dil_" + VERSION).rm()  # Clear if necessary.
            NOARCH.copy(SRC)
            BIN.copy(SRC / "bin")
            write_modified_dilconf(SRC / "data" / "dilconf.d",
                                   SRC / "bin" / "dilconf.d",
                                   Path("${BINDIR}") / ".." / "data")
            NAME = BUILDROOT.abspath / "dil_%s_linux%s" % (VERSION, bits)
            for ext in (".7z", ".tar.xz"):
                sw.start()
                make_archive(SRC, NAME + ext)
                PRODUCED += [(NAME + ext, sw.stop())]
            SRC.rm()

        # Windows:
        for bits in (32, 64):
            if bits != 32: continue  # Only 32bit supported atm.
            BIN = DEST / "windows" / "bin%d" % bits
            if not BIN.exists: continue
            SRC = (TMP / "dil_" + VERSION).rm()  # Clear if necessary.
            NOARCH.copy(SRC)
            BIN.copy(SRC / "bin")
            write_modified_dilconf(SRC / "data" / "dilconf.d",
                                   SRC / "bin" / "dilconf.d",
                                   Path("${BINDIR}") / ".." / "data")
            NAME = BUILDROOT.abspath / "dil_%s_win%s" % (VERSION, bits)
            for ext in (".7z", ".zip"):
                sw.start()
                make_archive(SRC, NAME + ext)
                PRODUCED += [(NAME + ext, sw.stop())]
            SRC.rm()
        NOARCH.rm()

        # All platforms:
        NAME = BUILDROOT.abspath / "dil_%s_all" % VERSION
        for ext in (".7z", ".zip", ".tar.xz"):
            sw.start()
            make_archive(DEST, NAME + ext)
            PRODUCED += [(NAME + ext, sw.stop())]

    TMP.rm()

    if PRODUCED:
        print("\nProduced files/folders:")
        for x, sec in PRODUCED:
            if Path(x).exists:
                print(x + " (%.2fs)" % sec)
        print()

    print("Finished in %.2fs!" % sw_all.stop())
Example #2
0
def main():
  from functools import partial as func_partial
  from argparse import ArgumentParser, SUPPRESS

  parser = ArgumentParser()
  addarg = parser.add_argument
  addflag = func_partial(addarg, action="store_true")
  addarg("version", metavar="VERSION", nargs=1,
    help="the version to be released")
  addflag("-s", "--dsymbols", dest="debug_symbols",
    help="generate debug symbols for debug builds")
  addflag("-d", "--docs", dest="docs", help="generate documentation")
  addflag("-n", "--no-bin", dest="no_binaries", help="don't compile code")
  addflag("--7z", dest="_7z", help="create a 7z archive")
  addflag("--gz", dest="tar_gz", help="create a tar.gz archive")
  addflag("--bz2", dest="tar_bz2", help="create a tar.bz2 archive")
  addflag("--zip", dest="zip", help="create a zip archive")
  addflag("--deb", dest="deb", help="create deb files")
  addflag("--pdf", dest="pdf", help="create a PDF document")
  addflag("--chm", dest="chm", help=SUPPRESS) # "create a CHM file"
  addflag("-m", dest="copy_modified",
    help="copy modified files from the (git) working directory")
  addflag("--ldc", dest="ldc", help="use ldc instead of dmd")
  addarg("--src", dest="src", metavar="SRC",
    help="use SRC folder instead of checking out code with git")
  addarg("--cmp-exe", dest="cmp_exe", metavar="EXE_PATH",
    help="specify EXE_PATH if dmd/ldc is not in your PATH")
  addarg("--builddir", dest="builddir", metavar="DIR",
    help="where to build the release and archives (default is build/)")
  addarg("--winpath", dest="winpath", metavar="P",
    help="permanently append P to PATH in the Windows (or wine's) registry. "
         "Exits the script.")
  addarg("--debm", dest="deb_mntnr", metavar="MTR",
    help=SUPPRESS) # Sets the maintainer info of the package.
  addarg("--debnum", dest="deb_num", metavar="NUM", default=1,
    help=SUPPRESS) # Sets the package number.

  options = args = parser.parse_args(sys.uargv[1:])

  if options.winpath != None:
    from env_path import append2PATH
    append2PATH(options.winpath)
    return

  change_cwd(__file__)

  # Validate the version argument.
  m = re.match(r"^((\d)\.(\d{3})(?:-(\w+))?)(?:\+(\w+))?$", args.version)
  if not m:
    parser.error("invalid VERSION format: /\d.\d\d\d(-\w+)?/ E.g.: 1.123")
  # The version of DIL to be built.
  class Version(unicode):
    def __new__(cls, parts):
      v = unicode.__new__(cls, parts[0])
      v.MAJ, v.MIN, SFX, BSFX = parts[1:]
      v.SFX = SFX or ''
      v.BINSFX = BSFX or ''
      return v
  VERSION = Version(m.groups())

  # Pick a compiler for compiling DIL.
  CmdClass = (DMDCommand, LDCCommand)[options.ldc]
  COMPILER = Path(options.cmp_exe or CmdClass.exe)
  COMPILER.CmdClass = CmdClass
  if not COMPILER.exists and not locate_command(COMPILER):
    parser.error("The executable '%s' could not be located." % COMPILER)

  # Path to DIL's root folder.
  DIL       = dil_path()

  # Build folder.
  BUILDROOT = Path(options.builddir or "build")/("dil_"+VERSION)
  # Destination of distributable files.
  DEST      = dil_path(BUILDROOT/"dil", dilconf=False)
  DEST.DOC  = doc_path(DEST.DOC)

  # Temporary directory, deleted in the end.
  TMP       = BUILDROOT/"tmp"
  # The list of module files (with info) that have been processed.
  MODLIST   = TMP/"modules.txt"
  # The source files that need to be compiled and documentation generated for.
  FILES     = []
  # The folders and files which were produced by a build.
  PRODUCED  = []

  sw, sw_all = StopWatch(), StopWatch()

  # Check out a new working copy.
  BUILDROOT.rm().mkdir() # First remove the whole folder and recreate it.
  if options.src != None:
    # Use the source folder specified by the user.
    src = Path(options.src)
    if not src.exists:
      parser.error("the given SRC path (%s) doesn't exist" % src)
    #if src.ext in ('zip', 'gz', 'bz2'):
      # TODO:
    src.copy(DEST)
  else:
    if not locate_command('git'):
      parser.error("'git' is not in your PATH; specify --src instead")
    if not locate_command('tar'):
      parser.error("program 'tar' is not in your PATH")
    # Use git to checkout a clean copy.
    DEST.mkdir()
    TARFILE = DEST/"dil.tar"
    call_proc("git", "archive", "-o", TARFILE, "HEAD")
    call_proc("tar", "-xf", TARFILE.name, cwd=DEST)
    TARFILE.rm()
    if options.copy_modified:
      modified_files = call_read("git", "ls-files", "-m")[:-1]
      if modified_files != "":
        for f in modified_files.split("\n"):
          Path(f).copy(DEST/f)
  # Create other directories not available in a clean checkout.
  DOC = DEST.DOC
  Paths(DOC.HTMLSRC, DOC.CSS, DOC.IMG, DOC.JS, TMP).mkdirs()

  # Rebuild the path object for kandil. (Images are globbed.)
  DEST.KANDIL = kandil_path(DEST/"kandil")

  print("== Copying files ==")
  copy_files(DEST)

  # Find the source code files.
  FILES = find_dil_source_files(DEST.SRC)

  # Update the version info.
  update_VERSION(DEST.SRC/"dil"/"Version.d", VERSION)
  write_VERSION(VERSION, DEST)

  if options.docs:
    build_dil_if_inexistant(DIL.EXE)

    print("== Generating documentation ==")
    DOC_FILES = DEST.DATA/("macros_dil.ddoc", "dilconf.d") + FILES
    versions = ["DDoc"]
    generate_docs(DIL.EXE, DEST.DOC, MODLIST, DOC_FILES,
                  versions, options=['-v', '-i', '-hl', '--kandil'])

  if options.pdf:
    write_PDF(DEST, DEST.DOC, VERSION, TMP)
  #if options.chm:
    #write_CHM(DEST, DEST.DOC, VERSION, TMP)

  TARGETS = [Targets[n] for n in ("Lin32", "Lin64", "Win32")]

  if not options.no_binaries:
    BINS = build_binaries(TARGETS, COMPILER, VERSION.MAJ, FILES, DEST)
    for bin in BINS:
      (DIL.DATA/"dilconf.d").copy(bin.folder)

  PRODUCED += [(DEST.abspath, sw.stop())]

  # Remove unneeded directories.
  options.docs or DEST.DOC.rm()

  # Build archives.
  assert DEST[-1] != Path.sep
  create_archives(options, DEST.name, DEST.name, DEST.folder)

  if options.deb and not options.no_binaries:
    MTR = get_MAINTAINER(options.deb_mntnr)
    NUM = int(options.deb_num)
    # Make an archive for each architecture.
    SRC = Path(DEST)
    SRC.DATA = DEST.DATA
    SRC.DOC  = DEST.DOC
    LINUX_BINS = [bin for bin in BINS if bin.target.islin]
    for arch in ("i386", "amd64"):
      # Gather the binaries that belong to arch.
      SRC.BINS  = [bin for bin in LINUX_BINS if bin.target.arch == arch]
      sw.start()
      DEB = make_deb_package(SRC, DEST.folder, VERSION, arch, DEST, MTR, NUM)
      PRODUCED += [(DEB.abspath, sw.stop())]

  if not options.no_binaries:
    # Make an arch-independent folder.
    NOARCH = TMP/"dil_noarch"
    DEST.copy(NOARCH)
    (NOARCH/("linux", "windows")).rm()

    # Linux:
    for bits in (32, 64):
      BIN = DEST/"linux"/"bin%d"%bits
      if not BIN.exists: continue
      SRC = (TMP/"dil_"+VERSION).rm() # Clear if necessary.
      NOARCH.copy(SRC)
      BIN.copy(SRC/"bin")
      write_modified_dilconf(SRC/"data"/"dilconf.d", SRC/"bin"/"dilconf.d",
        Path("${BINDIR}")/".."/"data")
      NAME = BUILDROOT.abspath/"dil_%s_linux%s" % (VERSION, bits)
      for ext in (".7z", ".tar.xz"):
        sw.start()
        make_archive(SRC, NAME+ext)
        PRODUCED += [(NAME+ext, sw.stop())]
      SRC.rm()

    # Windows:
    for bits in (32, 64):
      if bits != 32: continue # Only 32bit supported atm.
      BIN = DEST/"windows"/"bin%d"%bits
      if not BIN.exists: continue
      SRC = (TMP/"dil_"+VERSION).rm() # Clear if necessary.
      NOARCH.copy(SRC)
      BIN.copy(SRC/"bin")
      write_modified_dilconf(SRC/"data"/"dilconf.d", SRC/"bin"/"dilconf.d",
        Path("${BINDIR}")/".."/"data")
      NAME = BUILDROOT.abspath/"dil_%s_win%s" % (VERSION, bits)
      for ext in (".7z", ".zip"):
        sw.start()
        make_archive(SRC, NAME+ext)
        PRODUCED += [(NAME+ext, sw.stop())]
      SRC.rm()
    NOARCH.rm()

    # All platforms:
    NAME = BUILDROOT.abspath/"dil_%s_all" % VERSION
    for ext in (".7z", ".zip", ".tar.xz"):
      sw.start()
      make_archive(DEST, NAME+ext)
      PRODUCED += [(NAME+ext, sw.stop())]

  TMP.rm()

  if PRODUCED:
    print("\nProduced files/folders:")
    for x, sec in PRODUCED:
      if Path(x).exists:
        print(x+" (%.2fs)"%sec)
    print()


  print("Finished in %.2fs!" % sw_all.stop())
Example #3
0
def main():
  from functools import partial as func_partial
  from optparse import OptionParser

  usage = "Usage: scripts/release.py VERSION [Options]"
  parser = OptionParser(usage=usage)
  add_option = func_partial(parser.add_option, action="store_true",
                            default=False)
  add_option("-s", "--dsymbols", dest="debug_symbols",
    help="generate debug symbols for debug builds")
  add_option("-d", "--docs", dest="docs", help="generate documentation")
  add_option("-n", "--no-bin", dest="no_binaries", help="don't compile code")
  add_option("--7z", dest="_7z", help="create a 7z archive")
  add_option("--gz", dest="tar_gz", help="create a tar.gz archive")
  add_option("--bz2", dest="tar_bz2", help="create a tar.bz2 archive")
  add_option("--zip", dest="zip", help="create a zip archive")
  add_option("--pdf", dest="pdf", help="create a PDF document")
  add_option("-m", dest="copy_modified",
    help="copy modified files from the (git) working directory")
  parser.add_option("--src", dest="src", metavar="SRC", default=None,
    help="use SRC folder instead of checking out code with git")
  parser.add_option("--dmd-exe", dest="dmd_exe", metavar="EXE_PATH",
    default="dmd", help="specify EXE_PATH if dmd is not in your PATH")
  parser.add_option("--builddir", dest="builddir", metavar="DIR", default=None,
    help="where to build the release and archives (default is build/)")
  parser.add_option("--winpath", dest="winpath", metavar="P", default=None,
    help="permanently append P to PATH in the Windows (or wine's) registry. "
         "Exits the script.")

  (options, args) = parser.parse_args()

  if options.winpath != None:
    from env_path import append2PATH
    append2PATH(options.winpath, Path(""))
    return

  if len(args) < 1:
    return parser.print_help()
  if len(args) > 1:
    print "Warning! Arguments ignored: " + " ".join(args[1:])

  change_cwd(__file__)

  # Validate the version argument.
  m = re.match(r"((\d)\.(\d\d\d)(-\w+)?)", args[0])
  if not m:
    parser.error("invalid VERSION; format: /\d.\d\d\d(-\w+)?/ E.g.: 1.123")
  matched = m.groups()

  if not Path(options.dmd_exe).exists and not locate_command(options.dmd_exe):
    parser.error("The executable '%s' couldn't be located or does not exist." %
      options.dmd_exe)

  # Path to dil's root folder.
  DIL       = dil_path()
  # Name or path to the executable of dmd.
  DMD_EXE   = Path(options.dmd_exe)
  # The version of dil to be built.
  VERSION, V_MAJOR = matched[:2]
  V_MINOR, V_SUFFIX = (matched[2], firstof(str, matched[3], ''))

  # Build folder.
  BUILD_DIR = Path(firstof(str, options.builddir, "build"))
  # Destination of distributable files.
  DEST      = dil_path(BUILD_DIR/("dil."+VERSION), dilconf=False)
  BIN       = DEST.BIN # Shortcut to the bin/ folder.
  DEST.DOC  = doc_path(DEST.DOC)

  # Temporary directory, deleted in the end.
  TMP       = DEST/"tmp"
  # The list of module files (with info) that have been processed.
  MODLIST   = TMP/"modules.txt"
  # The files to generate documentation for.
  FILES     = []

  # Create the build directory.
  BUILD_DIR.makedirs()
  # Check out a new working copy.
  DEST.rmtree() # First remove the tree.
  if options.src != None:
    # Use the source folder specified by the user.
    src = Path(options.src)
    if not src.exists:
      parser.error("the given SRC path (%s) doesn't exist" % src)
    #if src.ext in ('.zip', '.gz', 'bz2'):
      # TODO:
    src.copytree(DEST)
  elif locate_command('git'):
    # Use git to checkout a clean copy.
    os.system("git clone ./ '%s'" % DEST)
    (DEST/".git").rmtree() # Remove the .git folder.
    if options.copy_modified:
      modified_files = os.popen("git ls-files -m").read()[:-1]
      if modified_files != "":
        for f in modified_files.split("\n"):
          Path(f).copy(DEST/f)
  else:
    parser.error("git is not in your PATH; specify --src instead")
  # Create other directories not available in a clean checkout.
  DOC = DEST.DOC
  map(Path.mkdir, (DEST.BIN, DOC, DOC.HTMLSRC,
                   DOC.CSS, DOC.IMG, DOC.JS, TMP))

  # Rebuild the path object for kandil. (Images are globbed.)
  DEST.KANDIL = kandil_path(DEST/"kandil")

  # Find the source code files.
  FILES = find_dil_source_files(DEST.SRC)

  # Update the version info.
  VERSION_FILE = DEST.SRC/"dil"/"Version.d"
  update_version(VERSION_FILE, V_MAJOR, V_MINOR, V_SUFFIX)

  if options.docs:
    build_dil_if_inexistant(DIL.EXE)

    DOC_FILES = [DEST.KANDIL.ddoc] + \
                 DEST.DATA//("macros_dil.ddoc", "dilconf.d") + FILES
    print "***** Generating documentation *****"
    versions = ["DDoc"]
    generate_docs(DIL.EXE, DEST.DOC, MODLIST, DOC_FILES,
                  versions, options=['-v', '-i', '-hl', '--kandil'])
    if options.pdf:
      write_PDF(DEST, DEST.DOC, VERSION, TMP)

  DMD_EXE.use_wine = False
  use_wine = False
  if platform is 'win32':
    build_linux_binaries = False
    build_windows_binaries = True
  else:
    build_linux_binaries = True
    build_windows_binaries = locate_command("wine") != None
    class BINPath(Path):
      def __div__(self, name):
        """ Converts a Unix path to a Windows path. """
        name = Path.__div__(self, name)
        return name if name.ext != '.exe' else name.replace("/", r"\\")
    BIN = BINPath(BIN)
    use_wine = True # Use wine on Linux to build Windows binaries.
    if not build_windows_binaries:
      print "Error: can't build windows binaries: "\
            "wine is not installed or not in PATH."

  if options.no_binaries:
    build_linux_binaries = build_windows_binaries = False

  # Create partial functions with common parameters.
  # Note: the -inline switch makes the binaries significantly larger on Linux.
  build_dil_rls = func_partial(build_dil, DMD_EXE, FILES,
                               release=True, optimize=True, inline=True)
  build_dil_dbg = func_partial(build_dil, DMD_EXE, FILES,
                               debug_info=options.debug_symbols)
  if build_linux_binaries:
    print "***** Building Linux binaries *****"
    # Linux Debug Binaries
    build_dil_dbg(BIN/"dil_d")
    build_dil_dbg(BIN/"dil2_d", versions=["D2"])
    # Linux Release Binaries
    build_dil_rls(BIN/"dil")
    build_dil_rls(BIN/"dil2", versions=["D2"])

  if build_windows_binaries:
    print "***** Building Windows binaries *****"
    DMD_EXE.use_wine = use_wine
    # Windows Debug Binaries
    build_dil_dbg(BIN/"dil_d.exe")
    build_dil_dbg(BIN/"dil2_d.exe", versions=["D2"])
    # Windows Release Binaries
    build_dil_rls(BIN/"dil.exe")
    build_dil_rls(BIN/"dil2.exe", versions=["D2"])

  print "***** Copying files *****"
  copy_files(DEST)

  options.docs or DEST.DOC.rmtree()
  TMP.rmtree()

  # Build archives.
  assert DEST[-1] != Path.sep
  opt = options
  for exec_cmd, cmd in zip((opt.tar_gz, opt.tar_bz2, opt.zip, opt._7z),
    ("tar --owner root --group root -czf %(name)s.tar.gz %(src)s",
     "tar --owner root --group root --bzip2 -cf %(name)s.tar.bz2 %(src)s",
     "zip -q -9 -r %(name)s.zip %(src)s",
     "7zr a %(name)s.7z %(src)s")):
    if not exec_cmd: continue
    if locate_command(cmd):
      print "Error: the utility '%s' is not in your PATH." % cmd
      continue
    cmd = cmd % dict(locals(), name=DEST, src=DEST)
    print cmd
    os.system(cmd)
Example #4
0
def main():
  from functools import partial as func_partial
  from optparse import OptionParser

  usage = "Usage: %s VERSION [Options]" % __file__
  parser = OptionParser(usage=usage)
  add_option = func_partial(parser.add_option, action="store_true",
                            default=False)
  add_option("-s", "--dsymbols", dest="debug_symbols",
    help="generate debug symbols for debug builds")
  add_option("-d", "--docs", dest="docs", help="generate documentation")
  add_option("-n", "--no-bin", dest="no_binaries", help="don't compile code")
  add_option("--7z", dest="_7z", help="create a 7z archive")
  add_option("--gz", dest="tar_gz", help="create a tar.gz archive")
  add_option("--bz2", dest="tar_bz2", help="create a tar.bz2 archive")
  add_option("--zip", dest="zip", help="create a zip archive")
  add_option("--pdf", dest="pdf", help="create a PDF document")
  #add_option("--chm", dest="chm", help="create a CHM file")
  add_option("-m", dest="copy_modified",
    help="copy modified files from the (git) working directory")
  parser.add_option("--src", dest="src", metavar="SRC", default=None,
    help="use SRC folder instead of checking out code with git")
  parser.add_option("--cmp-exe", dest="cmp_exe", metavar="EXE_PATH",
    help="specify EXE_PATH if dmd/ldc is not in your PATH")
  add_option("--ldc", dest="ldc", help="use ldc instead of dmd")
  parser.add_option("--builddir", dest="builddir", metavar="DIR", default=None,
    help="where to build the release and archives (default is build/)")
  parser.add_option("--winpath", dest="winpath", metavar="P", default=None,
    help="permanently append P to PATH in the Windows (or wine's) registry. "
         "Exits the script.")

  (options, args) = parser.parse_args(sys.uargv[1:])

  if options.winpath != None:
    from env_path import append2PATH
    append2PATH(options.winpath, Path(""))
    return

  if len(args) < 1:
    return parser.print_help()
  if len(args) > 1:
    print("Warning! Arguments ignored: " + " ".join(args[1:]))

  change_cwd(__file__)

  # Validate the version argument.
  m = re.match(r"((\d)\.(\d\d\d)(-\w+)?)", args[0])
  if not m:
    parser.error("invalid VERSION; format: /\d.\d\d\d(-\w+)?/ E.g.: 1.123")
  # The version of DIL to be built.
  VERSION, V_MAJOR, V_MINOR, V_SUFFIX = m.groups()
  V_SUFFIX = V_SUFFIX or ''

  # Pick a compiler for compiling DIL.
  CmdClass = (DMDCommand, LDCCommand)[options.ldc]
  COMPILER = Path(options.cmp_exe if options.cmp_exe else CmdClass.cmd)
  COMPILER.cmd = CmdClass
  if not COMPILER.exists and not locate_command(COMPILER):
    parser.error("The executable '%s' couldn't be located or does not exist." %
                 COMPILER)

  # Path to DIL's root folder.
  DIL       = dil_path()

  # Build folder.
  BUILD_DIR = Path(options.builddir or "build")
  # Destination of distributable files.
  DEST      = dil_path(BUILD_DIR/("dil."+VERSION), dilconf=False)
  BIN       = DEST.BIN # Shortcut to the bin/ folder.
  DEST.DOC  = doc_path(DEST.DOC)

  # Temporary directory, deleted in the end.
  TMP       = DEST/"tmp"
  # The list of module files (with info) that have been processed.
  MODLIST   = TMP/"modules.txt"
  # The files to generate documentation for.
  FILES     = []

  # Create the build directory.
  BUILD_DIR.makedirs()
  # Check out a new working copy.
  DEST.rmtree() # First remove the tree.
  if options.src != None:
    # Use the source folder specified by the user.
    src = Path(options.src)
    if not src.exists:
      parser.error("the given SRC path (%s) doesn't exist" % src)
    #if src.ext in ('.zip', '.gz', 'bz2'):
      # TODO:
    src.copytree(DEST)
  elif locate_command('git'):
    # Use git to checkout a clean copy.
    DEST.mkdir()
    TARFILE = DEST/"dil.tar"
    subprocess.call(["git", "archive", "-o", TARFILE, "HEAD"])
    subprocess.call(["tar", "-xf", TARFILE.name], cwd=DEST)
    TARFILE.rm()
    if options.copy_modified:
      modified_files = call_read(["git", "ls-files", "-m"])[:-1]
      if modified_files != "":
        for f in modified_files.split("\n"):
          Path(f).copy(DEST/f)
  else:
    parser.error("git is not in your PATH; specify --src instead")
  # Create other directories not available in a clean checkout.
  DOC = DEST.DOC
  map(Path.mkdir, (DEST.BIN, DOC, DOC.HTMLSRC,
                   DOC.CSS, DOC.IMG, DOC.JS, TMP))

  # Rebuild the path object for kandil. (Images are globbed.)
  DEST.KANDIL = kandil_path(DEST/"kandil")

  print("***** Copying files *****")
  copy_files(DEST)

  # Find the source code files.
  FILES = find_dil_source_files(DEST.SRC)

  # Update the version info.
  VERSION_FILE = DEST.SRC/"dil"/"Version.d"
  update_version(VERSION_FILE, V_MAJOR, V_MINOR, V_SUFFIX)

  if options.docs:
    build_dil_if_inexistant(DIL.EXE)

    print("***** Generating documentation *****")
    DOC_FILES = DEST.DATA//("macros_dil.ddoc", "dilconf.d") + FILES
    versions = ["DDoc"]
    generate_docs(DIL.EXE, DEST.DOC, MODLIST, DOC_FILES,
                  versions, options=['-v', '-i', '-hl', '--kandil'])

  if options.pdf:
    write_PDF(DEST, DEST.DOC, VERSION, TMP)
  #if options.chm:
    #write_CHM(DEST, DEST.DOC, VERSION, TMP)

  COMPILER.use_wine = False
  use_wine = False
  if is_win32:
    build_linux_binaries = False
    build_windows_binaries = True
  else:
    build_linux_binaries = True
    build_windows_binaries = locate_command("wine") != None
    class BINPath(Path):
      def __div__(self, name):
        """ Converts a Unix path to a Windows path. """
        name = Path.__div__(self, name)
        return name if name.ext != '.exe' else name.replace("/", r"\\")
    BIN = BINPath(BIN)
    use_wine = True # Use wine on Linux to build Windows binaries.
    if not build_windows_binaries:
      print("Error: can't build windows binaries: "
            "wine is not installed or not in PATH.")

  if options.no_binaries:
    build_linux_binaries = build_windows_binaries = False

  # Create partial functions with common parameters (aka. currying).
  # Note: the -inline switch makes the binaries significantly larger on Linux.
  linker_args = [None]
  build_dil_rls = func_partial(build_dil, COMPILER, FILES,
    release=True, optimize=True, inline=True, lnk_args=linker_args)
  build_dil_dbg = func_partial(build_dil, COMPILER, FILES,
    debug_info=options.debug_symbols, lnk_args=linker_args)

  if build_linux_binaries:
    print("\n***** Building Linux binaries *****\n")
    linker_args[0] = "-lmpfr"
    # Linux Debug Binaries
    build_dil_dbg(BIN/"dil_d")
    build_dil_dbg(BIN/"dil2_d", versions=["D2"])
    # Linux Release Binaries
    build_dil_rls(BIN/"dil")
    build_dil_rls(BIN/"dil2", versions=["D2"])

  if build_windows_binaries:
    print("\n***** Building Windows binaries *****\n")
    COMPILER.use_wine = use_wine
    linker_args[0] = "+mpfr.lib"
    # Windows Debug Binaries
    build_dil_dbg(BIN/"dil_d.exe")
    build_dil_dbg(BIN/"dil2_d.exe", versions=["D2"])
    # Windows Release Binaries
    build_dil_rls(BIN/"dil.exe")
    build_dil_rls(BIN/"dil2.exe", versions=["D2"])

  options.docs or DEST.DOC.rmtree()
  TMP.rmtree()

  # Build archives.
  assert DEST[-1] != Path.sep
  create_archives(options, DEST.name, DEST.name, DEST.folder)
Example #5
0
def main():
  from functools import partial as func_partial
  from optparse import OptionParser

  usage = "Usage: scripts/release.py VERSION [Options]"
  parser = OptionParser(usage=usage)
  add_option = func_partial(parser.add_option, action="store_true",
                            default=False)
  add_option("-s", "--dsymbols", dest="debug_symbols",
    help="generate debug symbols for debug builds")
  add_option("-d", "--docs", dest="docs", help="generate documentation")
  add_option("--7z", dest="_7z", help="create a 7z archive")
  add_option("--gz", dest="tar_gz", help="create a tar.gz archive")
  add_option("--bz2", dest="tar_bz2", help="create a tar.bz2 archive")
  add_option("--zip", dest="zip", help="create a zip archive")
  add_option("--git", dest="git",
    help="use git to check out a clean copy (default is hg)")
  parser.add_option("--src", dest="src", metavar="SRC", default=None,
    help="use SRC folder instead of checking out code using hg or git")
  parser.add_option("--dmd-exe", dest="dmd_exe", metavar="EXE_PATH",
    default="dmd", help="specify EXE_PATH if dmd is not in your PATH")
  parser.add_option("--builddir", dest="builddir", metavar="DIR", default=None,
    help="where to build the release and archives (default is build/)")
  parser.add_option("--winpath", dest="winpath", metavar="P", default=None,
    help="permanently append P to PATH in the Windows (or wine's) registry. "
         "Exits the script.")

  (options, args) = parser.parse_args()

  if options.winpath != None:
    from env_path import append2PATH
    append2PATH(options.winpath, Path(""))
    return

  if len(args) < 1:
    return parser.print_help()
  if len(args) > 1:
    print "Warning! Arguments ignored: " + " ".join(args[1:])

  # Validate the version argument.
  m = re.match(r"((\d)\.(\d\d\d)(-\w+)?)", args[0])
  if not m:
    parser.error("invalid VERSION; format: /\d.\d\d\d(-\w+)?/ E.g.: 1.123")
  matched = m.groups()

  if not Path(options.dmd_exe).exists and not locate_command(options.dmd_exe):
    print "The executable '%s' couldn't be located or does not exist." % \
          options.dmd_exe
    return

  notNone = max
  # Path of the executable of dil.
  DIL_EXE   = Path("bin")/"dil"
  # Name or path to the executable of dmd.
  DMD_EXE   = options.dmd_exe
  DMD_EXE_W = DMD_EXE # Executable to use for Windows builds.
  # The version of dil to be built.
  VERSION, V_MAJOR = matched[:2]
  V_MINOR, V_SUFFIX = (matched[2], notNone(matched[3], ''))

  # Build folder.
  BUILD_DIR = Path(notNone("build", options.builddir))
  # Destination of distributable files.
  DEST      = BUILD_DIR/("dil."+VERSION)
  # The destination of the binaries.
  DEST.BIN  = DEST/"bin"
  BIN       = DEST.BIN # Shortcut to the bin/ folder.
  # The source code folder of dil.
  DEST.SRC  = DEST/"src"
  # Documentation folder of dil.
  DEST.DOC  = DEST/"doc"
  # The JavaScript, CSS and image folders.
  DEST.JS, DEST.CSS, DEST.IMG = DEST.DOC//("js", "css", "img")
  # Destination of syntax highlighted source files.
  DEST.HTMLSRC = DEST.DOC/"htmlsrc"
  # Dil's data/ directory.
  DEST.DATA   = DEST/'data'
  # Dil's fancy documentation format.
  DEST.KANDIL = DEST/"kandil"

  # Temporary directory, deleted in the end.
  TMP       = DEST/"tmp"
  # The list of module files (with info) that have been processed.
  MODLIST   = TMP/"modules.txt"
  # The files to generate documentation for.
  FILES     = []

  # Create the build directory.
  BUILD_DIR.makedirs()
  # Check out a new working copy.
  DEST.rmtree() # First remove the tree.
  if options.src != None:
    Path(options.src).copytree(DEST)
  elif options.git:
    if locate_command('git'):
      os.system("git clone ./ %(DEST)s && cd %(DEST)s && git checkout"%locals())
      (DEST/".git").rmtree() # Remove the .git folder.
    else:
      raise Exception("git is not in your PATH")
  elif locate_command('hg'):
    os.system("hg archive -r tip -t files " + DEST)
  else:
    raise Exception("hg is not in your PATH; specify SRC or use git")
  # Create other directories not available in a clean checkout.
  map(Path.mkdir, (DEST.BIN, DEST.DOC, DEST.HTMLSRC,
                   DEST.CSS, DEST.IMG, DEST.JS, TMP))

  # Find the source code files.
  FILES = find_dil_source_files(DEST.SRC)

  # Make a backup of the original.
  VERSION_D = DEST.SRC/"dil"/"Version.d"
  VERSION_D.copy(TMP/"Version.d")
  # Update the version info.
  update_version(VERSION_D, V_MAJOR, V_MINOR)
  # Restore the original at the end of the build process.

  if options.docs:
    build_dil_if_inexistant(DIL_EXE)

    DOC_FILES = [DEST.KANDIL/"kandil.ddoc"] + \
                 DEST.DATA//("macros_dil.ddoc", "dilconf.d") + FILES
    versions = ["DDoc"]
    print "***** Generating documentation *****"
    generate_docs(DIL_EXE, DEST.DOC, MODLIST, DOC_FILES, versions, options='-v')

    modlist = read_modules_list(MODLIST)
    generate_modules_js(modlist, DEST.JS/"modules.js")

    print "***** Generating syntax highlighted HTML files *****"
    for args in generate_shl_files2(DIL_EXE, DEST.HTMLSRC, modlist):
      print "hl %s > %s" % args;
    download_jquery(DEST.JS/"jquery.js")

  if platform is 'win32':
    build_linux_binaries = False
    build_windows_binaries = True
  else:
    build_linux_binaries = True
    build_windows_binaries = locate_command("wine") != None
    class BINPath(Path):
      def __div__(self, name):
        """ Converts a Unix path to a Windows path. """
        name = Path.__div__(self, name)
        return name if name.ext != '.exe' else name.replace("/", r"\\")
    BIN = BINPath(BIN)
    DMD_EXE_W = "wine dmd.exe" # Use wine on Linux to build Windows binaries.
    if not build_windows_binaries:
      print "Error: can't build windows binaries: "\
            "wine is not installed or not in PATH."

  # Create partial functions with common parameters.
  # Note: the -inline switch makes the binaries significantly larger on Linux.
  build_dil_rls = func_partial(build_dil, FILES, dmd_exe=DMD_EXE,
                               release=True, optimize=True, inline=True)
  build_dil_dbg = func_partial(build_dil, FILES, dmd_exe=DMD_EXE,
                               debug_info=options.debug_symbols)
  if build_linux_binaries:
    print "***** Building Linux binaries *****"
    # Linux Debug Binaries
    build_dil_dbg(BIN/"dil_d")
    build_dil_dbg(BIN/"dil2_d", versions=["D2"])
    # Linux Release Binaries
    build_dil_rls(BIN/"dil")
    build_dil_rls(BIN/"dil2", versions=["D2"])

  if build_windows_binaries:
    print "***** Building Windows binaries *****"
    build_dil_dbg.keywords['dmd_exe'] = DMD_EXE_W
    build_dil_rls.keywords['dmd_exe'] = DMD_EXE_W
    # Windows Debug Binaries
    build_dil_dbg(BIN/"dil_d.exe")
    build_dil_dbg(BIN/"dil2_d.exe", versions=["D2"])
    # Windows Release Binaries
    build_dil_rls(BIN/"dil.exe")
    build_dil_rls(BIN/"dil2.exe", versions=["D2"])

  print "***** Copying files *****"
  copy_files(DEST)

  # Restore the original. NOTE: is this a good idea?
  (TMP/"Version.d").move(VERSION_D)

  if not options.docs:
    DEST.DOC.rmtree()
  TMP.rmtree()

  # Build archives.
  assert DEST[-1] != Path.sep
  opt = options
  for exec_cmd, cmd in zip((opt.tar_gz, opt.tar_bz2, opt.zip, opt._7z),
    ("tar --owner root --group root -czf %(name)s.tar.gz %(src)s",
     "tar --owner root --group root --bzip2 -cf %(name)s.tar.bz2 %(src)s",
     "zip -q -9 -r %(name)s.zip %(src)s",
     "7zr a %(name)s.7z %(src)s")):
    if not exec_cmd: continue
    if locate_command(cmd):
      print "Error: the utility '%s' is not in your PATH." % cmd
      continue
    cmd = cmd % dict(locals(), name=DEST, src=DEST)
    print cmd
    os.system(cmd)