ubuntu / ubuntu-make

Easy setup of common tools for developers on Ubuntu.
GNU General Public License v3.0
1.19k stars 189 forks source link

Intel XDK support ? #124

Closed leogaggl closed 7 years ago

leogaggl commented 9 years ago

Is there any interest in adding the Intel XDK as a supported tool in Ubuntu Make ?

https://software.intel.com/en-us/intel-xdk

Their Linux support is quite good and the 64bit version works well on 15.04 (and previously on 14.04).

thagabe commented 9 years ago

I second this. It would be much easier to use ubuntu make to install XDK to start working on the intel edison.

didrocks commented 9 years ago

Hey Leo,

that sounds like a nice idea, I would need to look a little bit closer to it to be able to have more knowledge about their sdk story, but as deep as I looked right now, it seems to fit the goal of Ubuntu Make quite well. I'm happy to help guiding for adding this sdk support to Ubuntu make to whoever gets to it before me though :)

thagabe commented 9 years ago

I've tried to learn how ubuntu-make works (mind you I have little to no python experience) and under ./ubuntu-make/umake/freameworks/web.py I've added this:

class IntelXDK(umake.frameworks.baseinstaller.BaseInstaller):

    def __init__(self, category):
        super().__init__(name="Intel XDK", description=_("Intel's XDK tool for developing web apps including HTML, CSS, JavaScript, and Node"),
                         category=category, only_on_archs=_supported_archs,
                         download_page=None,
                         dir_to_decompress_in_tarball="intel-xdk",
                         desktop_filename="intel-xdk.desktop")

    def download_provider_page(self):
        """Skip download provider page and directly use the download links"""

        arch = platform.machine()
        intel_version='2248'
        tag_machine = '32'
        if arch == 'x86_64':
            tag_machine = '64'
        self.download_requests.append(DownloadItem(
            "https://download.xdk.intel.com/xdk_web_linux{0}_master_{1}.tgz".format(tag_machine, intel_version),
            Checksum(None, None)))
        self.start_download_and_install()

    def post_install(self):
        """Create the Intel XDK Developer launcher"""
        create_launcher(self.desktop_filename, get_application_desktop_file(name=_("Intel XDK"),
                        icon_path=os.path.join(self.install_path, "browser", "icons", "mozicon128.png"),
                        exec=os.path.join(self.install_path, "intel-xdk"),
                        comment=_("Intel's XDK tool for developing web apps"),
                        categories="Development;IDE;"))

    @property
    def is_installed(self):
        # check path and requirements
        if not super().is_installed:
            return False
        if not os.path.isfile(os.path.join(self.install_path, "intel-xdk")):
            logger.debug("{} binary isn't installed".format(self.name))
            return False
        return True

I'm confused in two places 1) what does the self.start_download_and_install() ? Like How would it extract the XDK's tar and place everything it needs on the right places?

2) In the icon_path=os.path.join(self.install_path, "browser", "icons", "mozicon128.png"), How could I change the variables to make it work for the XDK?

Thank you.

didrocks commented 9 years ago

Thanks for starting working on this, much appreciated!

It seems that Intel's SDK is a very simple webpage with no additional magic. I would rather start from the AndroidStudio class at umake/frameworks/android.py which is the most generic case. Basically you only need to implement init, is_installed, post_install (as you have already done) and parse_download_link() instead of download_provider_page.

You provide the page to download in download_page= in init(), this fetches the webpage and you parse its content to always download the latest one and return the value (with a checksum, ideally if provided).

Those frameworks inherits from the BaseInstaller class which is doing the heavy lifting like downloading, extracting and installing at the right location. So, I would really go into that direction :)

To answer your question: 1) self.start_download_and_install() will start in an async way to download the returned value of parse_download_link() (helped by the BaseInstaller default behavior which appends them to self.download_requests list, as you did here). It will also install any needed packages that you may have provided in packages_requirements=, requesting root access only for that subprocess. Then, it will extract to the user's runtime provided location from the downloaded archive using something like "tar xf ". So the value of dir_to_decompress_in_tarball= is important. If you want to extract everything from the archive (meaning, there is no subdirectory), just ommit that parameter in init().

2) Not sure to understand that question. I guess the Intel SDK has an icon you can use, right? As you changed it for the exec path, look for an interesting one provided in the Intel SDK and direct to it. If the Intel SDK doesn't have any IDE or visual component, maybe look at umake/frameworks/go.py which will be closer to what you are looking for? (there is no launcher, so no icon and we add the tools to the PATH).

I hope that shed some lights and give you correct pointers. Do not hesitate if you have any other questions! Once you are done with installing the SDK successfully, we'll work together on the tests, but that would be for later. :)

thagabe commented 9 years ago

@didrocks Trying again with parse_download_link() but I'm not understanding how it's done. for example what does this do:

return self.category.parse_download_link('id="linux-bundle"', line, in_download)

for example

self.download_requests.append(DownloadItem(
            "https://download.xdk.intel.com/xdk_web_linux{0}_master_{1}.tgz".format(tag_machine, intel_version),
            Checksum(None, None)))

