code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

"""supports globs in sourceFile arguments"""

import filecmp
import fileinput
import glob
# Standart Python Modules
import os
import re
import sys

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
from inary.util import remove_prefix, uncompress

# ActionsAPI Modules
import inary.actionsapi
import inary.actionsapi.get as get
from inary.actionsapi.shelltools import *

from inary.actionsapi import error

# Error Classes
class FileError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[InaryTools]: " + value)

class ArgumentError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[InaryTools]: " + value)

# Tool functions
def executable_insinto(destinationDirectory, *sourceFiles):
    """insert a executable file into destinationDirectory"""

    if not sourceFiles or not destinationDirectory:
        raise ArgumentError(_('Insufficient arguments.'))

    if not can_access_directory(destinationDirectory):
        makedirs(destinationDirectory)

    for sourceFile in sourceFiles:
        sourceFileGlob = glob.glob(sourceFile)
        if len(sourceFileGlob) == 0:
            raise FileError(_("No executable file matched pattern \"{}\".").format(sourceFile))

        for source in sourceFileGlob:
            # FIXME: use an internal install routine for these
            system('install -m 0755 -o root -g root {0} {1}'.format(source, destinationDirectory))

def readable_insinto(destinationDirectory, *sourceFiles):
    """inserts file list into destinationDirectory"""

    if not sourceFiles or not destinationDirectory:
        raise ArgumentError(_('Insufficient arguments.'))

    if not can_access_directory(destinationDirectory):
        makedirs(destinationDirectory)

    for sourceFile in sourceFiles:
        sourceFileGlob = glob.glob(sourceFile)
        if len(sourceFileGlob) == 0:
            raise FileError(_("No file matched pattern \"{}\".").format(sourceFile))

        for source in sourceFileGlob:
            system('install -m 0644 "{0}" {1}'.format(source, destinationDirectory))

def lib_insinto(sourceFile, destinationDirectory, permission=644):
    """inserts a library fileinto destinationDirectory with given permission"""

    if not sourceFile or not destinationDirectory:
        raise ArgumentError(_('Insufficient arguments.'))

    if not can_access_directory(destinationDirectory):
        makedirs(destinationDirectory)

    if os.path.islink(sourceFile):
        os.symlink(os.path.realpath(sourceFile), os.path.join(destinationDirectory, sourceFile))
    else:
        system('install -m 0{0} {1} {2}'.format(permission, sourceFile, destinationDirectory))

# inarytools funtions
def dobin(sourceFile, destinationDirectory='/usr/bin'):
    """insert a executable file into /bin or /usr/bin"""
    ''' example call: inarytools.dobin("bin/xloadimage", "/bin", "xload") '''
    executable_insinto(join_path(get.installDIR(), destinationDirectory), sourceFile)

def dopixmaps(sourceFile, destinationDirectory='/usr/share/pixmaps'):
    """insert a data file into /usr/share/pixmaps"""
    ''' example call: inarytools.dopixmaps("/usr/share/pixmaps/firefox", "firefox") '''
    readable_insinto(join_path(get.installDIR(), destinationDirectory), sourceFile)

def dodir(destinationDirectory):
    """creates a directory tree"""
    makedirs(join_path(get.installDIR(), destinationDirectory))

def dodoc(*sourceFiles, **kw):
    """inserts the files in the list of files into /usr/share/doc/PACKAGE"""
    destDir = kw.get("destDir", get.srcNAME())
    readable_insinto(join_path(get.installDIR(), get.docDIR(), destDir), *sourceFiles)

def dohtml(*sourceFiles, **kw):
    """inserts the files in the list of files into /usr/share/doc/PACKAGE/html"""

    ''' example call: inarytools.dohtml("doc/doxygen/html/*")'''
    destDir = kw.get("destDir", get.srcNAME())
    destionationDirectory = join_path(get.installDIR(), get.docDIR(), destDir, 'html')

    if not can_access_directory(destionationDirectory):
        makedirs(destionationDirectory)

    allowed_extensions = ['.png', '.gif', '.html', '.htm', '.jpg', '.css', '.js']
    disallowed_directories = ['CVS', '.git', '.svn', '.hg']

    for sourceFile in sourceFiles:
        sourceFileGlob = glob.glob(sourceFile)
        if len(sourceFileGlob) == 0:
            raise FileError(_("No file matched pattern \"{}\".").format(sourceFile))

        for source in sourceFileGlob:
            if os.path.isfile(source) and os.path.splitext(source)[1] in allowed_extensions:
                system('install -m 0644 "{0}" {1}'.format(source, destionationDirectory))
            if os.path.isdir(source) and os.path.basename(source) not in disallowed_directories:
                eraser = os.path.split(source)[0]
                for root, dirs, files in os.walk(source):
                    newRoot = remove_prefix(eraser, root)
                    for sourcename in files:
                        if os.path.splitext(sourcename)[1] in allowed_extensions:
                            makedirs(join_path(destionationDirectory, newRoot))
                            system('install -m 0644 {0} {1}'.format(join_path(root, sourcename),
                                                                    join_path(destionationDirectory, newRoot,
                                                                              sourcename)))

def doinfo(*sourceFiles):
    """inserts the into files in the list of files into /usr/share/info"""
    readable_insinto(join_path(get.installDIR(), get.infoDIR()), *sourceFiles)

def dolib(sourceFile, destinationDirectory='/usr/lib', mode=755):
    """insert the library into /usr/lib"""
    '''example call: inarytools.dolib("libz.a")'''
    '''example call: inarytools.dolib("libz.so")'''
    if mode == 755 and sourceFile.endswith('.a'):
        mode = 644
    sourceFile = join_path(os.getcwd(), sourceFile)
    destinationDirectory = join_path(get.installDIR(), destinationDirectory)

    lib_insinto(sourceFile, destinationDirectory, mode)

def doman(*sourceFiles, pageDirectory=None):
    """inserts the man pages in the list of files into /usr/share/man/"""

    '''example call: inarytools.doman("man.1", "sulin.*")'''
    manDIR = join_path(get.installDIR(), get.manDIR())
    if not can_access_directory(manDIR):
        makedirs(manDIR)

    for sourceFile in sourceFiles:
        sourceFileGlob = glob.glob(sourceFile)
        if len(sourceFileGlob) == 0:
            raise FileError(_("No file matched pattern \"{}\"").format(sourceFile))

        for source in sourceFileGlob:
            compressed = source.endswith("gz") and source
            if compressed:
                source = source[:-3]
            try:
                if not pageDirectory:
                    pageName, pageDirectory = source[:source.rindex('.')], \
                                              source[source.rindex('.') + 1:]
            except ValueError:
                error(_('ActionsAPI [doman]: Wrong man page file: \"{}\"').format(source))

            manPDIR = join_path(manDIR, '/man{}'.format(pageDirectory))
            makedirs(manPDIR)
            if not compressed:
                system('install -m 0644 {0} {1}'.format(source, manPDIR))
            else:
                uncompress(compressed, targetDir=manPDIR)

def domo(sourceFile, locale, destinationFile, localeDirPrefix='/usr/share/locale'):
    """inserts the mo files in the list of files into /usr/share/locale/LOCALE/LC_MESSAGES"""

    '''example call: inarytools.domo("po/tr.po", "tr", "pam_login.mo")'''

    system('msgfmt {}'.format(sourceFile))
    makedirs('{0}{1}/{2}/LC_MESSAGES/'.format(get.installDIR(), localeDirPrefix, locale))
    move('messages.mo', '{0}{1}/{2}/LC_MESSAGES/{3}'.format(get.installDIR(), localeDirPrefix, locale, destinationFile))

def domove(sourceFile, destination, destinationFile=''):
    """moves sourceFile/Directory into destinationFile/Directory"""

    ''' example call: inarytools.domove("/usr/bin/bash", "/bin/bash")'''
    ''' example call: inarytools.domove("/usr/bin/", "/usr/sbin")'''
    makedirs(join_path(get.installDIR(), destination))

    sourceFileGlob = glob.glob(join_path(get.installDIR(), sourceFile))
    if len(sourceFileGlob) == 0:
        raise FileError(_("No file matched pattern \"{}\". 'domove' operation failed.").format(sourceFile))

    for filePath in sourceFileGlob:
        if not destinationFile:
            move(filePath, join_path(get.installDIR(), join_path(destination, os.path.basename(filePath))))
        else:
            move(filePath, join_path(get.installDIR(), join_path(destination, destinationFile)))

def rename(sourceFile, destinationFile):
    """ renames sourceFile as destinationFile"""

    ''' example call: inarytools.rename("/usr/bin/bash", "bash.old") '''
    ''' the result of the previous example would be "/usr/bin/bash.old" '''

    baseDir = os.path.dirname(sourceFile)

    try:
        os.rename(join_path(get.installDIR(), sourceFile), join_path(get.installDIR(), baseDir, destinationFile))
    except OSError as e:
        error(_('ActionsAPI [rename]: \"{0}\": \"{1}\"').format(e, sourceFile))

def dosed(sources, findPattern, replacePattern='', filePattern='', deleteLine=False, level=-1):
    """replaces patterns in sources"""

    ''' example call: inarytools.dosed("/etc/passwd", "caglar", "cem")'''
    ''' example call: inarytools.dosed("/etc/passwd", "caglar")'''
    ''' example call: inarytools.dosed("/etc/pass*", "caglar")'''
    ''' example call: inarytools.dosed("Makefile", "(?m)^(HAVE_PAM=.*)no", r"\1yes")'''
    ''' example call: inarytools.dosed("./", "^(CFLAGS) =", r"\1 +=", "Makefile", level = 1)
        will change: ./Makefile and ./*/Makefile'''
    ''' example call: inarytools.dosed("./", "^\s*g_type_init\(\)", filePattern = ".*.c", deleteLine = True)
        will change: delete lines which contains "g_type_init()" for all *.c files in ./ directory tree'''

    def get_files(path, pattern, level):
        res = []
        if path.endswith("/"): path = path[:-1]
        for root, dirs, files in os.walk(path):
            currentLevel = len(root.split("/")) - len(path.split("/"))
            if not level == -1 and currentLevel > level: continue
            for f in files:
                if re.search(pattern, f):
                    res.append("{0}/{1}".format(root, f))
        return res

    backupExtension = ".inary-backup"
    sourceFiles = []
    sourcesGlob = glob.glob(sources)

    for source in sourcesGlob:
        if os.path.isdir(source):
            sourceFiles.extend(get_files(source, filePattern, level))
        else:
            sourceFiles.append(source)

    # if there is no match, raise exception
    if len(sourceFiles) == 0:
        raise FileError(_('No such file matching pattern: \"{}\". \'dosed\' operation failed.').format(
            filePattern if filePattern else sources))

    for sourceFile in sourceFiles:
        if can_access_file(sourceFile):
            backupFile = "{0}{1}".format(sourceFile, backupExtension)
            for line in fileinput.input(sourceFile, inplace=1, backup=backupExtension):
                # FIXME: In-place filtering is disabled when standard input is read
                if re.search(findPattern, line):
                    line = "" if deleteLine else re.sub(findPattern, replacePattern, line)
                sys.stdout.write(line)
            if can_access_file(backupFile):
                # By default, filecmp.cmp() compares two files by looking file sizes.
                # shallow=False tells cmp() to look file content.
                if filecmp.cmp(sourceFile, backupFile, shallow=False):
                    ctx.ui.warning(_('dosed method has not changed file \"{}\".').format(sourceFile))
                else:
                    ctx.ui.info(_("\"{}\" has been changed by dosed method.").format(sourceFile), verbose=True)
                os.unlink(backupFile)
        else:
            raise FileError(_('File does not exist or permission denied: \"{}\"').format(sourceFile))

