Esempio n. 1
0
def build_binaries(TARGETS, COMPILER, V_MAJOR, FILES, DEST):
    from functools import partial as func_partial
    CmdClass = COMPILER.CmdClass

    def fix_dirsep(path, target):
        if not is_win32 and target.iswin:  # Wine needs Windows-style paths.
            path = path.replace(Path.sep, r"\\")
        return path

    if not is_win32 and any(t.iswin for t in TARGETS) and \
       not locate_command("wine"):
        print("Warning: cannot build Windows binaries: 'wine' is not in PATH.")
        TARGETS = [t for t in TARGETS if not t.iswin]

    # Create a curried build function with common parameters.
    build_binary = func_partial(build_dil,
                                CmdClass,
                                FILES,
                                exe=COMPILER,
                                versions=["D" + V_MAJOR])

    BINS = []  # Successfully compiled binaries.

    for target in TARGETS:
        print("== Building {name} {bits}bit binary ==".format(**target))
        dbgargs = rlsargs = {"m%d" % target.bits: True}
        if target.iswin:
            dbgargs = rlsargs = dict(rlsargs, wine=not is_win32)
        if target.islin:
            dbgargs = dict(rlsargs,
                           lnk_args=["-ltango-dmd", "-lphobos2", "-ldl"])
        # Destination dir for the binary.
        B = (DEST / target.dir / "bin%d" % target.bits).mkdir()
        SFX = ""  # An optional suffix. Empty for now.
        DBGEXE, RLSEXE = (B / target[exe] % SFX
                          for exe in ("dbgexe", "rlsexe"))
        dbgargs.update(debug_info=True)
        build_binary(fix_dirsep(DBGEXE, target), **dbgargs)
        # NB: the -inline switch makes the binaries significantly larger on Linux.
        # Enable inlining when DMDBUG #7967 is fixed.
        rlsargs.update(release=True, optimize=True, inline=False)
        build_binary(fix_dirsep(RLSEXE, target), **rlsargs)
        DBGEXE.target = RLSEXE.target = target
        BINS += [exe for exe in (DBGEXE, RLSEXE) if exe.exists]

    return BINS
Esempio n. 2
0
def build_binaries(TARGETS, COMPILER, V_MAJOR, FILES, DEST):
  from functools import partial as func_partial
  CmdClass = COMPILER.CmdClass

  def fix_dirsep(path, target):
    if not is_win32 and target.iswin: # Wine needs Windows-style paths.
      path = path.replace(Path.sep, r"\\")
    return path

  if not is_win32 and any(t.iswin for t in TARGETS) and \
     not locate_command("wine"):
    print("Warning: cannot build Windows binaries: 'wine' is not in PATH.")
    TARGETS = [t for t in TARGETS if not t.iswin]

  # Create a curried build function with common parameters.
  build_binary  = func_partial(build_dil, CmdClass, FILES, exe=COMPILER,
    versions=["D"+V_MAJOR])

  BINS = [] # Successfully compiled binaries.

  for target in TARGETS:
    print("== Building {name} {bits}bit binary ==".format(**target))
    dbgargs = rlsargs = {"m%d" % target.bits : True}
    if target.iswin:
      dbgargs = rlsargs = dict(rlsargs, wine=not is_win32)
    if target.islin:
      dbgargs = dict(rlsargs, lnk_args=["-ltango-dmd", "-lphobos2", "-ldl"])
    # Destination dir for the binary.
    B = (DEST/target.dir/"bin%d"%target.bits).mkdir()
    SFX = "" # An optional suffix. Empty for now.
    DBGEXE, RLSEXE = (B/target[exe] % SFX for exe in ("dbgexe", "rlsexe"))
    dbgargs.update(debug_info=True)
    build_binary(fix_dirsep(DBGEXE, target), **dbgargs)
    # NB: the -inline switch makes the binaries significantly larger on Linux.
    # Enable inlining when DMDBUG #7967 is fixed.
    rlsargs.update(release=True, optimize=True, inline=False)
    build_binary(fix_dirsep(RLSEXE, target), **rlsargs)
    DBGEXE.target = RLSEXE.target = target
    BINS += [exe for exe in (DBGEXE, RLSEXE) if exe.exists]

  return BINS