makes sense but the .parse_download_link doesn't really have much info. Where does line and _indownload come from? Can I use DownloadItem() under parse_download_link? Sorry if these are dumb questions!

didrocks commented 9 years ago

Hey thagabe!

So, as you can see, I'm calling self.category.parse_download_link() method (which is in the associated category in the main file). That was because I shared the implementation are shared Android Studio and Android NDK framework (and Eclipse ADT in the past).

Basically the function is doing this:

def parse_download_link(self, line, in_download):
    url, md5sum = (None, None)
    if 'id="linux-bundle"' in line:
        in_download = True
    if in_download:
        p = re.search(r'href="(.*)"', line)
        with suppress(AttributeError):
            url = p.group(1)
        p = re.search(r'<td>(\w+)</td>', line)
        with suppress(AttributeError):
            # ensure the size can match a md5 or sha1 checksum
            if len(p.group(1)) > 15:
                md5sum = p.group(1)
        if "</tr>" in line:
            in_download = False

    if url is None and md5sum is None:
        return (None, in_download)
    return ((url, md5sum), in_download)

It's a helper to parse a web page easily. Basically the function is called each line from the downlodaed web page by the BaseInstaller (see the line variable). "in_download" can be set by yourself and the previous value will be returned back from the next line (see that as a sticky local variable). This can help you in case the download url is in multiple lines. So basically, you try to grab the right download link from "line" and checksum and you return them if you find it. Then, the BaseInstaller will automatically install them, extract, install dependencies and verify the checksum if provided.

Does this make more sense? (DownloadItem() and such will be constructed for you from it).

Also, if the Intel XDK requires a license to accept, there is the same logic for parsing and returning the license from the "parse_license()" method.

I hope this shed some lights, do not hesitate if you have more questions!

thagabe commented 9 years ago

@didrocks Tried my hand at this again and I have gotten the logic for most of it:

class IntelXDK(umake.frameworks.baseinstaller.BaseInstaller):

    def __init__(self, category):
        super().__init__(name="Intel XDK", description=_("Intel's XDK tool for developing web apps including HTML, CSS, JavaScript, and Node"),
                         category=category, only_on_archs=_supported_archs,
                         download_page="https://download.xdk.intel.com/",
                         checksum_type=none,
                         dir_to_decompress_in_tarball="xdk_web",
                         desktop_filename="intel-xdk.desktop")

    def parse_download_link(self, line, in_download):
        """Parse Intel XDK download link, expect to find a url"""
        arch = platform.machine()
        intel-version='2248'
        tag_machine = '64'
        if arch == 'i686':
            tag_machine = '32'
        return self.category.parse_download_link('xdk_web_linux{0}_master_{1}}.tgz'.format(tag_machine, intel-version), line, in_download)

    def post_install(self):
        """Create the Intel XDK launcher"""
        create_launcher(self.desktop_filename, get_application_desktop_file(name=_("Intel XDK"),
                        icon_path=os.path.join(self.install_path, "bin", "studio.png"),
                        exec='"{}" %f'.format(os.path.join(self.install_path, "bin", "studio.sh")),
                        comment=_("Intel's XDK tool for developing web apps"),
                        categories="Development;IDE;"))

    @property
    def is_installed(self):
        # check path and requirements
        if not super().is_installed:
            return False
        if not os.path.isfile(os.path.join(self.install_path, "bin", "studio.sh")):
            logger.debug("{} binary isn't installed".format(self.name))
            return False
        return True

However, the parts I really need to work in is the untaring and how to correctly place the packages! Since the way Intel would want you to do it is by their installer provided inside the tar which is gui based (umake uses the unprivileged user correct? or does it use sudo?). There is probably a way to run the installer in silent mode with the correct parameters (just a matter of specifying that the desktop icon and the actual application be installed under ~/.local/share/applications/... and ~/tools/... respectively). Well I'm going to keep looking around for a way to implement this asap.

didrocks commented 9 years ago

Hey @thagabe, the first part of your work looks good (you can commit a make a git branch maybe? That would be easier to review).

I'm getting an access denied on the download intel page, maybe that's transient… If they have any checksum system, please hook this in! The tarball download will be then chcked for you.

A note: I doubt intel-version works as a name variable (python doesn't like - in variable name), intel_version would be better then!

I don't think your category has a parse_download_link method, I guess you should replace with the whole regexp function in my previous message to do the parsing :)

To answer your question: yeah, umake use unpriviledged user for untarring and extract things. It only uses sudo in a separate process for installing packages dependency if any (and if not already installed). Good luck for looking on how they are running the installer in silent mode (I do really hope it's possible). Do not forget to show any license agreement they may present to the user as we want to show them to our users as well.

mhalano commented 8 years ago

Any news here? I was suggest the Intel XDK too.

LyzardKing commented 7 years ago

It's not immediate to find the url in the download page. This needs some work to find a page we can parse

LyzardKing commented 7 years ago

Closing the issue since the intel XDK is now discontinued. The last tarballs are available at the same page.