def dosbin(sourceFile, destinationDirectory='/usr/sbin'):
    """insert a executable file into /sbin or /usr/sbin"""

    ''' example call: inarytools.dobin("bin/xloadimage", "/sbin") '''
    executable_insinto(join_path(get.installDIR(), destinationDirectory), sourceFile)

def dosym(sourceFile, destinationFile):
    """creates soft link between sourceFile and destinationFile"""

    ''' example call: inarytools.dosym("/usr/bin/bash", "/bin/bash")'''
    makedirs(join_path(get.installDIR(), os.path.dirname(destinationFile)))

    try:
        os.symlink(sourceFile, join_path(get.installDIR(), destinationFile))
    except OSError:
        error(_('ActionsAPI [dosym]: File already exists: \"{}\"').format(destinationFile))

def insinto(destinationDirectory, sourceFile, destinationFile='', sym=True):
    """insert a sourceFile into destinationDirectory as a destinationFile with same uid/guid/permissions"""
    makedirs(join_path(get.installDIR(), destinationDirectory))

    if not destinationFile:
        sourceFileGlob = glob.glob(sourceFile)
        if len(sourceFileGlob) == 0:
            raise FileError(_("No file matched pattern \"{}\".").format(sourceFile))

        for filePath in sourceFileGlob:
            if can_access_file(filePath):
                copy(filePath, join_path(get.installDIR(), join_path(destinationDirectory, os.path.basename(filePath))),
                     sym)
    else:
        copy(sourceFile, join_path(get.installDIR(), join_path(destinationDirectory, destinationFile)), sym)

def newdoc(sourceFile, destinationFile):
    """inserts a sourceFile into /usr/share/doc/PACKAGE/ directory as a destinationFile"""
    destinationDirectory = os.path.dirname(destinationFile)
    destinationFile = os.path.basename(destinationFile)
    # Use copy instead of move or let build-install scream like file not found!
    copy(sourceFile, destinationFile)
    readable_insinto(join_path(get.installDIR(), 'usr/share/doc', get.srcNAME(), destinationDirectory), destinationFile)

def newman(sourceFile, destinationFile):
    """inserts a sourceFile into /usr/share/man/manPREFIX/ directory as a destinationFile"""
    # Use copy instead of move or let build-install scream like file not found!
    copy(sourceFile, destinationFile)
    doman(destinationFile)

def remove(sourceFile):
    """removes sourceFile"""
    sourceFileGlob = glob.glob(join_path(get.installDIR(), sourceFile))
    if len(sourceFileGlob) == 0:
        raise FileError(_("No file matched pattern \"{}\". Remove operation failed.").format(sourceFile))

    for filePath in sourceFileGlob:
        unlink(filePath)

def removeDir(destinationDirectory):
    """removes destinationDirectory and its subtrees"""
    destdirGlob = glob.glob(join_path(get.installDIR(), destinationDirectory))
    if len(destdirGlob) == 0:
        raise FileError(
            _("No directory matched pattern \"{}\". Remove directory operation failed.").format(destinationDirectory))

    for directory in destdirGlob:
        unlinkDir(directory)

class Flags:
    def __init__(self, *evars):
        self.evars = evars

    def add(self, *flags):
        for evar in self.evars:
            os.environ[evar] = " ".join(os.environ[evar].split() + [f.strip() for f in flags])

    def remove(self, *flags):
        for evar in self.evars:
            os.environ[evar] = " ".join([v for v in os.environ[evar].split() if v not in [f.strip() for f in flags]])

    def replace(self, old_val, new_val):
        for evar in self.evars:
            os.environ[evar] = " ".join([new_val if v == old_val else v for v in os.environ[evar].split()])

    def sub(self, pattern, repl, count=0, flags=0):
        for evar in self.evars:
            os.environ[evar] = re.sub(pattern, repl, os.environ[evar], count, flags)

    def reset(self):
        for evar in self.evars:
            os.environ[evar] = ""

cflags = Flags("CFLAGS")
ldflags = Flags("LDFLAGS")
cxxflags = Flags("CXXFLAGS")
flags = Flags("CFLAGS", "CXXFLAGS")


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# Standard Python Modules
import os
from glob import glob
from shutil import copy, copytree

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
import inary.util as util
import inary.context as ctx

# ActionsAPI Modules
import inary.actionsapi
from inary.actionsapi import get
from inary.actionsapi.shelltools import system, export

# java -Xmx256M -jar x.jar --key=val
EXEC_TEMPLATE = """\
#!/bin/sh

cd {0}
java{1}-jar {2}{3}
"""

class CompileError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[JavaTools]: " + value)

class InstallError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[JavaTools]: " + value)

class RunTimeError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[JavaTools]: " + value)

class DoJavadocError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[JavaTools]: " + value)

####################
# Internal helpers #
####################

def _dodoc(*source_files, **kw):
    """copy doc files to /usr/share/doc/src_name recursively"""

    dest = util.join_path(get.docDIR(), kw.get('dest_dir', get.srcNAME()))
    destination = util.join_path(get.installDIR(), dest)

    if not os.access(destination, os.F_OK):
        os.makedirs(destination)

    for source_file in source_files:
        sources = glob(source_file)
        if not sources:
            raise DoJavadocError(_('No any file/directory matched to regex expression "{}".'.format(source_file)))

        for source in sources:
            if os.path.isfile(source):
                try:
                    copy(source, destination)
                except IOError:
                    raise DoJavadocError(_('DoJavadoc failed.'))
            elif os.path.isdir(source):
                target = util.join_path(destination, source.split("/")[-1])
                try:
                    copytree(source, target)
                except IOError:
                    raise DoJavadocError(_('DoJavadoc failed.'))

def _generate_classpath_file(classpath):
    """write classpath to environment file"""

    env_dir = util.join_path(get.installDIR(), '/etc/env.d')
    if not os.access(env_dir, os.F_OK):
        os.makedirs(env_dir)

    env_file = util.join_path(env_dir, get.srcNAME())
    if not os.access(env_file, os.F_OK):
        prefix = 'CLASSPATH='
    else:
        prefix = ':'

    cp_file = open(env_file, 'a')
    cp_file.write('{0}{1}'.format(prefix, ':'.join(classpath)))
    cp_file.close()

def _generate_exec_file(dest_dir, exe, java_args, exe_args):
    """generate executable file for executable jar"""

    exec_dir = util.join_path(get.installDIR(), '/usr/bin')
    if not os.access(exec_dir, os.F_OK):
        os.makedirs(exec_dir)

    # Using low level I/O to set permission without calling os.chmod
    exec_file = os.open(util.join_path(exec_dir, get.srcNAME()),
                        os.O_CREAT | os.O_WRONLY,
                        0o755)
    os.write(exec_file, EXEC_TEMPLATE.format(util.join_path('/', dest_dir),
                                             java_args,
                                             exe,
                                             exe_args))
    os.close(exec_file)

#############################
# Building and installation #
#############################

def compile(argument='', parameters='', build_tool='ant'):
    """compile source with given build tool and related parameters"""

    try:
        run(argument, parameters, build_tool)
    except RunTimeError:
        raise CompileError(_('Compile failed.'))

def installExe(exe='', java_args='', exe_args='', dest_dir=''):
    """install executable jar to specified location and get jar prepared to
    execute with given arguments.

    exe:        Path in work dir to executable jar
    java_args:  Arguments passed to jvm
    exe_args:   Arguments passed to executable jar
    dest_dir:   Installation dir of executable jar"""

    if not dest_dir:
        dest_dir = 'usr/share/java/{}'.format(get.srcNAME())
    destination = util.join_path(get.installDIR(), dest_dir)

    if not os.access(destination, os.F_OK):
        os.makedirs(destination)

    # To guarantee x/y.jar going under /usr/share/java as y.jar
    source = exe.split("/")[-1]
    try:
        copy(exe, destination)
        _generate_exec_file(dest_dir,
                            source,
                            ' {} '.format(java_args) if java_args else ' ',
                            ' {}'.format(exe_args) if exe_args else '')
    except IOError:
        raise InstallError(_('Installing file "{}" failed.'.format(exe)))

def installLib(src='*.jar', dest='/usr/share/java'):
    """install compilation output that is mix of the utility classes as
    in jars or meta/data files to specified locations.

    src:    Source file pattern to be installed
    dest:   Destination dir where the source files to be installed
    """

    classpath = []

    destination = util.join_path(get.installDIR(), dest)
    sources = glob(src)

    # If no source matched, then no need to create destination dir
    if not sources:
        raise InstallError(_('No any file/directory matched '
                             'to regex expression "{}".'.format(src)))

    if not os.access(destination, os.F_OK):
        os.makedirs(destination)

    for source in sources:
        if os.path.isfile(source):
            try:
                copy(source, destination)
            except IOError:
                raise InstallError(_('Installing file "{}" failed.'.format(source)))
            if source.endswith('.jar'):
                classpath.append(util.join_path('/',
                                                dest,
                                                source.split('/')[-1]))
        elif os.path.isdir(source):
            target = util.join_path(destination, source.split('/')[-1])
            try:
                copytree(source, target)
            except IOError:
                raise InstallError(_('Installing directory "{}" failed.'.format(source)))
            for root, dirs, files in os.walk(target):
                for f in files:
                    if f.endswith('.jar'):
                        # Exclude sandbox dir from jar path
                        jar = util.remove_prefix(get.installDIR(),
                                                 util.join_path(root, f))
                        classpath.append(jar)

    if classpath:
        _generate_classpath_file(classpath)