Esempio n. 3
0
def init(cback):
    global callback, labels, win, is_open
    callback = cback
    is_open = False
    win = Toplevel(TK_ROOT)
    win.title("BEE2")
    win.resizable(False, False)
    tk_tools.set_window_icon(win)
    win.protocol("WM_DELETE_WINDOW", exit_win)
    win.transient(TK_ROOT)
    win.withdraw()

    if utils.MAC:
        # Switch to use the 'modal' window style on Mac.
        TK_ROOT.call('::tk::unsupported::MacWindowStyle', 'style', win,
                     'moveableModal', '')
    # Stop our init from triggering UI sounds.
    sound.block_fx()

    frame = ttk.Frame(win, padding=10)
    frame.grid(row=0, column=0, sticky='NSEW')
    frame.rowconfigure(0, weight=1)
    frame.columnconfigure(0, weight=1)

    labels['noOptions'] = ttk.Label(frame, text=_('No Properties available!'))
    widgets['saveButton'] = ttk.Button(frame,
                                       text=_('Close'),
                                       command=exit_win)
    widgets['titleLabel'] = ttk.Label(frame, text='')
    widgets['titleLabel'].grid(columnspan=9)

    widgets['div_1'] = ttk.Separator(frame, orient="vertical")
    widgets['div_2'] = ttk.Separator(frame, orient="vertical")
    widgets['div_h'] = ttk.Separator(frame, orient="horizontal")

    for key, (prop_type, prop_name) in PROP_TYPES.items():
        # Translate property names from Valve's files.
        if prop_name.startswith('PORTAL2_'):
            prop_name = gameMan.translate(prop_name) + ':'

        labels[key] = ttk.Label(frame, text=prop_name)
        if prop_type is PropTypes.CHECKBOX:
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = srctools.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                frame,
                variable=values[key],
                command=func_partial(set_check, key),
            )
            widgets[key].bind('<Return>',
                              func_partial(
                                  toggleCheck,
                                  key,
                                  values[key],
                              ))

        elif prop_type is PropTypes.OSCILLATE:
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = srctools.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                frame,
                variable=values[key],
                command=func_partial(save_rail, key),
            )

        elif prop_type is PropTypes.PANEL:
            frm = ttk.Frame(frame)
            widgets[key] = frm
            values[key] = StringVar(value=DEFAULTS[key])
            for pos, (angle, disp_angle) in enumerate(PANEL_ANGLES):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=angle,
                    text=gameMan.translate(disp_angle),
                    command=func_partial(save_angle, key, angle),
                ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)

        elif prop_type is PropTypes.GELS:
            frm = ttk.Frame(frame)
            widgets[key] = frm
            values[key] = IntVar(value=DEFAULTS[key])
            for pos, text in enumerate(PAINT_OPTS):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=pos,
                    text=gameMan.translate(text),
                    command=func_partial(save_paint, key, pos),
                ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)
            out_values[key] = str(DEFAULTS[key])

        elif prop_type is PropTypes.PISTON:
            widgets[key] = pist_scale = ttk.Scale(
                frame,
                from_=0,
                to=4,
                orient="horizontal",
                command=func_partial(save_pist, key),
            )
            values[key] = DEFAULTS[key]
            out_values[key] = str(DEFAULTS[key])
            if ((key == 'toplevel' and DEFAULTS['startup'])
                    or (key == 'bottomlevel' and not DEFAULTS['startup'])):
                pist_scale.set(
                    max(DEFAULTS['toplevel'], DEFAULTS['bottomlevel']))
            if ((key == 'toplevel' and not DEFAULTS['startup'])
                    or (key == 'bottomlevel' and DEFAULTS['startup'])):
                pist_scale.set(
                    min(DEFAULTS['toplevel'], DEFAULTS['bottomlevel']))

        elif prop_type is PropTypes.TIMER:
            widgets[key] = ttk.Scale(
                frame,
                from_=0,
                to=30,
                orient="horizontal",
                command=func_partial(save_tim, key),
            )
            values[key] = DEFAULTS[key]

    values['startup'] = DEFAULTS['startup']
