{"action":"created","comment":{"url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/comments/34530925","id":34530925,"diff_hunk":"@@ -0,0 +1,244 @@\n+\"use strict\";\n+\n+var fs = require(\"fs\");\n+var fse = require(\"fs-extra\");\n+var glob = require(\"glob\");\n+var path = require(\"path\");\n+var hash = require(\"./util/hash\");\n+var unquote = require(\"./util/unquote\");\n+\n+\n+/* class AssetPathEntry\n+ *\n+ * srcPath - directory where assets are sourced.\n+ * Option: name [Optional] - The logical name of this path entry. When specified,\n+ *   the source url of an asset in this directory will be of the form\n+ *   \"<name>/path/relativeTo/srcPath.ext\".\n+ * Option: httpPrefix [Optional] - The http prefix where the assets url should be anchored\n+ *   \"url(<httpPrefix>/path/relativeTo/srcPath.ext)\". Defaults to \"/<name>\" or just \"/\"\n+ *   when there is no name.\n+ * Option: pattern [Optional] - A glob pattern that controls what files can be in this asset path.\n+ *   Defaults to \"**\\/*\".\n+ * Option: globOpts [Optional] - Options to use for globbing.\n+ *   See: https://github.com/isaacs/node-glob#options\n+ */\n+function AssetPathEntry(srcPath, opts) {\n+  opts = opts || {};\n+  if (!fs.statSync(srcPath).isDirectory()) {\n+    throw new Error(\"Expected \" + srcPath + \" to be a directory.\");\n+  }\n+  this.name = opts.name || null;\n+  this.httpPrefix = opts.httpPrefix || opts.name;\n+  this.srcPath = srcPath;\n+  this.pattern = opts.pattern || \"**/*\";\n+  this.globOpts = {};\n+  hash.merge(this.globOpts, this.defaultGlobOpts);\n+  if (opts.globOpts) {\n+    hash.merge(this.globOpts, opts.globOpts);\n+  }\n+  this.globOpts.cwd = this.srcPath; // cannot be overridden by globOpts\n+  this.globOpts.root = this.srcPath; // cannot be overridden by globOpts\n+}\n+\n+function quoted(string) {\n+  return string ? '\"' + string + '\"' : string;\n+}\n+\n+function resolveModuleName(assetPathEntry, defaultName) {\n+  return assetPathEntry.name || defaultName;\n+}\n+\n+AssetPathEntry.prototype = {\n+  defaultGlobOpts: {\n+    follow: true,\n+    nodir: true\n+  },\n+  asRegistrationString: function(defaultName) {\n+    var files = glob.sync(this.pattern, this.globOpts);\n+    var assetMap = [];\n+    var self = this;\n+    files.forEach(function(file) {\n+      // TODO: handle windows error\n+      var uri = self.httpPrefix;\n+      var moduleName = resolveModuleName(self, defaultName);\n+\n+      // TODO: do this in a helper function\n+      if (uri && moduleName) {\n+        uri = uri + \"/\" + moduleName;\n+      } else if (moduleName) {\n+        uri = moduleName;\n+      }\n+\n+      if (uri) {\n+        uri = uri + \"/\" + file;\n+      } else {\n+        uri = file;\n+      }\n+\n+      assetMap.push('\"' + file + '\": (filepath: \"' + path.join(self.srcPath, file) + '\", uri: \"' + uri + '\")');\n+    });\n+    return \"@include register-assets(\" +\n+             (quoted(resolveModuleName(this, defaultName)) || \"null\") + \", \" +\n+             \"(\" + assetMap.join(\",\\n  \") + \"));\";\n+  },\n+  toString: function() {\n+    return \"<\" + this.pattern + \" within \" + this.sourcePath + \">\";\n+  }\n+};\n+\n+\n+function AssetCollection() {\n+  this.assetPath = [];\n+}\n+\n+AssetCollection.prototype = {\n+  /* See: AssetPathEntry */\n+  addSource: function(srcPath, opts) {\n+    this.assetPath.push(new AssetPathEntry(srcPath, opts));\n+    return this;\n+  },\n+  asAssetImport: function (defaultName) {\n+    var scssString = ['@import \"eyeglass/assets\";'];\n+    this.assetPath.forEach(function(pathEntry) {\n+      scssString.push(pathEntry.asRegistrationString(defaultName));\n+    });\n+    var importString = scssString.join(\"\\n\");\n+    return importString;\n+  }\n+};\n+\n+function chainableExport(srcPath, opts) {\n+  return this.addSource(srcPath, opts);\n+}\n+\n+function newExportableAssetCollection(srcPath, opts) {\n+    var assets = new AssetCollection();\n+    assets.export = chainableExport;\n+    return assets.export(srcPath, opts);\n+}\n+\n+function resolveAsset(sass, sassUtils, registeredAssetsMap, relativePathString) {\n+  registeredAssetsMap = sassUtils.handleEmptyMap(registeredAssetsMap);\n+  sassUtils.assertType(registeredAssetsMap, \"map\");\n+  sassUtils.assertType(relativePathString, \"string\");\n+\n+  var relativePath = unquote(relativePathString.getValue());\n+  var registeredAssets = sassUtils.castToJs(registeredAssetsMap);\n+\n+  var appAssets = registeredAssets.coerce.get(null);\n+  if (appAssets) {\n+    // XXX sassUtils.assertType(appAssets, \"map\");\n+    var appAsset = appAssets.coerce.get(relativePath);\n+    if (appAsset) {\n+      return appAsset;\n+    }\n+  }\n+\n+  var segments = relativePath.split(\"/\");","path":"lib/assets.js","position":137,"original_position":137,"commit_id":"b9b47460f566f947253bd201f51993eb8abe2caf","original_commit_id":"4a7fbd904a0d03c4decd483b9f2f556113bf75ea","user":{"login":"chriseppstein","id":1839,"avatar_url":"https://avatars.githubusercontent.com/u/1839?v=3","gravatar_id":"","url":"https://api.github.com/users/chriseppstein","html_url":"https://github.com/chriseppstein","followers_url":"https://api.github.com/users/chriseppstein/followers","following_url":"https://api.github.com/users/chriseppstein/following{/other_user}","gists_url":"https://api.github.com/users/chriseppstein/gists{/gist_id}","starred_url":"https://api.github.com/users/chriseppstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chriseppstein/subscriptions","organizations_url":"https://api.github.com/users/chriseppstein/orgs","repos_url":"https://api.github.com/users/chriseppstein/repos","events_url":"https://api.github.com/users/chriseppstein/events{/privacy}","received_events_url":"https://api.github.com/users/chriseppstein/received_events","type":"User","site_admin":false},"body":"Yes. We need to fix this.","created_at":"2015-07-14T01:41:59Z","updated_at":"2015-07-14T01:41:59Z","html_url":"https://github.com/sass-eyeglass/eyeglass/pull/48#discussion_r34530925","pull_request_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48","_links":{"self":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/comments/34530925"},"html":{"href":"https://github.com/sass-eyeglass/eyeglass/pull/48#discussion_r34530925"},"pull_request":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48"}}},"pull_request":{"url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48","id":39640565,"html_url":"https://github.com/sass-eyeglass/eyeglass/pull/48","diff_url":"https://github.com/sass-eyeglass/eyeglass/pull/48.diff","patch_url":"https://github.com/sass-eyeglass/eyeglass/pull/48.patch","issue_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/48","number":48,"state":"open","locked":false,"title":"Assets","user":{"login":"chriseppstein","id":1839,"avatar_url":"https://avatars.githubusercontent.com/u/1839?v=3","gravatar_id":"","url":"https://api.github.com/users/chriseppstein","html_url":"https://github.com/chriseppstein","followers_url":"https://api.github.com/users/chriseppstein/followers","following_url":"https://api.github.com/users/chriseppstein/following{/other_user}","gists_url":"https://api.github.com/users/chriseppstein/gists{/gist_id}","starred_url":"https://api.github.com/users/chriseppstein/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/chriseppstein/subscriptions","organizations_url":"https://api.github.com/users/chriseppstein/orgs","repos_url":"https://api.github.com/users/chriseppstein/repos","events_url":"https://api.github.com/users/chriseppstein/events{/privacy}","received_events_url":"https://api.github.com/users/chriseppstein/received_events","type":"User","site_admin":false},"body":"Ok. Assets are here and they are a little different than we designed initially. The biggest change is because node-sass does not tell custom Sass function (in javascript) what Sass file it was called from. Instead, we have implemented as asset registration system based on the importer mechanism and I actually really like this. There is a global map `$eg-registered-assets` which lists all the assets that you import. There is a special import `@import \"assets\"` which will register the assets for the current application or eyeglass module. You can also `@import \"module-name/assets\"` for any direct dependency module that the current sass file belongs to.\r\n\r\nAssets that are exposed by importing are registered in applications by calling `eyeglass.assets.addSource(...)` and in plugins by setting the assets property in eyeglass-exports to `eyeglass.assets.export(...)`. Export is basically an alias for addSource, I just like how it sounded for the plugin use case.\r\n\r\nCode review please.\r\n\r\nPing: @Jakobo @eoneill @scottdavis \r\n\r\nRemaining tasks for assets:\r\n\r\n- [ ] Documentation\r\n- [ ] make asset registration functions (in addition to the mixins)\r\n- [ ] expose asset resolution public js api for eyeglass map\r\n- [ ] Bring up test coverage so CI pass","created_at":"2015-07-09T23:52:39Z","updated_at":"2015-07-14T01:41:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"576c56d07e05b5df48332ffe94de310e8bb8aa67","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48/commits","review_comments_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48/comments","review_comment_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/comments{/number}","comments_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/48/comments","statuses_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/statuses/b9b47460f566f947253bd201f51993eb8abe2caf","head":{"label":"sass-eyeglass:assets","ref":"assets","sha":"b9b47460f566f947253bd201f51993eb8abe2caf","user":{"login":"sass-eyeglass","id":10853331,"avatar_url":"https://avatars.githubusercontent.com/u/10853331?v=3","gravatar_id":"","url":"https://api.github.com/users/sass-eyeglass","html_url":"https://github.com/sass-eyeglass","followers_url":"https://api.github.com/users/sass-eyeglass/followers","following_url":"https://api.github.com/users/sass-eyeglass/following{/other_user}","gists_url":"https://api.github.com/users/sass-eyeglass/gists{/gist_id}","starred_url":"https://api.github.com/users/sass-eyeglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sass-eyeglass/subscriptions","organizations_url":"https://api.github.com/users/sass-eyeglass/orgs","repos_url":"https://api.github.com/users/sass-eyeglass/repos","events_url":"https://api.github.com/users/sass-eyeglass/events{/privacy}","received_events_url":"https://api.github.com/users/sass-eyeglass/received_events","type":"Organization","site_admin":false},"repo":{"id":30313796,"name":"eyeglass","full_name":"sass-eyeglass/eyeglass","owner":{"login":"sass-eyeglass","id":10853331,"avatar_url":"https://avatars.githubusercontent.com/u/10853331?v=3","gravatar_id":"","url":"https://api.github.com/users/sass-eyeglass","html_url":"https://github.com/sass-eyeglass","followers_url":"https://api.github.com/users/sass-eyeglass/followers","following_url":"https://api.github.com/users/sass-eyeglass/following{/other_user}","gists_url":"https://api.github.com/users/sass-eyeglass/gists{/gist_id}","starred_url":"https://api.github.com/users/sass-eyeglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sass-eyeglass/subscriptions","organizations_url":"https://api.github.com/users/sass-eyeglass/orgs","repos_url":"https://api.github.com/users/sass-eyeglass/repos","events_url":"https://api.github.com/users/sass-eyeglass/events{/privacy}","received_events_url":"https://api.github.com/users/sass-eyeglass/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sass-eyeglass/eyeglass","description":"NPM Modules for Sass","fork":false,"url":"https://api.github.com/repos/sass-eyeglass/eyeglass","forks_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/forks","keys_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/teams","hooks_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/hooks","issue_events_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/events{/number}","events_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/events","assignees_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/assignees{/user}","branches_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/branches{/branch}","tags_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/tags","blobs_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/refs{/sha}","trees_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/statuses/{sha}","languages_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/languages","stargazers_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/stargazers","contributors_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/contributors","subscribers_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/subscribers","subscription_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/subscription","commits_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/commits{/sha}","git_commits_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/commits{/sha}","comments_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/comments{/number}","issue_comment_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/comments{/number}","contents_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/contents/{+path}","compare_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/merges","archive_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/downloads","issues_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues{/number}","pulls_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls{/number}","milestones_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/milestones{/number}","notifications_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/labels{/name}","releases_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/releases{/id}","created_at":"2015-02-04T18:21:33Z","updated_at":"2015-07-13T18:33:50Z","pushed_at":"2015-07-14T01:38:38Z","git_url":"git://github.com/sass-eyeglass/eyeglass.git","ssh_url":"git@github.com:sass-eyeglass/eyeglass.git","clone_url":"https://github.com/sass-eyeglass/eyeglass.git","svn_url":"https://github.com/sass-eyeglass/eyeglass","homepage":null,"size":543,"stargazers_count":321,"watchers_count":321,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":8,"forks":13,"open_issues":8,"watchers":321,"default_branch":"master"}},"base":{"label":"sass-eyeglass:master","ref":"master","sha":"61bfaaefbace0f27873621695e14768445ec0005","user":{"login":"sass-eyeglass","id":10853331,"avatar_url":"https://avatars.githubusercontent.com/u/10853331?v=3","gravatar_id":"","url":"https://api.github.com/users/sass-eyeglass","html_url":"https://github.com/sass-eyeglass","followers_url":"https://api.github.com/users/sass-eyeglass/followers","following_url":"https://api.github.com/users/sass-eyeglass/following{/other_user}","gists_url":"https://api.github.com/users/sass-eyeglass/gists{/gist_id}","starred_url":"https://api.github.com/users/sass-eyeglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sass-eyeglass/subscriptions","organizations_url":"https://api.github.com/users/sass-eyeglass/orgs","repos_url":"https://api.github.com/users/sass-eyeglass/repos","events_url":"https://api.github.com/users/sass-eyeglass/events{/privacy}","received_events_url":"https://api.github.com/users/sass-eyeglass/received_events","type":"Organization","site_admin":false},"repo":{"id":30313796,"name":"eyeglass","full_name":"sass-eyeglass/eyeglass","owner":{"login":"sass-eyeglass","id":10853331,"avatar_url":"https://avatars.githubusercontent.com/u/10853331?v=3","gravatar_id":"","url":"https://api.github.com/users/sass-eyeglass","html_url":"https://github.com/sass-eyeglass","followers_url":"https://api.github.com/users/sass-eyeglass/followers","following_url":"https://api.github.com/users/sass-eyeglass/following{/other_user}","gists_url":"https://api.github.com/users/sass-eyeglass/gists{/gist_id}","starred_url":"https://api.github.com/users/sass-eyeglass/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sass-eyeglass/subscriptions","organizations_url":"https://api.github.com/users/sass-eyeglass/orgs","repos_url":"https://api.github.com/users/sass-eyeglass/repos","events_url":"https://api.github.com/users/sass-eyeglass/events{/privacy}","received_events_url":"https://api.github.com/users/sass-eyeglass/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/sass-eyeglass/eyeglass","description":"NPM Modules for Sass","fork":false,"url":"https://api.github.com/repos/sass-eyeglass/eyeglass","forks_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/forks","keys_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/keys{/key_id}","collaborators_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/teams","hooks_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/hooks","issue_events_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/events{/number}","events_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/events","assignees_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/assignees{/user}","branches_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/branches{/branch}","tags_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/tags","blobs_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/refs{/sha}","trees_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/trees{/sha}","statuses_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/statuses/{sha}","languages_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/languages","stargazers_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/stargazers","contributors_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/contributors","subscribers_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/subscribers","subscription_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/subscription","commits_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/commits{/sha}","git_commits_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/git/commits{/sha}","comments_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/comments{/number}","issue_comment_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/comments{/number}","contents_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/contents/{+path}","compare_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/compare/{base}...{head}","merges_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/merges","archive_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/downloads","issues_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues{/number}","pulls_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls{/number}","milestones_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/milestones{/number}","notifications_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/labels{/name}","releases_url":"https://api.github.com/repos/sass-eyeglass/eyeglass/releases{/id}","created_at":"2015-02-04T18:21:33Z","updated_at":"2015-07-13T18:33:50Z","pushed_at":"2015-07-14T01:38:38Z","git_url":"git://github.com/sass-eyeglass/eyeglass.git","ssh_url":"git@github.com:sass-eyeglass/eyeglass.git","clone_url":"https://github.com/sass-eyeglass/eyeglass.git","svn_url":"https://github.com/sass-eyeglass/eyeglass","homepage":null,"size":543,"stargazers_count":321,"watchers_count":321,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":13,"mirror_url":null,"open_issues_count":8,"forks":13,"open_issues":8,"watchers":321,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48"},"html":{"href":"https://github.com/sass-eyeglass/eyeglass/pull/48"},"issue":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/48"},"comments":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/issues/48/comments"},"review_comments":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48/comments"},"review_comment":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/pulls/48/commits"},"statuses":{"href":"https://api.github.com/repos/sass-eyeglass/eyeglass/statuses/b9b47460f566f947253bd201f51993eb8abe2caf"}}}}