######################
# Javadoc generation #
######################

def dojavadoc(*source_files, **kw):
    """generate & copy javadoc files to /usr/share/doc/src_name recursively"""

    build_tool = kw.get('build_tool', 'ant')
    parameters = kw.get('parameters', '')
    argument = kw.get('argument', 'javadoc')

    try:
        run(argument, parameters, build_tool)
        _dodoc(*source_files, **kw)
    except (RunTimeError, DoJavadocError):
        raise DoJavadocError(_('Javadoc generation failed.'))

#####################
# Generic execution #
#####################

def run(argument='', parameters='', build_tool='ant'):
    """run build tool with given parameters"""

    export('JAVA_HOME', '/opt/sun-jre')
    # Otherwise, javadoc might be completed with errors
    export('LC_ALL', 'en_US.UTF-8')

    if system('{0} {1} {2}'.format(build_tool, parameters, argument)):
        raise RunTimeError(_('Run failed.'))

repo_name: SulinOS/inary

license: mit


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

from inary.actionsapi import cmaketools
# ActionsAPI Modules
from inary.actionsapi import get
from inary.actionsapi import shelltools

basename = "kde5"

prefix = "/{}".format(get.defaultprefixDIR())
libdir = "{}/lib".format(prefix)
bindir = "{}/bin".format(prefix)
libexecdir = "{}/lib".format(prefix)
iconsdir = "{}/share/icons".format(prefix)
applicationsdir = "{0}/share/applications/{1}".format(prefix, basename)
mandir = "/{}".format(get.manDIR())
sharedir = "{}/share".format(prefix)
localedir = "{}/share/locale".format(prefix)
qmldir = "{}/lib/qt5/qml".format(prefix)
plugindir = "{}/lib/qt5/plugins".format(prefix)
moduledir = "{}/lib/qt5/mkspecs/modules".format(prefix)
pythondir = "{}/bin/python".format(prefix)
appsdir = "{}".format(sharedir)
sysconfdir = "/etc"
configdir = "{}/xdg".format(sysconfdir)
servicesdir = "{}/services".format(sharedir)
servicetypesdir = "{}/servicetypes".format(sharedir)
includedir = "{}/include".format(prefix)
docdir = "/{0}/{1}".format(get.docDIR(), basename)
htmldir = "{}/html".format(docdir)
wallpapersdir = "{}/share/wallpapers".format(prefix)

def configure(parameters='', installPrefix=prefix, sourceDir='..'):
    """ parameters -DLIB_INSTALL_DIR="hede" -DSOMETHING_USEFUL=1"""

    shelltools.makedirs("build")
    shelltools.cd("build")

    cmaketools.configure("-DCMAKE_BUILD_TYPE=Release \
                          -DKDE_INSTALL_LIBEXECDIR={0} \
                          -DCMAKE_INSTALL_LIBDIR=lib \
                          -DKDE_INSTALL_USE_QT_SYS_PATHS=ON \
                          -DKDE_INSTALL_QMLDIR={1} \
                          -DKDE_INSTALL_SYSCONFDIR={2} \
                          -DKDE_INSTALL_PLUGINDIR={3} \
                          -DECM_MKSPECS_INSTALL_DIR={4} \
                          -DBUILD_TESTING=OFF \
                          -DKDE_INSTALL_LIBDIR=lib \
                          -Wno-dev \
                          -DCMAKE_INSTALL_PREFIX={5} \
                         {6}".format(libexecdir, qmldir, sysconfdir, plugindir, moduledir, prefix, parameters),
                         installPrefix, sourceDir)

    shelltools.cd("..")

def make(parameters=''):
    cmaketools.make('-C build {}'.format(parameters))

def install(parameters='', argument='install'):
    cmaketools.install('-C build {}'.format(parameters), argument)


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# Standard Python Modules
import os
import re
import shutil

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
import inary.context as ctx

# ActionsAPI Modules
import inary.actionsapi
import inary.actionsapi.get          as get
import inary.actionsapi.autotools    as autotools
import inary.actionsapi.inarytools   as inarytools
import inary.actionsapi.shelltools   as shelltools

class ConfigureError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[KernelTools]" + value)

# Internal helpers

def __getAllSupportedFlavours():
    if os.path.exists("/etc/kernel"):
        return os.listdir("/etc/kernel")

#################
# Other helpers #
#################

def __getFlavour():
    try:
        flavour = get.srcNAME().split("linux-")[1]
    except IndexError:
        return ""
    else:
        return flavour

def __getModuleFlavour():
    for fl in [_f for _f in __getAllSupportedFlavours() if "-" in _f]:
        try:
            if fl.split("-")[1] == get.srcNAME().split("-")[1]:
                return fl
        except IndexError:
            # the package is not a module, may be a userspace application
            # needing the kernel sources/headers for only reference.
            pass

    return "linux"

def __getKernelARCH():
    """i386 is relevant for our i686 architecture."""
    return get.ARCH()

def __getSuffix():
    """Read and return the value read from .suffix file."""
    suffix = get.srcVERSION()
    if __getFlavour():
        suffix += "-{}".format(__getFlavour())
    return suffix

def __getExtraVersion():
    extraversion = ""
    try:
        # if successful, this is something like:
        # .1 for 2.6.30.1
        # _rc8 for 2.6.30_rc8
        extraversion = re.split("5.[0-9].[0-9]{2}([._].*)", get.srcVERSION())[1]
    except IndexError:
        # e.g. if version == 2.6.30
        pass

    # Append pae, default, rt, etc. to the extraversion if available
    if __getFlavour():
        extraversion += "-{}".format(__getFlavour())

    return extraversion

#######################
# Configuration stuff #
#######################

def getKernelVersion(flavour=None):
    # Returns the KVER information to use with external module compilation
    # This is something like 2.6.30_rc7-119 which will be appended to /lib/modules.
    # if flavour==None, it will return the KVER in the /etc/kernel/kernel file else,
    # /etc/kernel/<flavour>.
    # If it fails, it will return the running kernel version.

    # Try to detect module flavour
    if not flavour:
        flavour = __getModuleFlavour()

    kverfile = os.path.join("/etc/kernel", flavour)

    if os.path.exists(kverfile):
        return open(kverfile).read().strip()
    else:
        # Fail
        raise ConfigureError(_("Can't find kernel version information file \"{}\".").format(kverfile))

def configure():
    # Copy the relevant configuration file

    # Set EXTRAVERSION

    inarytools.dosed("Makefile", "EXTRAVERSION =.*", "EXTRAVERSION = {}".format(__getExtraVersion()))
    # Configure the kernel interactively if
    # configuration contains new options
    autotools.make("ARCH={} oldconfig".format(__getKernelARCH()))

    # Check configuration with listnewconfig
    try:
        autotools.make("ARCH={} listnewconfig".format(__getKernelARCH()))
    except:
        pass

###################################
# Building and installation stuff #
###################################

def dumpVersion():
    # Writes the specific kernel version into /etc/kernel
    destination = os.path.join(get.installDIR(), "etc/kernel/")
    if not os.path.exists(destination):
        os.makedirs(destination)

    open(os.path.join(destination, get.srcNAME()), "w").write(__getSuffix())

def build(debugSymbols=False):
    extra_config = []
    if debugSymbols:
        # Enable debugging symbols (-g -gdwarf2)
        extra_config.append("CONFIG_DEBUG_INFO=y")

    autotools.make("ARCH={0} {1}".format(__getKernelARCH(), " ".join(extra_config)))

def install():
    suffix = __getSuffix()

    # Dump kernel version under /etc/kernel
    dumpVersion()

    # Install kernel image
    inarytools.insinto("/boot/", "arch/x86/boot/bzImage", "linux-{}".format(suffix))

    # Install the modules
    # mod-fw= avoids firmwares from installing
    # Override DEPMOD= to not call depmod as it will be called
    # during module-init-tools' package handler
    autotools.rawInstall("INSTALL_MOD_PATH={}/".format(get.installDIR()),
                         "DEPMOD=/bin/true modules_install mod-fw=")

    # Remove symlinks first
    inarytools.remove("/lib/modules/{}-sulinos/source".format(suffix))
    inarytools.remove("/lib/modules/{}-sulinos/build".format(suffix))

    # Install Module.symvers and System.map here too
    shutil.copy("Module.symvers", "{0}/lib/modules/{1}-sulinos/".format(get.installDIR(), suffix))
    shutil.copy("System.map", "{0}/lib/modules/{1}-sulinos/".format(get.installDIR(), suffix))

    # Create extra/ and updates/ subdirectories
    for _dir in ("extra", "updates"):
        inarytools.dodir("/lib/modules/{0}-sulinos/{1}".format(suffix, _dir))

def installHeaders(extraHeaders=None):
    """ Install the files needed to build out-of-tree kernel modules. """
    extras = ["drivers/md/",
              "net/mac80211",
              "drivers/media/i2c/",
              "drivers/media/usb/dvb-usb",
              "drivers/media/dvb-frontends",
              "drivers/media/tuners",
              "drivers/media/platform"]

    if extraHeaders:
        extras.extend(extraHeaders)

    pruned = ["include", "scripts", "Documentation"]
    wanted = ["Makefile*", "Kconfig*", "Kbuild*", "*.sh", "*.pl", "*.lds"]

    suffix = __getSuffix()
    headersDirectoryName = "usr/src/linux-headers-{}-sulinos".format(suffix)

    # Get the destination directory for header installation
    destination = os.path.join(get.installDIR(), headersDirectoryName)
    shelltools.makedirs(destination)

    # First create the skel
    find_cmd = "find . -path {0} -prune -o -type f \( -name {1} \) -print".format(
        " -prune -o -path ".join(["'./{}/*'".format(l for l in pruned)]),
        " -o -name ".join(["'{}'".format(k for k in wanted)])
    ) + " | cpio -pVd --preserve-modification-time {}".format(destination)

    shelltools.system(find_cmd)

    shelltools.system("pwd")
    # Install additional headers
    for headers in extras:
        if not os.path.exists("{0}/{1}".format(destination, headers)):
            shelltools.system("mkdir -p {0}/{1}".format(destination, headers))
        shelltools.system("pwd")
        shelltools.system("cp -a {0}/*.h {1}/{2}".format(headers, destination, headers))
    # Install remaining headers
    shelltools.system("cp -a {0} {1}".format(" ".join(pruned), destination))

    # Cleanup directories
    shelltools.system("rm -rf {}/scripts/*.o".format(destination))
    shelltools.system("rm -rf {}/scripts/*/*.o".format(destination))
    shelltools.system("rm -rf {}/Documentation/DocBook".format(destination))

    # Finally copy the include directories found in arch/
    shelltools.system("(find arch -name include -type d -print | \
                        xargs -n1 -i: find : -type f) | \
                        cpio -pd --preserve-modification-time {}".format(destination))

    # Copy Modules.symvers and System.map
    shutil.copy("Module.symvers", "{}/".format(destination))
    shutil.copy("System.map", "{}/".format(destination))
    shutil.copy("Kbuild", "{}/".format(destination))
    shutil.copy("Kconfig", "{}/".format(destination))
    shutil.copy("Makefile", "{}/".format(destination))

    # Copy .config file which will be needed by some external modules
    shutil.copy(".config", "{}/".format(destination))

    # Settle the correct build symlink to this headers
    inarytools.dosym("/{}".format(headersDirectoryName), "/lib/modules/{}-sulinos/build".format(suffix))
    inarytools.dosym("build", "/lib/modules/{}-sulinos/source".format(suffix))

