Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C API: Import Handler - Get Path of File Containing @import Statement #2348

Closed
bdkjones opened this issue Mar 9, 2017 · 13 comments
Closed

Comments

@bdkjones
Copy link

bdkjones commented Mar 9, 2017

This page documents the C API for @import handlers.

I would suggest updating these docs to show how the implementor can retrieve the absolute path of the file containing the @import statement that's being handled.

I've attempted to get that information the same way I get it in my @warn and @debug function handlers:

size_t idx = sass_compiler_get_callee_stack_size(comp);
if (idx <= 0) {
    return NULL;  // Avoid the out-of-bounds exception.
}

Sass_Callee_Entry entry = NULL;
entry = sass_compiler_get_callee_entry(comp, idx - 1);

if (entry == NULL) {
    return NULL;
}

// Get the path to the file containing this @import statement
const char *filePathOnDisk = sass_callee_get_path(entry);

When this runs, however, idx is always zero and thus there is no callee_entry to query for its path. I looked through the headers, but didn't see an alternative. What's the correct way to do this? And can we update that documentation page to show it?

@bdkjones
Copy link
Author

bdkjones commented Mar 9, 2017

I do see the sass_compiler_get_import_stack_size() and sass_compiler_get_import_entry() functions, but these return a Sass_Import_Entry. The entry struct has sass_import_get_abs_path(), but the header indicates that function returns the absolute path after my import function has resolved it. What I'm looking for is the absolute path of the file containing the @import. I'm sure I'm just missing it, so an example in the importer docs would be helpful.

@bdkjones
Copy link
Author

bdkjones commented Mar 9, 2017

Well, after trying it out, it looks like that sass_import_get_abs_path() does return the absolute path of the file containing the @import statement. But this page has a comment next to abs_path which says, "path after importer has resolved it". That led me to believe abs_path wouldn't be relevant until my importer had resolved and set it.

I guess I just need to confirm that this is the correct approach:

Sass_Import_List glob_importer(const char* path, Sass_Importer_Entry cb, struct Sass_Compiler* comp)
{    
    size_t idx = sass_compiler_get_import_stack_size(comp);
    if (idx <= 0) {
        // Avoid the out-of-bounds exception.
        return NULL;
    }

    Sass_Import_Entry entry = NULL;
    entry = sass_compiler_get_import_entry(comp, idx - 1);

    if (entry == NULL) {
        return NULL;
    }

    // Get the path to the file containing this @import statement
    const char *filePathOnDisk = sass_import_get_abs_path(entry);

    // Do stuff
}

@mgreter
Copy link
Contributor

mgreter commented Mar 10, 2017

The callee stack and import stack are two seperate things. Please always provide the used libsass version! I've added more API functions in this regard very recently, so I'm not sure you already got that changes!

@bdkjones
Copy link
Author

I'm working with Libsass 3.5.0 Beta 3. The latest tagged release on GitHub.

@mgreter
Copy link
Contributor

mgreter commented Mar 10, 2017

In that case your approach seems to be correct AFAICT!

@bdkjones
Copy link
Author

So abs_path of a Sass_Import_Entry is always the absolute path of the file containing the @import statement and NOT the absolute path of the file BEING imported?

If so, I'd recommend adding a note to the docs and maybe include an example of this process on the import-handler examples page.

@mgreter
Copy link
Contributor

mgreter commented Mar 10, 2017

I can't tell you that on top of my head. It may also depend if you are querying it during the import phase or during execution phase. Doc PRs are always welcome!

@mgreter
Copy link
Contributor

mgreter commented Mar 10, 2017

Generally speaking abs_path could be anything and not only a "path" (eg. a url). It contains the string custom importer returns (which should be built from the parent abs_path and the given imp_path, if imp_path is not yet absolute itself). Btw. you haven't really clarified if you access this info from an importer or from a function! During imports the "currrent" is not yet put on the import stack AFAIR.

@bdkjones
Copy link
Author

I'm accessing the info from an importer. I'm adding a custom importer to support basic globbing (yep, I know it's a terrible idea, but the world is full of people who just want to make their lives difficult).

I have a file named main.scss with @import "neat";. Using the above approach in my import-handler, I get the following:

@import found for path: neat
Path on disk: /Users/bdkjones/Desktop/neattest/main.scss

It would appear that abs_path contains the path of the file that has the @import statement, at least during the "resolve imports" stage.

It's a little strange that abs_path changes. I would have expected it to be NULL before my custom import-handler resolved the @import statement. Perhaps a better approach would be to add a new property to Sass_Import_Entry that always contains the absolute path of the file containing the @import statement? Something like parent_abs_path?

@bdkjones
Copy link
Author

Although that wouldn't be relevant in cases where @import is resolved as source-content rather than passing file paths back to Libsass (such as when loading a remote resource). I dunno...this is why you guys are the API designers and I just file issues!

@mgreter
Copy link
Contributor

mgreter commented Mar 10, 2017

For globbing please refer to this implementation:
https://github.com/mgreter/libsass-glob

@mgreter
Copy link
Contributor

mgreter commented Mar 10, 2017

It would appear that abs_path contains the path of the file that has the @import statement, at least during the "resolve imports" stage.

You don't give enough details for me to understand which abs_path you actually mean. From the passed import to the custom importer or from the import stack, etc. As I said, we cannot know if you want to work with filepaths or any other scheme. So the abs_path is not a path (directory) but the full file path, so in case you want to work with filepaths, you need to remove the filename from the path (i.e. dirname).

@bdkjones
Copy link
Author

From the passed import to the custom importer.

That reference implementation of globbing is perfect! Perhaps a link to that on the docs page for custom importers would be useful. Besides updating the docs, though, I don't think this is an open issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants