[gnome-builder] npm: add npm build system plugin



commit 31b7629cb6a0e9b7569340191dc96fb69351f836
Author: Giovanni Campagna <gcampagn cs stanford edu>
Date:   Thu Jun 29 10:41:04 2017 -0700

    npm: add npm build system plugin
    
    Recognizes "package.json" as a valid project file (instead of using
    the directory type), and runs "npm install" while building.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=784358

 meson_options.txt         |    1 +
 plugins/meson.build       |    2 +
 plugins/npm/meson.build   |   13 +++++
 plugins/npm/npm.plugin    |   11 +++++
 plugins/npm/npm_plugin.py |  108 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 135 insertions(+), 0 deletions(-)
---
diff --git a/meson_options.txt b/meson_options.txt
index c997017..99b5d0e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -52,6 +52,7 @@ option('with_meson_templates', type: 'boolean', value: false)
 option('with_mingw', type: 'boolean')
 option('with_mono', type: 'boolean')
 option('with_notification', type: 'boolean')
+option('with_npm', type: 'boolean')
 option('with_phpize', type: 'boolean')
 option('with_project_tree', type: 'boolean')
 option('with_python_gi_imports_completion', type: 'boolean')
diff --git a/plugins/meson.build b/plugins/meson.build
index 64c7d31..4b0792a 100644
--- a/plugins/meson.build
+++ b/plugins/meson.build
@@ -41,6 +41,7 @@ subdir('meson-templates')
 subdir('mingw')
 subdir('mono')
 subdir('notification')
+subdir('npm')
 subdir('phpize')
 subdir('project-tree')
 subdir('python-gi-imports-completion')
@@ -91,6 +92,7 @@ status += [
   'MinGW ................. : @0@'.format(get_option('with_mingw')),
   'Mono .................. : @0@'.format(get_option('with_mono')),
   'Notifications ......... : @0@'.format(get_option('with_notification')),
+  'Node Package Manager .. : @0@'.format(get_option('with_npm')),
   'PHPize ................ : @0@'.format(get_option('with_phpize')),
   'Project Tree .......... : @0@'.format(get_option('with_project_tree')),
   'Python GI Completion .. : @0@'.format(get_option('with_python_gi_imports_completion')),
diff --git a/plugins/npm/meson.build b/plugins/npm/meson.build
new file mode 100644
index 0000000..cd9678b
--- /dev/null
+++ b/plugins/npm/meson.build
@@ -0,0 +1,13 @@
+if get_option('with_npm')
+
+install_data('npm_plugin.py', install_dir: plugindir)
+
+configure_file(
+          input: 'npm.plugin',
+         output: 'npm.plugin',
+  configuration: configuration_data(),
+        install: true,
+    install_dir: plugindir,
+)
+
+endif
diff --git a/plugins/npm/npm.plugin b/plugins/npm/npm.plugin
new file mode 100644
index 0000000..f3f4083
--- /dev/null
+++ b/plugins/npm/npm.plugin
@@ -0,0 +1,11 @@
+[Plugin]
+Module=npm_plugin
+Loader=python3
+Name=NPM/nodejs
+Description=Provides integration with the NPM package system
+Authors=Giovanni Campagna <gcampagn cs stanford edu>
+Copyright=Copyright © 2016 Christian Hergert, 2017 Giovanni Campagna
+Builtin=true
+Hidden=true
+X-Project-File-Filter-Pattern=package.json
+X-Project-File-Filter-Name=NPM package (package.json)
diff --git a/plugins/npm/npm_plugin.py b/plugins/npm/npm_plugin.py
new file mode 100644
index 0000000..3230458
--- /dev/null
+++ b/plugins/npm/npm_plugin.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python3
+
+#
+# npm_plugin.py
+#
+# Copyright (C) 2016 Christian Hergert <chris dronelabs com>
+#               2017 Giovanni Campagna <gcampagn cs stanford edu>
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import gi
+import threading
+import os
+
+gi.require_version('Ide', '1.0')
+
+from gi.repository import Gio
+from gi.repository import GLib
+from gi.repository import GObject
+from gi.repository import Ide
+
+class NPMBuildSystem(Ide.Object, Ide.BuildSystem, Gio.AsyncInitable):
+    project_file = GObject.Property(type=Gio.File)
+
+    def do_get_id(self):
+        return 'npm'
+
+    def do_get_display_name(self):
+        return 'NPM (node.js)'
+
+    def do_init_async(self, io_priority, cancellable, callback, data):
+        task = Gio.Task.new(self, cancellable, callback)
+
+        # This is all done synchronously, doing it in a thread would probably
+        # be somewhat ideal although unnecessary at this time.
+
+        try:
+            # Maybe this is a package.json
+            if self.props.project_file.get_basename() in ('package.json',):
+                task.return_boolean(True)
+                return
+
+            # Maybe this is a directory with a package.json
+            if self.props.project_file.query_file_type(0) == Gio.FileType.DIRECTORY:
+                child = self.props.project_file.get_child('package.json')
+                if child.query_exists(None):
+                    self.props.project_file = child
+                    task.return_boolean(True)
+                    return
+        except Exception as ex:
+            task.return_error(ex)
+
+        task.return_error(Ide.NotSupportedError())
+
+    def do_init_finish(self, task):
+        return task.propagate_boolean()
+
+    def do_get_priority(self):
+        return 300
+
+class NPMPipelineAddin(Ide.Object, Ide.BuildPipelineAddin):
+    """
+    The NPMPipelineAddin is responsible for creating the necessary build
+    stages and attaching them to phases of the build pipeline.
+    """
+
+    def do_load(self, pipeline):
+        context = self.get_context()
+        build_system = context.get_build_system()
+
+        # Ignore pipeline unless this is a npm/nodejs project
+        if type(build_system) != NPMBuildSystem:
+            return
+
+        package_json = build_system.props.project_file
+        config = pipeline.get_configuration()
+        system_type = config.get_device().get_system_type()
+        builddir = pipeline.get_builddir()
+        runtime = config.get_runtime()
+
+        npm = 'npm'
+        if config.getenv('NPM'):
+            npm = config.getenv('NPM')
+        elif not runtime.contains_program_in_path('npm'):
+            raise OSError('The runtime must contain nodejs/npm to build npm modules')
+
+        # Fetch dependencies so that we no longer need network access
+        fetch_launcher = pipeline.create_launcher()
+        fetch_launcher.set_cwd(package_json.get_parent().get_path())
+        fetch_launcher.push_argv(npm)
+        if Ide.get_system_type() != system_type:
+            fetch_launcher.push_argv('--arch')
+            fetch_launcher.push_argv(system_type)
+        fetch_launcher.push_argv('install')
+        self.track(pipeline.connect_launcher(Ide.BuildPhase.DOWNLOADS, 0, fetch_launcher))
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]