def installLibcHeaders(excludes=None):
    headers_tmp = os.path.join(get.installDIR(), 'tmp-headers')
    headers_dir = os.path.join(get.installDIR(), 'usr/include')

    make_cmd = "O={0} INSTALL_HDR_PATH={0}/install".format(headers_tmp)

    # Cleanup temporary header directory
    shelltools.system("rm -rf {}".format(headers_tmp))

    # Create directories
    shelltools.makedirs(headers_tmp)
    shelltools.makedirs(headers_dir)

    ###################Workaround begins here ...
    # Workaround information -- http://patches.openembedded.org/patch/33433/
    cpy_src = "{}/linux-*/arch/x86/include/generated".format(get.workDIR())
    cpy_tgt = "{}/arch/x86/include".format(headers_tmp)
    shelltools.makedirs(cpy_tgt)

    copy_cmd = "cp -Rv {0} {1} ".format(cpy_src, cpy_tgt)

    shelltools.system(copy_cmd)
    #######################Workaround ends here ...

    # make defconfig and install the headers
    autotools.make("mrproper")
    autotools.make("{} defconfig".format(make_cmd))
    autotools.rawInstall(make_cmd, "headers_install")

    oldwd = os.getcwd()

    shelltools.cd(os.path.join(headers_tmp, "install", "include"))
    shelltools.system("find . -name '.' -o -name '.*' -prune -o -print | \
                       cpio -pVd --preserve-modification-time {}".format(headers_dir))

    # Remove sound/ directory which is installed by alsa-headers
    shelltools.system("rm -rf {}/sound".format(headers_dir))

    # Remove possible excludes given by actions.py
    if excludes:
        shelltools.system(
            "rm -rf {}".format(" ".join(["{0}/{1}".format(headers_dir, exc.strip("/")) for exc in excludes])))

    shelltools.cd(oldwd)

    # Remove tmp directory
    shelltools.system("rm -rf {}".format(headers_tmp))


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# Standard Python Modules
import os

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary-Core Modules

# ActionsAPI Modules
import inary.actionsapi
from inary.actionsapi.shelltools import *
import inary.actionsapi.get as get

class RunTimeError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[LibTools]: " + value)

def preplib(sourceDirectory='/usr/lib'):
    sourceDirectory = join_path(get.installDIR(), sourceDirectory)
    if can_access_directory(sourceDirectory):
        if system('/sbin/ldconfig -n -N {}'.format(sourceDirectory)):
            raise RunTimeError(_('Running \'ldconfig\' failed.'))

def gnuconfig_update():
    """ copy newest config.* onto source\'s """
    pass_gnuconfig=False
    for root, dirs, files in os.walk(os.getcwd()):
        for fileName in files:
            if fileName in ['config.sub', 'config.guess']:
                targetFile = os.path.join(root, fileName)
                if os.path.islink(targetFile):
                    unlink(targetFile)

                try:
                    copy('/usr/share/gnuconfig/{}'.format(fileName), join_path(root, fileName))
                except:
                    ctx.ui.info(_('GNU Config Update Failed.'))
                    if not pass_gnuconfig:
                        if not ctx.ui.confirm(_('Would you like to continue? (it may be dangerous!!!):')):
                            raise RunTimeError(_('GNU Config Update Failed. Please check your gnuconfig scripts. (/usr/share/gnuconfig)'))
                        else:
                            pass_gnuconfig=True
                else:
                    ctx.ui.info(_('GNU Config Update Finished.'))

def libtoolize(parameters=''):
    if system('/usr/bin/libtoolize {}'.format(parameters)):
        raise RunTimeError(_('Running \"libtoolize\" failed.'))

def gen_usr_ldscript(dynamicLib):
    makedirs('{}/usr/lib'.format(get.installDIR()))

    destinationFile = open('{0}/usr/lib/{1}'.format(get.installDIR(), dynamicLib), 'w')
    content = '''
/* GNU ld script
    Since Sulin has critical dynamic libraries
    in /lib, and the static versions in /usr/lib,
    we need to have a "fake" dynamic lib in /usr/lib,
    otherwise we run into linking problems.
*/
GROUP ( /lib/{} )
'''.format(dynamicLib)

    destinationFile.write(content)
    destinationFile.close()
    chmod('{0}/usr/lib/{1}'.format(get.installDIR(), dynamicLib))


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

import inary.actionsapi
import inary.util as util
import inary.context as ctx
from inary.actionsapi import get
from inary.actionsapi.shelltools import cd
from inary.actionsapi.shelltools import ls
from inary.actionsapi.shelltools import copy
from inary.actionsapi.inarytools import dosed
from inary.actionsapi.shelltools import system
from inary.actionsapi.shelltools import makedirs
from inary.actionsapi.inarytools import removeDir
from inary.actionsapi.shelltools import isDirectory
from inary.actionsapi.shelltools import can_access_file

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

class MesonError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[MesonTools]: " + value)

class ConfigureError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[MesonTools]: " + value)

class NinjaBuildError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[MesonTools]: " + value)

def fixpc():
    """ fix .pc files in installDIR()/usr/lib32/pkgconfig"""
    path = "{}/usr/lib32/pkgconfig".format(get.installDIR())
    if isDirectory(path):
        for f in ls("{}/*.pc".format(path)):
            dosed(f, get.emul32prefixDIR(), get.defaultprefixDIR())

def meson_configure(parameters=""):
    if can_access_file('meson.build'):
        prefix = get.defaultprefixDIR()
        args = "meson \
              --prefix=/{0} \
              --buildtype=plain \
              --libdir=/{0}/lib{1} \
              --libexecdir=/{2} \
              --sysconfdir=/{3} \
              --localstatedir=/{4} \
              {5} inaryPackageBuild".format(
            prefix,
            "32 " if get.buildTYPE() == "emul32" else "",
            get.libexecDIR(),
            get.confDIR(),
            get.localstateDIR(),
            parameters)

        if system(args):
            raise MesonError(_('Configure failed.'))
    else:
        raise ConfigureError(_('No configure script found. (\"{}\" file not found.)'.format("meson.build")))

def cmake_configure(parameters=""):
    makedirs("inaryPackageBuild")
    cd("inaryPackageBuild")

    if can_access_file(util.join_path("..", 'CMakeLists.txt')):
        args = 'cmake -DCMAKE_INSTALL_PREFIX=/{0} \
                      -DCMAKE_INSTALL_LIBDIR={1} \
                      -DCMAKE_C_FLAGS="{6} {2}" \
                      -DCMAKE_CXX_FLAGS="{6} {3}" \
                      -DCMAKE_LD_FLAGS="{4}" \
                      -DCMAKE_BUILD_TYPE=RelWithDebInfo {5} -G Ninja ..'.format(get.defaultprefixDIR(),
                                                                        "/usr/lib32 " if get.buildTYPE() == "emul32" else "/usr/lib",
                                                                        get.CFLAGS(),
                                                                        get.CXXFLAGS(),
                                                                        get.LDFLAGS(),
                                                                        parameters,
                                                                        "-m32"  if get.buildTYPE() == "emul32" else "-m64")

        if system(args):
            raise ConfigureError(_('CMake configure failed.'))
    else:
        raise ConfigureError(_('No configure script found. (\"{}\" file not found.)'.format("CMakeLists.txt")))

def ninja_build(parameters=""):
    if system("ninja {} {} -C inaryPackageBuild".format(get.makeJOBS(), parameters)):
        raise NinjaBuildError(_("Build failed."))
    if get.buildTYPE() == "emul32":
        fixpc()
        if isDirectory("{}/emul32".format(get.installDIR())): removeDir("/emul32")

def ninja_install(parameters=""):
    insdir = util.join_path(get.installDIR(), "emul32") if get.buildTYPE() == "emul32" else get.installDIR()
    if system('DESTDIR="{}" ninja install {} -C inaryPackageBuild'.format(insdir, get.makeJOBS())):
        raise NinjaBuildError(_("Install failed."))
    if isDirectory("{}/emul32".format(get.installDIR())):
        if isDirectory("{}/emul32/lib32".format(get.installDIR())):
            copy("{}/emul32/lib32".format(get.installDIR()), "{}/".format(get.installDIR()))
        if isDirectory("{}/emul32/usr/lib32".format(get.installDIR())):
            copy("{}/emul32/usr/lib32".format(get.installDIR()), "{}/usr/".format(get.installDIR()))
        removeDir("/emul32")

def ninja_check():
    if system('ninja test {} -C inaryPackageBuild'.format(get.makeJOBS())):
        raise MesonError(_("Check failed."))


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# standard python modules
import os

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
import inary.context as ctx

# ActionsAPI Modules
import inary.actionsapi
import inary.actionsapi.get as get
from inary.actionsapi.shelltools import system
from inary.actionsapi.shelltools import can_access_file
from inary.actionsapi.shelltools import export
from inary.actionsapi.shelltools import unlink
from inary.actionsapi.shelltools import unlinkDir

class ConfigureError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[PerlTools]: " + value)

class MakeError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[PerlTools]: " + value)

class InstallError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[PerlTools]: " + value)

