Как установить включающий путь в коде Gjs?

Как я мог видеть, Gjs imports по умолчанию загружает только /usr/share/gjs-1.0 и /usr/lib/gjs-1.0. Я хочу разбить приложение на модули, как мы можем сделать с узлом, но я должен найти модули относительно файла сценария.

Я нашел два способа добавить пути включения:

  1. gjs --include-path=my-modules my-script.js
  2. GJS_PATH=my-modules gjs my-script.js

... но оба связаны с текущим каталогом, а не с файлом (незаметно), и их нужно было объявить в командной строке, что делало это излишне сложным.

Как я могу установить путь включения в коде Gjs? (Так что я могу сделать это относительно файла)

Или... Есть другой способ импортировать файлы из любого места, например, в python?

(Пожалуйста, вам не нужно предлагать использовать программу запуска шелл-скриптов для решения проблемы --include-path и GJS_PATH. Это очевидно, но менее эффективно. Если у нас нет лучшего решения, мы выживем с ним.)< /эм>


person Aurium    schedule 10.04.2012    source источник


Ответы (2)


Вам нужно установить или изменить imports.searchPath (что неочевидно, потому что не отображается с for (x in imports)print(x)). Итак, это:

imports.searchPath.unshift('.');
var foo = imports.foo;

импортирует файл «foo.js» как объект foo.

Это совместимо с Seed, хотя imports знает, что у него есть searchPath.

(Более ранние версии этого ответа были значительно менее точными и более провокационными. Извините).

person Douglas Bagnall    schedule 29.05.2012

Как говорит Дуглас, вам нужно изменить imports.searchPath, чтобы включить местоположение вашей библиотеки. Использовать . просто, но это зависит от того, что файлы всегда запускаются из одного и того же каталога. К сожалению, поиск каталога исполняемого в данный момент скрипта — это огромный хак. Вот как Gnome Shell делает это для API расширений

Я адаптировал это в следующую функцию для общего использования:

const Gio = imports.gi.Gio;

function getCurrentFile() {
    let stack = (new Error()).stack;

    // Assuming we're importing this directly from an extension (and we shouldn't
    // ever not be), its UUID should be directly in the path here.
    let stackLine = stack.split('\n')[1];
    if (!stackLine)
        throw new Error('Could not find current file');

    // The stack line is like:
    //   init([object Object])@/home/user/data/gnome-shell/extensions/[email protected]/prefs.js:8
    //
    // In the case that we're importing from
    // module scope, the first field is blank:
    //   @/home/user/data/gnome-shell/extensions/[email protected]/prefs.js:8
    let match = new RegExp('@(.+):\\d+').exec(stackLine);
    if (!match)
        throw new Error('Could not find current file');

    let path = match[1];
    let file = Gio.File.new_for_path(path);
    return [file.get_path(), file.get_parent().get_path(), file.get_basename()];
}

Вот как вы можете использовать его из файла точки входа app.js после определения функции getCurrentFile:

let file_info = getCurrentFile();

// define library location relative to entry point file
const LIB_PATH = file_info[1] + '/lib';
// then add it to the imports search path
imports.searchPath.unshift(LIB_PATH);

Ви! теперь импортировать наши библиотеки очень просто:

// import your app libraries (if they were in lib/app_name)
const Core = imports.app_name.core;
person Just Jake    schedule 29.12.2012
comment
IME немного изменился формат строки стека; теперь он включает второе двоеточие и число, предположительно номер столбца. Я изменил регулярное выражение на /@(.+?)(?::\d+){1,2}/ - person realh; 03.06.2019