Esempio n. 4
0
def init(cback):
    global callback, labels, win, is_open
    callback = cback
    is_open = False
    win = Toplevel(TK_ROOT)
    win.title("BEE2")
    win.resizable(False, False)
    win.iconbitmap('../BEE2.ico')
    win.protocol("WM_DELETE_WINDOW", exit_win)
    win.withdraw()
    labels['noOptions'] = ttk.Label(win, text='No Properties avalible!')
    widgets['saveButton'] = ttk.Button(win, text='Close', command=exit_win)
    widgets['titleLabel'] = ttk.Label(win, text='')
    widgets['titleLabel'].grid(columnspan=9)

    widgets['div_1'] = ttk.Separator(win, orient="vertical")
    widgets['div_2'] = ttk.Separator(win, orient="vertical")
    widgets['div_h'] = ttk.Separator(win, orient="horizontal")

    for key, (prop_type, prop_name) in PROP_TYPES.items():
        labels[key] = ttk.Label(win, text=prop_name + ':')
        if prop_type == 'checkbox':
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = utils.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                win,
                variable=values[key],
                command=func_partial(set_check, key),
            )
            widgets[key].bind('<Return>',
                              func_partial(
                                  toggleCheck,
                                  key,
                                  values[key],
                              ))

        elif prop_type == 'railLift':
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = utils.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                win,
                variable=values[key],
                command=func_partial(save_rail, key),
            )

        elif prop_type == 'panAngle':
            frm = ttk.Frame(win)
            widgets[key] = frm
            values[key] = StringVar(value=DEFAULTS[key])
            for pos, angle in enumerate(['30', '45', '60', '90']):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=angle,
                    text=angle,
                    command=func_partial(save_angle, key, angle),
                ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)

        elif prop_type == 'gelType':
            frm = ttk.Frame(win)
            widgets[key] = frm
            values[key] = IntVar(value=DEFAULTS[key])
            for pos, text in enumerate(PAINT_OPTS):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=pos,
                    text=text,
                    command=func_partial(save_paint, key, pos),
                ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)
            out_values[key] = str(DEFAULTS[key])

        elif prop_type == 'pistPlat':
            widgets[key] = Scale(
                win,
                from_=0,
                to=4,
                orient="horizontal",
                showvalue=False,
                command=func_partial(save_pist, key),
            )
            values[key] = DEFAULTS[key]
            out_values[key] = str(DEFAULTS[key])
            if ((key == 'toplevel' and DEFAULTS['startup'])
                    or (key == 'bottomlevel' and not DEFAULTS['startup'])):
                widgets[key].set(
                    max(DEFAULTS['toplevel'], DEFAULTS['bottomlevel']))
            if ((key == 'toplevel' and not DEFAULTS['startup'])
                    or (key == 'bottomlevel' and DEFAULTS['startup'])):
                widgets[key].set(
                    min(DEFAULTS['toplevel'], DEFAULTS['bottomlevel']))

        elif prop_type == 'timerDel':
            widgets[key] = ttk.Scale(
                win,
                from_=0,
                to=30,
                orient="horizontal",
                command=func_partial(save_tim, key),
            )
            values[key] = DEFAULTS[key]

        elif prop_type == 'railPlat':
            widgets[key] = ttk.Checkbutton(win)
    values['startup'] = DEFAULTS['startup']