def configure(parameters=''):
    """configure source with given parameters."""
    export('PERL_MM_USE_DEFAULT', '1')
    if can_access_file('Build.PL'):
        if system('perl{0} Build.PL installdirs=vendor destdir={1}'.format(get.curPERL(), get.installDIR())):
            raise ConfigureError(_('Configure failed.'))
    elif can_access_file('Makefile.PL'):
        if system('perl{0} Makefile.PL {1} PREFIX=/usr INSTALLDIRS=vendor DESTDIR={2}'.format(get.curPERL(), parameters,
                                                                                get.installDIR())):
            raise ConfigureError(_('Configure failed.'))
    else:
            raise ConfigureError(_('No configure script found. (\"{}\" file not found.)'.format("Build.PL/Makefile.PL")))

def make(parameters=''):
    """make source with given parameters."""
    if can_access_file('Makefile'):
        if system('make {}'.format(parameters)):
            raise MakeError(_('Make failed.'))
    else:
        if system('perl{0} Build {1}'.format(get.curPERL(), parameters)):
            raise MakeError(_('\'perl build\' failed.'))

def install(parameters='install'):
    """install source with given parameters."""
    if can_access_file('Makefile'):
        if system('make {}'.format(parameters)):
            raise InstallError(_('Install failed.'))
    else:
        if system('perl{} Build install'.format(get.curPERL())):
            raise MakeError(_('\'perl install\' failed.'))

    removePacklist()
    removePodfiles()

def removePacklist(path='usr/lib/perl5/'):
    """ cleans .packlist file from perl packages """
    full_path = '{0}/{1}'.format(get.installDIR(), path)
    for root, dirs, files in os.walk(full_path):
        for packFile in files:
            if packFile == ".packlist":
                if can_access_file('{0}/{1}'.format(root, packFile)):
                    unlink('{0}/{1}'.format(root, packFile))
                    removeEmptydirs(root)

def removePodfiles(path='usr/lib/perl5/'):
    """ cleans *.pod files from perl packages """
    full_path = '{0}/{1}'.format(get.installDIR(), path)
    for root, dirs, files in os.walk(full_path):
        for packFile in files:
            if packFile.endswith(".pod"):
                if can_access_file('{0}/{1}'.format(root, packFile)):
                    unlink('{0}/{1}'.format(root, packFile))
                    removeEmptydirs(root)

def removeEmptydirs(d):
    """ remove empty dirs from perl package if exists after deletion .pod and .packlist files """
    if not os.listdir(d) and not d == get.installDIR():
        unlinkDir(d)
        d = d[:d.rfind("/")]
        removeEmptydirs(d)


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# Standart Python Modules
import subprocess

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# INARY Modules
import inary.context as ctx
import inary.actionsapi

class PkgconfigError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[pkgconfig]: " + value)

