Category: Uncategorized

Avoid colons when manually installing Meteor packages

I ran into a difficult-to-google problem today:

daymeter:accounts-todoist: updating npm dependencies -- todoist...
/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/meteor-promise/promise_server.js:218
      throw error;
      ^

Error: ENOENT: no such file or directory, rename '/home/kevin/code/meteor/apps/daymeter/app/packages/daymeter_accounts-todoist/.npm/package-new-1qxl97s.31js' -> '/home/kevin/code/meteor/apps/daymeter/app/packages/daymeter:accounts-todoist/.npm/package'
    at Object.renameSync (fs.js:797:3)
    at /home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/fs/tools/fs/files.ts:1641:23
    at attempt (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/fs/tools/fs/files.ts:1726:9)
    at Promise.catch.cp_r.preserveSymlinks (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/fs/tools/fs/files.ts:1738:5)
    at new Promise (<anonymous>)
    at rename (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/fs/tools/fs/files.ts:1719:10)
    at Object.renameDirAlmostAtomically (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/fs/tools/fs/files.ts:1076:7)
    at completeNpmDirectory (/tools/isobuild/meteor-npm.js:811:9)
    at createFreshNpmDirectory (/tools/isobuild/meteor-npm.js:768:3)
    at Object.meteorNpm.updateDependencies (/tools/isobuild/meteor-npm.js:117:7)
    at Object.compile (/tools/isobuild/compiler.js:128:19)
    at /tools/isobuild/isopack-cache.js:354:30
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at IsopackCache._loadLocalPackage (/tools/isobuild/isopack-cache.js:309:18)
    at /tools/isobuild/isopack-cache.js:243:16
    at Function.time (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/tool-env/tools/tool-env/profile.ts:284:12)
    at /tools/isobuild/isopack-cache.js:242:17
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at IsopackCache._ensurePackageLoaded (/tools/isobuild/isopack-cache.js:233:20)
    at /tools/isobuild/isopack-cache.js:75:14
    at /tools/packaging/package-map.js:57:7
    at Function.each (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/underscore/underscore-node-f-pre.js:1321:7)
    at exports.PackageMap.eachPackage (/tools/packaging/package-map.js:49:7)
    at IsopackCache.buildLocalPackages (/tools/isobuild/isopack-cache.js:74:24)
    at /tools/project-context.js:961:25
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at ProjectContext._buildLocalPackages (/tools/project-context.js:960:18)
    at /tools/project-context.js:365:9
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at ProjectContext._completeStagesThrough (/tools/project-context.js:355:18)
    at /tools/project-context.js:347:12
    at Function.run (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/tool-env/tools/tool-env/profile.ts:289:14)
    at ProjectContext.prepareProjectForBuild (/tools/project-context.js:346:13)
    at /tools/cli/commands-packages.js:2291:20
    at Object.capture (/tools/utils/buildmessage.js:283:5)
    at Command.func (/tools/cli/commands-packages.js:2290:27)
    at /tools/cli/main.js:1528:15
 => awaited here:
    at Promise.await (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/meteor-promise/promise_server.js:60:12)
    at rename (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/fs/tools/fs/files.ts:1747:6)
    at Object.renameDirAlmostAtomically (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/fs/tools/fs/files.ts:1076:7)
    at completeNpmDirectory (/tools/isobuild/meteor-npm.js:811:9)
    at createFreshNpmDirectory (/tools/isobuild/meteor-npm.js:768:3)
    at Object.meteorNpm.updateDependencies (/tools/isobuild/meteor-npm.js:117:7)
    at Object.compile (/tools/isobuild/compiler.js:128:19)
    at /tools/isobuild/isopack-cache.js:354:30
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at IsopackCache._loadLocalPackage (/tools/isobuild/isopack-cache.js:309:18)
    at /tools/isobuild/isopack-cache.js:243:16
    at Function.time (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/tool-env/tools/tool-env/profile.ts:284:12)
    at /tools/isobuild/isopack-cache.js:242:17
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at IsopackCache._ensurePackageLoaded (/tools/isobuild/isopack-cache.js:233:20)
    at /tools/isobuild/isopack-cache.js:75:14
    at /tools/packaging/package-map.js:57:7
    at Function.each (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/dev_bundle/lib/node_modules/underscore/underscore-node-f-pre.js:1321:7)
    at exports.PackageMap.eachPackage (/tools/packaging/package-map.js:49:7)
    at IsopackCache.buildLocalPackages (/tools/isobuild/isopack-cache.js:74:24)
    at /tools/project-context.js:961:25
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at ProjectContext._buildLocalPackages (/tools/project-context.js:960:18)
    at /tools/project-context.js:365:9
    at Object.enterJob (/tools/utils/buildmessage.js:388:12)
    at ProjectContext._completeStagesThrough (/tools/project-context.js:355:18)
    at /tools/project-context.js:347:12
    at Function.run (/home/kevin/.meteor/packages/meteor-tool/.2.5.0.1wy4v7o.yrnhl++os.linux.x86_64+web.browser+web.browser.legacy+web.cordova/mt-os.linux.x86_64/tools/tool-env/tools/tool-env/profile.ts:289:14)
    at ProjectContext.prepareProjectForBuild (/tools/project-context.js:346:13)
    at /tools/cli/commands-packages.js:2291:20
    at Object.capture (/tools/utils/buildmessage.js:283:5)
    at Command.func (/tools/cli/commands-packages.js:2290:27)
    at /tools/cli/main.js:1528:15 {
  errno: -2,
  syscall: 'rename',
  code: 'ENOENT',
  path: '/home/kevin/code/meteor/apps/daymeter/app/packages/daymeter_accounts-todoist/.npm/package-new-1qxl97s.31js',
  dest: '/home/kevin/code/meteor/apps/daymeter/app/packages/daymeter:accounts-todoist/.npm/package'

In this example, I’m getting an Error: ENOENT: no such file or directory, rename error. Nothing is wrong with the package. The actual problem is that I have installed the package into the packages/daymeter:accounts-todoist directory. The colon in daymeter:accounts-todoist causes issues.

It is simple to solve the issue; rename the directory to use an underscore. In this case, that is daymeter_accounts-todoist.

Since it is the package.js file that determines the actual package name Meteor looks for when using meteor add, this has no effect on adding the package to the application.

Moving a custom profile to its own repo

State can be weird in Drupal 8.

I recently experienced a situation where the project had a profile—let’s call it theprof—that got moved into its own repository, beefed up (various modules and themes moved to it, etc.), and included in the implementing project via `composer.json`.

We then ran into a weird problem: rebuilding the cache successfully found all of the enabled modules again, but the theme was no longer active. Not only was it inactive, but Drupal couldn’t even find it!

What in the world was going on?

It turns out that Drupal 8 discovers themes differently than modules. When discovering modules, it first actively discovers profiles and then passes a list of these to the class used for discovering “extensions” (a general term used to refer to both modules and themes).

However, when discovering themes, it simply delegates the job of finding profiles to Drupal itself. And Drupal, reasonably, retrieves the path to a profile it has seen before from the State subsystem (generally, the `key_value` table in the database).

Note: It retrieves the path to a profile “it has seen before” this way.

That means that when we moved theprof from profiles/theprof to profiles/contrib/theprof, Drupal still had its path set to the old path in the system.profile.files State key. The solution in the end was simple:

/**
 * Clear profile path cache so that theme discovery works.
 */
function mymodule_update_8004() {
  $state = Drupal::state();
  $state->delete('system.profile.files');

  // Rebuild module and theme data.
  // @see drupal_flush_all_caches()
  $module_data = \Drupal::service('extension.list.module')->reset()->getList();
  /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */
  $theme_handler = \Drupal::service('theme_handler');
  $theme_handler->refreshInfo();
  // In case the active theme gets requested later in the same request we need
  // to reset the theme manager.
  \Drupal::theme()->resetActiveTheme();
}

Workaround for ‘zR’ (expand all folds) not working in IdeaVim 0.58 in PhpStorm, IntelliJ IDEA, etc.

Just sharing my tweet on the blog as well:

The main point: put the following into your .ideavimrc, and reload with :source ~/.ideavimrc

map zR :action ExpandAllRegions<CR>:action ExpandAllRegions<CR>

Call to undefined function cache_get() in Drupal 7? Check your settings.php.

Ran into this one today while setting up a local environment with DDEV:

PHP Fatal error:  Uncaught Error: Call to undefined function cache_get() in /var/www/html/includes/module.inc:754
 Stack trace:
 #0 /var/www/html/includes/module.inc(954): module_implements('system_theme_in...')
 #1 /var/www/html/modules/system/system.module(2511): module_invoke_all('system_theme_in...')
 #2 /var/www/html/includes/theme.inc(798): _system_rebuild_theme_data()
 #3 /var/www/html/includes/theme.maintenance.inc(57): list_themes()
 #4 /var/www/html/includes/bootstrap.inc(2922): _drupal_maintenance_theme()
 #5 /var/www/html/includes/errors.inc(179): drupal_maintenance_theme()
 #6 /var/www/html/includes/bootstrap.inc(2634): _drupal_log_error(Array, true)
 #7 [internal function]: _drupal_exception_handler(Object(Error))
 #8 {main}
 thrown in /var/www/html/includes/module.inc on line 754
 Drush command terminated abnormally due to an unrecoverable error.

It’s not very obvious at all what’s going on here. Clearly, Drupal is somehow failing to load. I at first thought it was the database connection details not getting loaded properly and ensured that they were OK. But the error persisted.

“Strange,” I thought. “The DB connection info is definitely correct.” So I went back to https://www.drupal.org/forum/support/post-installation/2016-06-23/fatal-error-call-to-undefined-function-cache_get, which had some up in search, again. Everyone hitting the error seemed to have syntax errors in their settings.php. I figured that, logically, I must too, and just not be seeing it.

Sure enough:

 

if ($file_exists($dir . '/settings.local.php')) {
  require_once($dir . '/settings.local.php');
}

❝I think you’re looking for the file_exists() function there, buddy.❞

 

So I removed the extraneous $ and, sure enough, the site started working.

This has been another episode of the ongoing worldwide series Is It Plugged In?

Sign up for the FillPDF API private beta

I wanted to echo the blog post from FillPDF Service here. I’m working on a brand new version that is going to be way easier to use, and won’t be de-facto limited to use via the Drupal module. I’m starting a private beta test soon and opening up an early version to testers.

Sign up for the private beta.

It’s going to (finally) be a real REST API! Use vanilla PHP, Python, Elixir, whatever, and fill in PDFs without having to upload them to a server first. Most similar services either require that you upload your PDF template in advance or are hard to use. FillPDF Service doesn’t need that, and it won’t begin to. I may add similar features later on, but it will be on top of what’s already there.

I’m very excited about what’s to come. It will be a big change for FillPDF Service.

Anyway, beta testers will get free usage up to a certain point (most likely equivalent to the Clipboard plan, 600 merges) and can pay for more after that. The existing flexible billing features, like flexible overages, will come later. The beta is basically the API without the billing system set up. I’ll be setting that up while people beta test.

Sign up for the private beta.

WizOne Solutions will be at Drupaldelphia and Drupal Dev Days Lisbon (so far)

I wasn’t planning on Drupaldelphia OR Drupal Dev Days this year, but I’ll be going to both. If you are too, and want to meet up or talk, get in touch via my contact form above or on Twitter.

 

P.S. I’m strongly considering going to DrupalCamp Nordics in Stockholm early September and Drupal Iron Camp in/near Belgrade mid-to-late October. Playing with the idea of WordCamp Vienna, too, but that’s much less likely 🙂

I’ve been busy!

You may notice that I haven’t blogged in quite some time. I was busy with a long-term client, so I was focusing more on that than this website. Things changed a bit, and I’ve decided to be more active here.

I have a couple blog posts in the pipeline, one on avoiding a nasty issue when PHPUnit in Drupal 8 to test an API powered by another Drupal 8 site.

I also want to give my impressions of DrupalCamp London 2018, which I attended.

Meanwhile, I’ve updated the site a bit. The old Services page is now the Solutions page. There is also a new Pricing page, which is still in progress.

I plan to make it easy to book time with me over the coming months.

My Drupal Camp Sacramento Area Presentations: Drupal Hooks and Fill PDF

This is another quick update to let you know that I will be presenting on two topics on Drupal Camp Sacramento Area. You can read the presentation summaries for full details, but I’ll give a little bit of info here too.

Why Drupal uses hooks, and why you should too

This presentation will introduce you to hooks – what they are, why Drupal itself uses them, and a live demo of hooks in action. If you want to learn to develop for Drupal or want to understand better what options your developers have, check it out: Why Drupal uses hooks, and why you should too

Streamline your workflow with Fill PDF – fill your PDF templates with your site’s forms

I’ve seen a lot of people working in or working for real estate and in sports-related areas using Fill PDF lately, and it was originally conceived for use with legal forms. I wanted to show how it can be used to populate these kinds of forms without forcing visitors to leave the Web site and hoping they come back. Do you think there’s a need for this? Search Twitter for “fill pdf”, and you will be surprised! People complain every day about having to fill out and send back PDFs. They too want the process to be easier! There’s a module for that! Check it out: Streamline your workflow with Fill PDF – fill your PDF templates with your site’s forms

WizOne Solutions is going to make Web attendee badges again for this camp…stay tuned over the next couple of days!

wiz1.us – Custom Drupal 7 URL Shortener!

I just launched my own URL shortener for internal use. I am using a fork of the ShURLy Drupal module that runs under Drupal 7. It’s working well so far! I’ll write more about this soon, but just wanted to get it out there. Check out my first link at http://wiz1.us/m