Esempio n. 5
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())
Esempio n. 6
0
def init(cback):
    global callback, labels, win, is_open
    callback = cback
    is_open = False
    win = Toplevel(TK_ROOT)
    win.title("BEE2")
    win.resizable(False, False)
    win.iconbitmap('../BEE2.ico')
    win.protocol("WM_DELETE_WINDOW", exit_win)
    win.withdraw()
    labels['noOptions'] = ttk.Label(win, text='No Properties avalible!')
    widgets['saveButton'] = ttk.Button(win, text='Close', command=exit_win)
    widgets['titleLabel'] = ttk.Label(win, text='')
    widgets['titleLabel'].grid(columnspan=9)

    widgets['div_1'] = ttk.Separator(win, orient="vertical")
    widgets['div_2'] = ttk.Separator(win, orient="vertical")
    widgets['div_h'] = ttk.Separator(win, orient="horizontal")

    for key, (prop_type, prop_name) in PROP_TYPES.items():
        labels[key] = ttk.Label(win, text=prop_name+':')
        if prop_type == 'checkbox':
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = utils.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                win,
                variable=values[key],
                command=func_partial(set_check, key),
                )
            widgets[key].bind(
                '<Return>',
                func_partial(
                    toggleCheck,
                    key,
                    values[key],
                    )
                )

        elif prop_type == 'railLift':
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = utils.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                win,
                variable=values[key],
                command=func_partial(save_rail, key),
                )

        elif prop_type == 'panAngle':
            frm = ttk.Frame(win)
            widgets[key] = frm
            values[key] = StringVar(value=DEFAULTS[key])
            for pos, angle in enumerate(['30', '45', '60', '90']):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=angle,
                    text=angle,
                    command=func_partial(save_angle, key, angle),
                    ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)

        elif prop_type == 'gelType':
            frm = ttk.Frame(win)
            widgets[key] = frm
            values[key] = IntVar(value=DEFAULTS[key])
            for pos, text in enumerate(PAINT_OPTS):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=pos,
                    text=text,
                    command=func_partial(save_paint, key, pos),
                    ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)
            out_values[key] = str(DEFAULTS[key])

        elif prop_type == 'pistPlat':
            widgets[key] = Scale(
                win,
                from_=0,
                to=4,
                orient="horizontal",
                showvalue=False,
                command=func_partial(save_pist, key),
                )
            values[key] = DEFAULTS[key]
            out_values[key] = str(DEFAULTS[key])
            if ((key == 'toplevel' and DEFAULTS['startup']) or
                    (key == 'bottomlevel' and not DEFAULTS['startup'])):
                widgets[key].set(max(
                    DEFAULTS['toplevel'],
                    DEFAULTS['bottomlevel']
                    ))
            if ((key == 'toplevel' and not DEFAULTS['startup']) or
                    (key == 'bottomlevel' and DEFAULTS['startup'])):
                widgets[key].set(min(
                    DEFAULTS['toplevel'],
                    DEFAULTS['bottomlevel']))

        elif prop_type == 'timerDel':
            widgets[key] = ttk.Scale(
                win,
                from_=0,
                to=30,
                orient="horizontal",
                command=func_partial(save_tim, key),
                )
            values[key] = DEFAULTS[key]

        elif prop_type == 'railPlat':
            widgets[key] = ttk.Checkbutton(win)
    values['startup'] = DEFAULTS['startup']