def getVariableForLibrary(library, variable):
    # Returns a specific variable provided in the library .pc file
    try:
        proc = subprocess.Popen(["pkg-config",
                                 "--variable={}".format(variable),
                                 "{}".format(library)],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        return_code = proc.wait()
    except OSError as exception:
        if exception.errno == 2:
            raise PkgconfigError(_("Package pkgconfig is not installed on your system."))
    else:
        if return_code == 0 and proc.stdout:
            return proc.stdout.read().strip()
        else:
            # Command failed
            raise PkgconfigError(proc.stderr.read().strip())

def getLibraryVersion(library):
    """Returns the module version provided in the library .pc file."""
    try:
        proc = subprocess.Popen(["pkg-config",
                                 "--modversion",
                                 library],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        return_code = proc.wait()
    except OSError as exception:
        if exception.errno == 2:
            raise PkgconfigError(_("Package pkgconfig is not installed on your system."))
    else:
        if return_code == 0 and proc.stdout:
            return proc.stdout.read().strip()
        else:
            # Command failed
            raise PkgconfigError(proc.stderr.read().strip())

def getLibraryCFLAGS(library):
    """Returns compiler flags for compiling with this library.
    Ex: -I/usr/include/nss"""
    try:
        proc = subprocess.Popen(["pkg-config",
                                 "--cflags",
                                 "{}".format(library)],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        return_code = proc.wait()
    except OSError as exception:
        if exception.errno == 2:
            raise PkgconfigError(_("Package pkgconfig is not installed on your system."))
    else:
        if return_code == 0 and proc.stdout:
            return proc.stdout.read().strip()
        else:
            # Command failed
            raise PkgconfigError(proc.stderr.read().strip())

def getLibraryLIBADD(library):
    """Returns linker flags for linking with this library.
    Ex: -lpng14"""
    try:
        proc = subprocess.Popen(["pkg-config",
                                 "--libs",
                                 "{}".format(library)],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        return_code = proc.wait()
    except OSError as exception:
        if exception.errno == 2:
            raise PkgconfigError(_("Package pkgconfig is not installed on your system."))
    else:
        if return_code == 0 and proc.stdout:
            return proc.stdout.read().strip()
        else:
            # Command failed
            raise PkgconfigError(proc.stderr.read().strip())

def runManualCommand(*args):
    """Runs the given command and returns the output."""
    cmd = ["pkg-config"]
    cmd.extend(args)
    try:
        proc = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        return_code = proc.wait()
    except OSError as exception:
        if exception.errno == 2:
            raise PkgconfigError(_("Package pkgconfig is not installed on your system."))
    else:
        if return_code == 0 and proc.stdout:
            return proc.stdout.read().strip()
        else:
            # Command failed
            raise PkgconfigError(proc.stderr.read().strip())

def libraryExists(library):
    """Returns True if the library provides a .pc file."""
    result = None
    try:
        result = subprocess.call(["pkg-config",
                                  "--exists",
                                  "{}".format(library)])
    except OSError as exception:
        if exception.errno == 2:
            raise PkgconfigError(_("Package pkgconfig is not installed on your system."))
    else:
        return result == 0


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

import glob
# standard python modules
import os

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
import inary.context as ctx

# ActionsAPI Modules
import inary.actionsapi
import inary.actionsapi.get as get
from inary.actionsapi.shelltools import system, can_access_file, unlink, isEmpty
from inary.actionsapi.inarytools import dodoc

class ConfigureError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[PythonTools]: " + value)

class CompileError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[PythonTools]: " + value)

class InstallError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[PythonTools]: " + value)

class RunTimeError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[PythonTools]: " + value)

def configure(parameters='', pyVer=''):
    """does python setup.py configure"""
    if system('python{0} setup.py configure {1}'.format(pyVer, parameters)):
        raise ConfigureError(_('Configuration failed.'))

def compile(parameters='', pyVer=''):
    """compile source with given parameters."""
    if system('python{0} setup.py build {1}'.format(pyVer, parameters)):
        raise CompileError(_('Make failed.'))

def install(parameters='', pyVer=''):
    """does python setup.py install"""
    if system('python{0} setup.py install --root={1} --no-compile -O0 {2}'.format(pyVer, get.installDIR(), parameters)):
        raise InstallError(_('Install failed.'))

    docFiles = ('AUTHORS', 'CHANGELOG', 'CONTRIBUTORS', 'COPYING*', 'COPYRIGHT',
                'Change*', 'KNOWN_BUGS', 'LICENSE', 'MAINTAINERS', 'NEWS',
                'README*', 'PKG-INFO')

    for docGlob in docFiles:
        for doc in glob.glob(docGlob):
            if not isEmpty(doc):
                dodoc(doc)

def run(parameters='', pyVer=''):
    """executes parameters with python"""
    if system('python{0} {1}'.format(pyVer, parameters)):
        raise RunTimeError(_('Running \"{}\" failed.').format(parameters))

def fixCompiledPy(lookInto='/usr/lib/{}/'.format(get.curPYTHON())):
    """ cleans *.py[co] from packages """
    for root, dirs, files in os.walk('{0}/{1}'.format(get.installDIR(), lookInto)):
        for compiledFile in files:
            if compiledFile.endswith('.pyc') or compiledFile.endswith('.pyo'):
                if can_access_file('{0}/{1}'.format(root, compiledFile)):
                    unlink('{0}/{1}'.format(root, compiledFile))


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

import gettext
import glob

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
import inary.context as ctx

# ActionsAPI Modules
import inary.actionsapi

# ActionsAPI Modules
from inary.actionsapi import get
from inary.actionsapi import cmaketools
from inary.actionsapi import shelltools

basename = "qt5"

prefix = "/{}".format(get.defaultprefixDIR())
libdir = "{}/lib".format(prefix)
libexecdir = "{}/libexec".format(prefix)
sysconfdir = "/etc"
bindir = "{}/bin".format(prefix)
includedir = "{}/include".format(prefix)

# qt5 spesific variables

headerdir = "{0}/include/{1}".format(prefix, basename)
datadir = "{0}/share/{1}".format(prefix, basename)
docdir = "/{0}/{1}".format(get.docDIR(), basename)
archdatadir = "{0}/{1}".format(libdir, basename)
examplesdir = "{0}/{1}/examples".format(libdir, basename)
importdir = "{0}/{1}/imports".format(libdir, basename)
plugindir = "{0}/{1}/plugins".format(libdir, basename)
qmldir = "{0}/{1}/qmldir".format(libdir, basename)
testdir = "{0}/share/{1}".format(prefix, basename)
translationdir = "{0}/translations".format(datadir)

qmake = "{}/qmake-qt5".format(bindir)

class ConfigureError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[QTTools]: " + value)

def configure(projectfile='', parameters='', installPrefix=prefix):
    if projectfile != '' and not shelltools.can_access_file(projectfile):
        raise ConfigureError(_("Project file \"{}\" not found.").format(projectfile))

    profiles = glob.glob("*.pro")
    if len(profiles) > 1 and projectfile == '':
        raise ConfigureError(
            _("It seems there are more than one .pro file, you must specify one. (Possible .pro files: \"{}\")").format(
                ", ".join(profiles)))

    shelltools.system(
        "{0} -makefile {1} PREFIX='{2}' QMAKE_CFLAGS+='{3}' QMAKE_CXXFLAGS+='{4}' {5}".format(qmake, projectfile,
                                                                                installPrefix,
                                                                                get.CFLAGS(),
                                                                                get.CXXFLAGS(),
                                                                                parameters))

def make(parameters=''):
    cmaketools.make(parameters)

def install(parameters='', argument='install'):
    cmaketools.install('INSTALL_ROOT="{0}" {1}'.format(get.installDIR(), parameters), argument)


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# standard python modules
import os
from gettext import translation
from glob import glob

__trans = translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
import inary.context as ctx

# ActionsAPI Modules
import inary.actionsapi
import inary.actionsapi.get as get
from inary.actionsapi.shelltools import export
from inary.actionsapi.shelltools import isEmpty
from inary.actionsapi.shelltools import system

class ConfigureError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[RubyModules]: " + value)

class CompileError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[RubyModules]: " + value)

class InstallError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[RubyModules]: " + value)

class RunTimeError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[RubyModules]: " + value)

def get_config(config):
    return os.popen("ruby -rrbconfig -e 'puts RbConfig::CONFIG[\"{}\"]'".format(config)).read().strip()

def get_ruby_version():
    return get_config('ruby_version')

def get_rubylibdir():
    return get_config('rubylibdir')

def get_sitedir():
    return get_config('sitedir')

def get_gemdir():
    return os.popen('gem env gemdir').read().strip()

def get_ruby_install_name():
    return get_config('ruby_install_name')

def get_gemhome():
    (rubylibdir, ruby_version) = os.path.split(get_rubylibdir())

    return os.path.join(get.installDIR(), rubylibdir.lstrip('/'), 'gems', ruby_version)

def get_sitelibdir():
    return get_config('sitelibdir')

def generate_gemname():
    return "-".join(get.srcNAME().split("-")[1:])

def auto_dodoc():
    from inary.actionsapi.inarytools import dodoc

    docs = ('AUTHORS', 'CHANGELOG', 'CONTRIBUTORS', 'Change*', 'KNOWN_BUGS',
            'MAINTAINERS', 'NEWS', 'README*', 'History.txt')

    for doc_glob in docs:
        for doc in glob(doc_glob):
            if not isEmpty(doc):
                dodoc(doc)

def install(parameters=''):
    """does ruby setup.rb install"""
    if system(
            'ruby -w setup.rb --prefix=/{0}/{1} --destdir={1} {2}'.format(get.defaultprefixDIR(), get_gemdir(), get.installDIR(), parameters)):
        raise InstallError(_('Install failed.'))

    auto_dodoc()

def rake_install(parameters=''):
    """execute rake script for installation"""
    if system('rake -t -l {0} {1}'.format(os.path.join('/', get.defaultprefixDIR(), 'lib'), parameters)):
        raise InstallError(_('Install failed.'))

    auto_dodoc()

def gem_build(parameters=''):
    if system('gem build {} {}'.format(generate_gemname(), parameters)):
        raise InstallError(_('Build failed.'))

def gem_install(parameters=''):
    """Make installation from GemFile"""
    if system('gem install --backtrace {0} -i "{1}{2}"  -n "{1}/usr/bin" {3}.gem'.format(parameters, get.installDIR(), get_gemdir() , generate_gemname() + "-" + get.srcVERSION())):
        raise InstallError(_('Install failed.'))

    auto_dodoc()

def run(parameters=''):
    """executes parameters with ruby"""
    export('DESTDIR', get.installDIR())

    if system('ruby {}'.format(parameters)):
        raise RuntimeError(_("Running 'ruby {}' failed.").format(parameters))


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# Inary Modules
import inary.context as ctx

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# ActionsAPI Modules
import inary.actionsapi
import inary.actionsapi.get as get
from inary.actionsapi.shelltools import system

class MakeError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[Scons]: " + value)

class InstallError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[Scons]: " + value)

def make(parameters=''):
    if system('scons {0} {1}'.format(get.makeJOBS(), parameters)):
        raise MakeError(_('Make failed.'))

def install(parameters='install', prefix=get.installDIR(), argument='prefix'):
    if system('scons {0}={1} {2}'.format(argument, prefix, parameters)):
        raise InstallError(_('Install failed.'))


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

import glob
import grp
# Standart Python Modules
import os
import pwd
import shutil
import sys

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules
import inary.context as ctx

# ActionsAPI Modules

from inary.actionsapi import error
from inary.util import run_logged
from inary.util import join_path
from inary.util import colorize

def can_access_file(filePath):
    """test the existence of file"""
    return os.access(filePath, os.F_OK)

def can_access_directory(destinationDirectory):
    """test readability, writability and executablility of directory"""
    return os.access(destinationDirectory, os.R_OK | os.W_OK | os.X_OK)

def makedirs(destinationDirectory):
    """recursive directory creation function"""
    try:
        if not os.access(destinationDirectory, os.F_OK):
            os.makedirs(destinationDirectory)
    except OSError:
        error(_('ActionsAPI [makedirs]: Cannot create directory \"{}\"').format(destinationDirectory))

def echo(destionationFile, content):
    try:
        f = open(destionationFile, 'a')
        f.write('{}\n'.format(content))
        f.close()
    except IOError:
        error(_('ActionsAPI [echo]: Can\'t append to file \"{}\"').format(destionationFile))

def chmod(filePath, mode=0o755):
    """change the mode of filePath to the mode"""
    filePathGlob = glob.glob(filePath)
    if len(filePathGlob) == 0:
        error(_("ActionsAPI [chmod]: No file matched pattern \"{}\"").format(filePath))

    for fileName in filePathGlob:
        if can_access_file(fileName):
            try:
                os.chmod(fileName, mode)
            except OSError:
                ctx.ui.error(_('ActionsAPI [chmod]: Operation not permitted: {0} (mode: 0{1})').format(fileName, mode))
        else:
            ctx.ui.error(_('ActionsAPI [chmod]: File \"{}\" doesn\'t exists.').format(fileName))

def chown(filePath, uid='root', gid='root'):
    """change the owner and group id of filePath to uid and gid"""
    if can_access_file(filePath):
        try:
            os.chown(filePath, pwd.getpwnam(uid)[2], grp.getgrnam(gid)[2])
        except OSError:
            ctx.ui.error(
                _('ActionsAPI [chown]: Permission denied: {0} (uid: {1}, gid: {2})').format(filePath, uid, gid))
    else:
        ctx.ui.error(_('ActionsAPI [chown]: File \"{}\" doesn\'t exists.').format(filePath))

def sym(source, destination):
    """creates symbolic link"""
    try:
        os.symlink(source, destination)
    except OSError:
        ctx.ui.error(_('ActionsAPI [sym]: Permission denied: \"{0}\" to \"{1}\"').format(source, destination))

def unlink(pattern):
    """remove the file path"""
    filePathGlob = glob.glob(pattern)
    if len(filePathGlob) == 0:
        ctx.ui.error(_("ActionsAPI [unlink]: No file matched pattern \"{}\". Remove operation failed.").format(pattern))
        return

    for filePath in filePathGlob:
        if isFile(filePath) or isLink(filePath):
            try:
                os.unlink(filePath)
            except OSError:
                ctx.ui.error(_('ActionsAPI [unlink]: Permission denied: \"{}\"').format(filePath))
        elif isDirectory(filePath):
            ctx.ui.warning(_(
                'ActionsAPI [unlink]: \"{}\" is not a file, use \'unlinkDir\' or \'removeDir\' to remove directories.').format(
                filePath))

        else:
            ctx.ui.error(_('ActionsAPI [unlink]: File \"{}\" doesn\'t exists.').format(filePath))

def unlinkDir(sourceDirectory):
    """delete an entire directory tree"""
    if isDirectory(sourceDirectory) or isLink(sourceDirectory):
        try:
            shutil.rmtree(sourceDirectory)
        except OSError:
            error(_('ActionsAPI [unlinkDir]: Operation not permitted: \"{}\"').format(sourceDirectory))
    elif isFile(sourceDirectory):
        pass
    else:
        error(_('ActionsAPI [unlinkDir]: Directory \"{}\" doesn\'t exists.').format(sourceDirectory))

def move(source, destination):
    """recursively move a "source" file or directory to "destination\""""
    sourceGlob = glob.glob(source)
    if len(sourceGlob) == 0:
        error(_("ActionsAPI [move]: No file matched pattern \"{}\".").format(source))

    for filePath in sourceGlob:
        if isFile(filePath) or isLink(filePath) or isDirectory(filePath):
            try:
                shutil.move(filePath, destination)
            except OSError:
                error(_('ActionsAPI [move]: Permission denied: \"{0}\" to \"{1}\"').format(filePath, destination))
        else:
            error(_('ActionsAPI [move]: File \"{}\" doesn\'t exists.').format(filePath))

# FIXME: instead of passing a sym parameter, split copy and copytree into 4 different function
def copy(source, destination, sym=True):
    """recursively copy a "source" file or directory to "destination\" """
    sourceGlob = glob.glob(source)
    if len(sourceGlob) == 0:
        error(_("ActionsAPI [copy]: No file matched pattern \"{}\".").format(source))

    for filePath in sourceGlob:
        if isFile(filePath) and not isLink(filePath):
            try:
                shutil.copy(filePath, destination)
            except IOError:
                error(_('ActionsAPI [copy]: Permission denied: \"{0}\" to \"{1}\"').format(filePath, destination))
        elif isLink(filePath) and sym:
            if isDirectory(destination):
                os.symlink(os.readlink(filePath), join_path(destination, os.path.basename(filePath)))
            else:
                if isFile(destination):
                    os.remove(destination)
                os.symlink(os.readlink(filePath), destination)
        elif isLink(filePath) and not sym:
            if isDirectory(filePath):
                copytree(filePath, destination)
            else:
                shutil.copy(filePath, destination)
        elif isDirectory(filePath):
            copytree(filePath, destination, sym)
        else:
            error(_('ActionsAPI [copy]: File \"{}\" does not exist.').format(filePath))

def copytree(source, destination, sym=True):
    """recursively copy an entire directory tree rooted at source"""
    if isDirectory(source):
        if os.path.exists(destination):
            if isDirectory(destination):
                copytree(source, join_path(destination, os.path.basename(source.strip('/'))))
                return
            else:
                copytree(source, join_path(destination, os.path.basename(source)))
                return
        try:
            shutil.copytree(source, destination, sym)
        except OSError as e:
            error(_('ActionsAPI [copytree] \"{0}\" to \"{1}\": {2}').format(source, destination, e))
    else:
        error(_('ActionsAPI [copytree]: Directory \"{}\" doesn\'t exists.').format(source))

def touch(filePath):
    """changes the access time of the 'filePath', or creates it if it does not exist"""
    filePathGlob = glob.glob(filePath)

    if filePathGlob:
        if len(filePathGlob) == 0:
            error(_("ActionsAPI [touch]: No file matched pattern \"{}\".").format(filePath))

        for f in filePathGlob:
            os.utime(f, None)
    else:
        try:
            f = open(filePath, 'w')
            f.close()
        except IOError:
            error(_('ActionsAPI [touch]: Permission denied: \"{}\"').format(filePath))

def cd(directoryName=''):
    """change directory"""
    current = os.getcwd()
    if directoryName:
        os.chdir(directoryName)
    else:
        os.chdir(os.path.dirname(current))

def ls(source):
    """listdir"""
    if os.path.isdir(source):
        return os.listdir(source)
    else:
        return glob.glob(source)

def export(key, value):
    """export environ variable"""
    os.environ[key] = value

def isLink(filePath):
    """return True if filePath refers to a symbolic link"""
    return os.path.islink(filePath)

def isFile(filePath):
    """return True if filePath is an existing regular file"""
    return os.path.isfile(filePath)

def isDirectory(filePath):
    """Return True if filePath is an existing directory"""
    return os.path.isdir(filePath)

def isEmpty(filePath):
    """Return True if filePath is an empty file"""
    return os.path.getsize(filePath) == 0

def realPath(filePath):
    """return the canonical path of the specified filename, eliminating any symbolic links encountered in the path"""
    return os.path.realpath(filePath)

def baseName(filePath):
    """return the base name of pathname filePath"""
    return os.path.basename(filePath)

def dirName(filePath):
    """return the directory name of pathname path"""
    return os.path.dirname(filePath)

def system(command):
    # command an list but should be an str
    sys.stdout.write(colorize(_("[Running Command]: "),'brightwhite') + command + "\n")
    #    command = str.join(str.split(command))
    retValue = run_logged(command)

    # if return value is different than 0, it means error, raise exception
    if retValue != 0:
        error(_("ActionsAPI [system]: Command \'{0}\' failed, return value was {1}.").format(command, retValue))

    return retValue


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

import gettext
# standard python modules
import os
import shlex
import shutil

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

# Inary Modules

# ActionsAPI Modules
import inary.actionsapi
import inary.actionsapi.get as get
from inary.actionsapi.shelltools import *
from inary.actionsapi.inarytools import dodir, domove, dosym, insinto

WorkDir = "{0}-{1}".format(get.srcNAME(), get.srcVERSION().split('_')[-1])

class CompileError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[TexLife]: " + value)

class InstallError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[TexLife]: " + value)

class RunTimeError(inary.actionsapi.Error):
    def __init__(self, value=''):
        inary.actionsapi.Error.__init__(self, value)
        self.value = value
        ctx.ui.error("[TexLife]: " + value)

def compile(parameters=''):
    """compiling texlive packages"""

    # Move sources according to tplobj files
    if moveSources():
        raise CompileError(_('Moving source files failed.'))
    # Generate config files
    if generateConfigFiles():
        raise CompileError(_('Generate config files failed.'))
    # Build format files
    if buildFormatFiles():
        raise CompileError(_('Building format files failed.'))

def install(parameters=''):
    """Installing texlive packages"""

    # Create symlinks from format to engines
    if createSymlinksFormat2Engines():
        raise InstallError(_('Creating symlinks from format to engines failed.'))

    # Installing docs
    if installDocFiles():
        raise InstallError(_('Installing docs failed.'))

    # Installing texmf, texmf-dist, tlpkg, texmf-var
    if installTexmfFiles():
        raise InstallError(_('Installing texmf files failed.'))

    # Installing config files
    if installConfigFiles():
        raise InstallError(_('Installing config files failed.'))

    # Handle config files
    if handleConfigFiles():
        raise InstallError(_('Handle config files failed.'))

def createSymlinksFormat2Engines():
    """Create symlinks from format to engines"""
    for formatfile in ls("{}/texmf/fmtutil/format*.cnf".format(get.curDIR())):
        symfile = open(formatfile)
        for line in symfile.readlines():
            if not line.startswith("#"):
                symbin = line.split(None)
                if "cont-" in symbin[0] or "metafun" in symbin[0] or "mptopdf" in symbin[0]:
                    ctx.ui.info(_('Symlink \"{}\" skipped (special case)').format(symbin[0]))
                elif "mf" in symbin[0]:
                    ctx.ui.info(_('Symlink \"{0[0]}\" -> \"{0[1]}\" skipped (texlive-core takes care of it.').format(symbin))
                else:
                    if symbin[0] == symbin[1]:
                        ctx.ui.info(_('Symlink \"{0[0]}\" -> \"{0[1]}\" skipped.').format(symbin))
                    elif can_access_file("{0}/usr/bin/{1}".format(get.installDIR(), symbin[0])):
                        ctx.ui.info(_('Symlink \"{}\" skipped (file exists.)').format(symbin[0]))
                    else:
                        ctx.ui.info(_('Making symlink from {0[0]} to {0[1]}').format(symbin))
                        dodir("/usr/bin")
                        sym(symbin[1], "{0}/usr/bin/{1}".format(get.installDIR(), symbin[0]))
        symfile.close()

def installDocFiles():
    """Installing docs"""
    if "documentation" in get.srcNAME():
        if os.path.isdir("{}/texmf-doc".format(get.curDIR())):
            copytree("texmf-doc", "{}/usr/share/texmf-doc".format(get.installDIR()))
    else:
        for removedir in ["texmf", "texmf-dist"]:
            if os.path.isdir("{0}/{1}/doc/".format(get.curDIR(), removedir)):
                shutil.rmtree("{0}/{1}/doc".format(get.curDIR(), removedir))

def installTexmfFiles():
    """Installing texmf, texmf-dist, tlpkg, texmf-var"""
    for installdoc in ["texmf", "texmf-dist", "tlpkg", "texmf-var"]:
        if os.path.isdir("{0}/{1}".format(get.curDIR(), installdoc)):
            if not installdoc == "texmf-var":
                shutil.copytree(installdoc, "{0}/usr/share/{1}".format(get.installDIR(), installdoc))
            else:
                copytree(installdoc, "{}/var/lib/texmf".format(get.installDIR()))

def installConfigFiles():
    """Installing config files"""
    if can_access_file("{0}/{1}.cfg".format(get.curDIR(), get.srcNAME())):
        insinto("/etc/texmf/updmap.d", "{0}/{1}.cfg".format(get.curDIR(), get.srcNAME()))

    if can_access_file("{0}/{1}.config.ps".format(get.curDIR(), get.srcNAME())):
        insinto("/etc/texmf/dvips.d", "{0}/{1}.config.ps".format(get.curDIR(), get.srcNAME()))

    if can_access_file("{0}/{1}.config".format(get.curDIR(), get.srcNAME())):
        insinto("/etc/texmf/dvipdfm/config", "{0}/{1}.config".format(get.curDIR(), get.srcNAME()))

    if can_access_file("{0}/language/{1}.def.config".format(get.curDIR(), get.srcNAME())):
        insinto("/etc/texmf/language.def.d", "{0}/language.{1}.def".format(get.curDIR(), get.srcNAME()))

    if can_access_file("{0}/language.{1}.dat".format(get.curDIR(), get.srcNAME())):
        insinto("/etc/texmf/language.dat.d", "{0}/language.{1}.dat".format(get.curDIR(), get.srcNAME()))

def handleConfigFiles():
    """Handling config files"""
    for root, dirs, files in os.walk("{}/usr/share/texmf".format(get.installDIR())):
        if not ("config" in root or "doc" in root):
            for configFile in files:
                if configFile.endswith(("cfg", "cnf")):
                    dirname = root.split("/")[-1]
                    if not os.path.isdir("{0}/etc/texmf/{1}.d".format(get.installDIR(), dirname)):
                        ctx.ui.info(_('Creating \"/etc/texmf/{}.d\"').format(dirname))
                        dodir("/etc/texmf/{}.d".format(dirname))
                    ctx.ui.info(_('Moving (and symlinking) \"/usr/share/texmf/{0}\" to \"/etc/texmf/{1}.d\"').format(configFile,
                                                                                dirname))
                    domove("/usr/share/texmf/{0}/{1}".format(dirname, configFile), "/etc/texmf/{}.d".format(dirname))
                    dosym("/etc/texmf/{0}.d/{1}".format(dirname, configFile),
                          "/usr/share/texmf/{0}/{1}".format(dirname, configFile))

def addFormat(parameters):
    """Add format files"""
    if not os.path.isdir("{}/texmf/fmtutil/".format(get.curDIR())):
        makedirs("{}/texmf/fmtutil/".format(get.curDIR()))
    if not os.path.isfile("{0}/texmf/fmtutil/format.{1}.cnf".format(get.curDIR(), get.srcNAME())):
        cnf_file = open("{0}/texmf/fmtutil/format.{1}.cnf".format(get.curDIR(), get.srcNAME()), "w")
        cnf_file.write("# Generated for {} by actionsapi/texlivemodules.py\n".format(get.srcNAME()))
        cnf_file.close()

    # TODO: Use regex for code simplification
    parameters = " ".join(parameters.split())  # Removing white-space characters
    parameters = shlex.split(parameters)  # Split parameters until the value "option"
    para_dict = {}
    for option in parameters:
        pair = option.strip()  # Remove whitespaces before "options" value
        pair = pair.split("=", 1)  # The value "options" may have multiple "=", thus split just one time
        if len(pair) == 2:  # The list may contain values that are not pair
            para_dict[pair[0]] = pair[1]
            if pair[0] == "patterns" and pair[1] == '':
                para_dict["patterns"] = '-'  # Specified in the texlive-module.eclass
            elif not pair[0] == 'patterns':
                para_dict["patterns"] = '-'

    cnf_file = open('{0}/texmf/fmtutil/format.{1}.cnf'.format(get.curDIR(), get.srcNAME()), 'a')
    cnf_file.write('{0[name]}\t{0[engine]}\t{0[patterns]}\t{0[options]}\n'.format(para_dict))
    cnf_file.close()

def moveSources():
    reloc = "texmf-dist"

    for tlpobjfile in os.listdir("tlpkg/tlpobj/"):
        jobsfile = open("tlpkg/tlpobj/{}".format(tlpobjfile))
        for line in jobsfile.readlines():
            if "RELOC" in line:
                path = line.split("/", 1)[-1]
                path = path.strip()
                filename = path.split("/", -1)
                dirname = os.path.dirname(path)
                if not os.path.isdir("{0}/{1}".format(reloc, dirname)):
                    os.system("mkdir -p {0}/{1}".format(reloc, dirname))
                shutil.move("{}".format(path), "{0}/{1}".format(reloc, dirname))

def buildFormatFiles():
    """Build format files"""
    if os.path.isdir("{}/texmf/fmtutil/".format(get.curDIR())):
        for formatfile in ls("{}/texmf/fmtutil/format*.cnf".format(get.curDIR())):
            makedirs("{}/texmf-var/web2c/".format(get.curDIR()))
            ctx.ui.info(_('Building format file {}').format(formatfile))
            export("TEXMFHOME", "{0}/texmf:/{0}texmf-dist:{0}/texmf-var".format(get.curDIR()))
            export("VARTEXFONTS", "fonts")
            system("env -u TEXINPUTS fmtutil --cnffile {} --fmtdir texmf-var/web2c --all".format(formatfile))

def addLanguageDat(parameter):
    """Create language.*.dat files"""
    parameter = parameter.split()
    para_dict = {}
    for option in parameter:
        pair = option.split("=")
        if len(pair) == 2:  # That's just a caution, the pair should have two items, not more not less
            para_dict[pair[0]] = pair[1]

    language_dat = open('{0}/language.{1}.dat'.format(get.curDIR(), get.srcNAME()), 'a')
    language_dat.write('{0[name]}\t{0[file]}\n"'.format(para_dict))
    language_dat.close()

    if "synonyms" in para_dict:
        language_dat = open('{0}/language.{1}.dat'.format(get.curDIR(), get.srcNAME()), 'a')
        language_dat.write("={}\n".format(para_dict["synonyms"]))
        language_dat.close()

def addLanguageDef(parameter):
    """Create language.*.def files"""
    parameter = parameter.split()
    para_dict = {}
    for option in parameter:
        pair = option.split("=")
        if len(pair) == 2:  # That's just a caution, the pair should have two items, not more not less
            para_dict[pair[0]] = pair[1]

    if "lefthyphenmin" in para_dict and not para_dict["lefthyphenmin"]:
        para_dict["lefthyphenmin"] = "2"
    if "righthyphenmin" in para_dict and not para_dict["righthyphenmin"]:
        para_dict["righthyphenmin"] = "3"

    language_def = open('{0}/language.{1}.def'.format(get.curDIR(), get.srcNAME()), 'a')
    language_def.write("\\addlanguage{%s}{%s}{}{%s}{%s}\n" % (
        para_dict["name"], para_dict["file"], para_dict["lefthyphenmin"], para_dict["righthyphenmin"]))
    language_def.close()

    if "synonyms" in para_dict:
        language_def = open('{0}/language.{1}.def'.format(get.curDIR(), get.srcNAME()), 'a')
        language_def.write("\\addlanguage{%s}{%s}{}{%s}{%s}\n" % (
            para_dict["synonyms"], para_dict["file"], para_dict["lefthyphenmin"], para_dict["righthyphenmin"]))
        language_def.close()

def generateConfigFiles():
    """Generate config files"""
    for tlpobjfile in ls("{}/tlpkg/tlpobj/*".format(get.curDIR())):
        jobsfile = open(tlpobjfile)
        for line in jobsfile.readlines():
            splitline = line.split(" ", 2)
            if splitline[0] == "execute":
                command = splitline[1]
                parameter = splitline[2].strip()
                if command == "addMap":
                    echo("{0}/{1}.cfg".format(get.curDIR, get.srcNAME()), "Map {}".format(parameter))
                    ctx.ui.info(_('Map {0} is added to {1}/{2}.cfg').format(parameter, get.curDIR(), get.srcNAME()))
                elif command == "addMixedMap":
                    echo("{0}/{1}.cfg".format(get.curDIR(), get.srcNAME()), "MixedMap {}".format(parameter))
                    ctx.ui.info(
                        _('MixedMap {0} is added to {1}/{2}.cfg').format(parameter, get.curDIR(), get.srcNAME()))
                elif command == "addDvipsMap":
                    echo("{0}/{1}-config.ps".format(get.curDIR(), get.srcNAME()), "p +{}".format(parameter))
                    ctx.ui.info(
                        _('p +{0} is added to {1}/{2}-config.ps').format(parameter, get.curDIR(), get.srcNAME()))
                elif command == "addDvipdfmMap":
                    echo("{0}/{1}-config".format(get.curDIR(), get.srcNAME()), "f {}".format(parameter))
                    ctx.ui.info(_('f {0} is added to {1}/{2}-config').format(parameter, get.curDIR(), get.srcNAME()))
                elif command == "AddHyphen":
                    addLanguageDat(parameter)
                    addLanguageDef(parameter)
                elif command == "AddFormat":
                    addFormat(parameter)
                elif command == "BuildFormat":
                    ctx.ui.info(_('Language file  {}  already generated.').format(parameter))
                elif command == "BuildLanguageDat":
                    ctx.ui.info(_('No rule to proccess {}. Please file a bug.').format(command))
        jobsfile.close()


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.

# Standard Python Modules
import os

# Inary-Core Modules
import inary.context as ctx

# Set individual information, that are generally needed for ActionsAPI

def exportFlags():
    """General flags used in actions API."""

    # first reset environ
    os.environ.clear()
    os.environ.update(ctx.config.environ)

    # Build systems depend on these environment variables. That is why
    # we export them instead of using as (instance) variables.
    values = ctx.config.values
    os.environ['HOST'] = values.build.host
    os.environ['CFLAGS'] = values.build.cflags
    os.environ['CXXFLAGS'] = values.build.cxxflags
    os.environ['LDFLAGS'] = values.build.ldflags
    os.environ['USER_LDFLAGS'] = values.build.ldflags
    os.environ['JOBS'] = values.build.jobs
    os.environ['MAKEFLAGS'] = values.build.makeflags

    os.environ['LD_AS_NEEDED'] = "1"

    # http://liste.pardus.org.tr/gelistirici/2009-January/016442.html
    os.environ['CC'] = "{}-gcc".format(values.build.host)
    os.environ['CXX'] = "{}-g++".format(values.build.host)
    os.environ['LD'] = "ld"

class Env(object):
    """General environment variables used in actions API"""

    def __init__(self):

        exportFlags()

        self.__vars = {
            'pkg_dir': 'PKG_DIR',
            'work_dir': 'WORK_DIR',
            'install_dir': 'INSTALL_DIR',
            'build_type': 'INARY_BUILD_TYPE',
            'src_name': 'SRC_NAME',
            'src_version': 'SRC_VERSION',
            'src_release': 'SRC_RELEASE',
            'host': 'HOST',
            'cflags': 'CFLAGS',
            'cxxflags': 'CXXFLAGS',
            'ldflags': 'LDFLAGS',
            'jobs': 'JOBS'
        }

    def __getattr__(self, attr):

        # Using environment variables is somewhat tricky. Each time
        # you need them you need to check for their value.
        if attr in self.__vars:
            return os.getenv(self.__vars[attr])
        else:
            return None

class Dirs:
    """General directories used in actions API."""
    # TODO: Eventually we should consider getting these from a/the
    # configuration file
    doc = 'usr/share/doc'
    sbin = 'usr/sbin'
    man = 'usr/share/man'
    info = 'usr/share/info'
    data = 'usr/share'
    conf = 'etc'
    localstate = 'var'
    libexec = 'usr/libexec'
    defaultprefix = 'usr'
    emul32prefix = 'emul32'

    # These should be owned by object not the class. Or else Python
    # will bug us with NoneType errors because of uninitialized
    # context (ctx) because of the import in build.py.
    def __init__(self):
        self.values = ctx.config.values
        self.kde = self.values.dirs.kde_dir
        self.qt = self.values.dirs.qt_dir

class Generals:
    """General informations from /etc/inary/inary.conf"""

    def __init__(self):
        self.values = ctx.config.values
        self.architecture = self.values.general.architecture
        self.distribution = self.values.general.distribution
        self.distribution_release = self.values.general.distribution_release

# As we import this module from build.py, we can't init glb as a
# singleton here.  Or else Python will bug us with NoneType errors
# because of uninitialized context (ctx) because of exportFlags().
#
# We import this modue from build.py becase we need to reset/init glb
# for each build.
# See bug #2575
glb = None

def initVariables():
    global glb
    ctx.env = Env()
    ctx.dirs = Dirs()
    ctx.generals = Generals()
    glb = ctx


code:
# -*- coding: utf-8 -*-
#
# Copyright (C) 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.
#


code:
# -*- coding: utf-8 -*-
#
# Main fork Pisi: Copyright (C) 2005 - 2011, Tubitak/UEKAE
#
# Copyright (C) 2016 - 2018, Suleyman POYRAZ (Zaryob)
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# Please read the COPYING file.
#

"""conflict analyzer"""

import gettext

__trans = gettext.translation('inary', fallback=True)
_ = __trans.gettext

import inary.data.relation as relation

""" Conflict relation """

class Conflict(relation.Relation):
    def __str__(self):
        s = self.package
        if self.versionFrom:
            s += _(" version >= ") + self.versionFrom
        if self.versionTo:
            s += _(" version <= ") + self.versionTo
        if self.version:
            s += _(" version ") + self.version
        if self.releaseFrom:
            s += _(" release >= ") + self.releaseFrom
        if self.releaseTo:
            s += _(" release <= ") + self.releaseTo
        if self.release:
            s += _(" release ") + self.release
        return s

def installed_package_conflicts(confinfo):
    """determine if an installed package in *repository* conflicts with
given conflicting spec"""
    return relation.installed_package_satisfies(confinfo)

def package_conflicts(pkg, confs):
    for c in confs:
        if pkg.name == c.package and c.satisfies_relation(pkg.version, pkg.release):
            return c

    return None

def calculate_conflicts(order, packagedb):
    """
    Return a tuple of the conflicting packages information -> tuple
    @param order: list of package names -> list_of_strings
    @param packagedb: package database
    """

    # check conflicting packages in the installed system
    def check_installed(pkg, order):
        conflicts = []

        for conflict in pkg.conflicts:
            if conflict.package not in order and installed_package_conflicts(conflict):
                conflicts.append(conflict)

        return conflicts

    B_0 = set(order)
    conflicting_pkgs = conflicts_inorder = set()
    conflicting_pairs = {}

    for x in order:
        pkg = packagedb.get_package(x)

        # check if any package has conflicts with the installed packages
        conflicts = check_installed(pkg, order)
        if conflicts:
            conflicting_pairs[x] = [str(c) for c in conflicts]
            conflicting_pkgs = conflicting_pkgs.union([c.package for c in conflicts])

        # now check if any package has conflicts with each other
        B_i = B_0.intersection(set([c.package for c in pkg.conflicts]))
        conflicts_inorder_i = set()
        for p in [packagedb.get_package(x) for x in B_i]:
            conflicted = package_conflicts(p, pkg.conflicts)
            if conflicted:
                conflicts_inorder_i.add(str(conflicted))

        if conflicts_inorder_i:
            conflicts_inorder = conflicts_inorder.union(conflicts_inorder_i)
            conflicts_inorder.add(pkg.name)

    return conflicting_pkgs, conflicts_inorder, conflicting_pairs