Esempio n. 7
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())
Esempio n. 8
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)
Esempio n. 9
0
def init(cback):
    global callback, labels, win, is_open
    callback = cback
    is_open = False
    win = Toplevel(TK_ROOT)
    win.title("BEE2")
    win.resizable(False, False)
    tk_tools.set_window_icon(win)
    win.protocol("WM_DELETE_WINDOW", exit_win)
    win.transient(TK_ROOT)
    win.withdraw()

    if utils.MAC:
        # Switch to use the 'modal' window style on Mac.
        TK_ROOT.call(
            '::tk::unsupported::MacWindowStyle',
            'style',
            win,
            'moveableModal',
            ''
        )

    frame = ttk.Frame(win, padding=10)
    frame.grid(row=0, column=0, sticky='NSEW')
    frame.rowconfigure(0, weight=1)
    frame.columnconfigure(0, weight=1)

    labels['noOptions'] = ttk.Label(frame, text=_('No Properties available!'))
    widgets['saveButton'] = ttk.Button(frame, text=_('Close'), command=exit_win)
    widgets['titleLabel'] = ttk.Label(frame, text='')
    widgets['titleLabel'].grid(columnspan=9)

    widgets['div_1'] = ttk.Separator(frame, orient="vertical")
    widgets['div_2'] = ttk.Separator(frame, orient="vertical")
    widgets['div_h'] = ttk.Separator(frame, orient="horizontal")

    for key, (prop_type, prop_name) in PROP_TYPES.items():
        # Translate property names from Valve's files.
        if prop_name.startswith('PORTAL2_'):
            prop_name = gameMan.translate(prop_name) + ':'

        labels[key] = ttk.Label(frame, text=prop_name)
        if prop_type is PropTypes.CHECKBOX:
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = srctools.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                frame,
                variable=values[key],
                command=func_partial(set_check, key),
                )
            widgets[key].bind(
                '<Return>',
                func_partial(
                    toggleCheck,
                    key,
                    values[key],
                    )
                )

        elif prop_type is PropTypes.OSCILLATE:
            values[key] = IntVar(value=DEFAULTS[key])
            out_values[key] = srctools.bool_as_int(DEFAULTS[key])
            widgets[key] = ttk.Checkbutton(
                frame,
                variable=values[key],
                command=func_partial(save_rail, key),
                )

        elif prop_type is PropTypes.PANEL:
            frm = ttk.Frame(frame)
            widgets[key] = frm
            values[key] = StringVar(value=DEFAULTS[key])
            for pos, (angle, disp_angle) in enumerate(PANEL_ANGLES):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=angle,
                    text=gameMan.translate(disp_angle),
                    command=func_partial(save_angle, key, angle),
                    ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)

        elif prop_type is PropTypes.GELS:
            frm = ttk.Frame(frame)
            widgets[key] = frm
            values[key] = IntVar(value=DEFAULTS[key])
            for pos, text in enumerate(PAINT_OPTS):
                ttk.Radiobutton(
                    frm,
                    variable=values[key],
                    value=pos,
                    text=gameMan.translate(text),
                    command=func_partial(save_paint, key, pos),
                    ).grid(row=0, column=pos)
                frm.columnconfigure(pos, weight=1)
            out_values[key] = str(DEFAULTS[key])

        elif prop_type is PropTypes.PISTON:
            widgets[key] = Scale(
                frame,
                from_=0,
                to=4,
                orient="horizontal",
                showvalue=False,
                command=func_partial(save_pist, key),
                )
            values[key] = DEFAULTS[key]
            out_values[key] = str(DEFAULTS[key])
            if ((key == 'toplevel' and DEFAULTS['startup']) or
                    (key == 'bottomlevel' and not DEFAULTS['startup'])):
                widgets[key].set(max(
                    DEFAULTS['toplevel'],
                    DEFAULTS['bottomlevel']
                    ))
            if ((key == 'toplevel' and not DEFAULTS['startup']) or
                    (key == 'bottomlevel' and DEFAULTS['startup'])):
                widgets[key].set(min(
                    DEFAULTS['toplevel'],
                    DEFAULTS['bottomlevel']))

        elif prop_type is PropTypes.TIMER:
            widgets[key] = ttk.Scale(
                frame,
                from_=0,
                to=30,
                orient="horizontal",
                command=func_partial(save_tim, key),
                )
            values[key] = DEFAULTS[key]

    values['startup'] = DEFAULTS['startup']
Esempio n. 10
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)
Esempio n. 11
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)