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

support alfred 4 and 3 #5

Closed

Conversation

karlsander
Copy link

@karlsander karlsander commented Jun 2, 2019

This PR adds support for Alfred 4, which completely drops the version postfix while keeping support for v3.

It's not exactly elegant, but supporting 2 different paths just isn't I guess. Here's an alternative, simple PR that just drops v3 support.

@LitoMore
Copy link
Contributor

LitoMore commented Jun 6, 2019

I think we could add a parameter to the method like resolveAlfredPrefs(options).

Then we can use this module in alfy twice for checking both Alfred 3 and Alfred 4.

@LitoMore
Copy link
Contributor

LitoMore commented Jun 6, 2019

@SamVerschueren @sindresorhus Any comments with this discussion?

@LitoMore
Copy link
Contributor

LitoMore commented Jun 6, 2019

More details for my idea:

resolveAlfredPrefs(options)

options.settingsPath

Default to /Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist, the latest version of Alfred.


When we using this module in alfy, we should check both Alfred 3 and Alfred 4.

const prefsLatest = await resolveAlfredPrefs();
const prefs3 = await resolveAlfredPrefs({
  settingsPath: '/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist'
})

// Doing symlink for Alfred 3 and Alfred 4
// ...

@deanishe
Copy link

deanishe commented Jun 26, 2019

For Alfred 4+, the correct way to get the path to Alfred's preferences bundle is to read the current value from ~/Library/Application Support/Alfred/prefs.json.

The file was added specifically for this purpose.

@LitoMore
Copy link
Contributor

I will make a new pull request to add support for both 3 and 4. Then I will ask Sindre to help me review my pull request.

@sindresorhus
Copy link
Collaborator

Alright. I'm ok with supporting Alfred 3 and 4 using the method @deanishe has suggested.

@LitoMore
Copy link
Contributor

LitoMore commented Jul 2, 2019

@sindresorhus Here are my ideas about the API design, could you give me some advice?

Idea 1

const resolveAlfredRefs = require('resolve-alfred-refs');

(async () => {
  console.log(await resolveAlfredRefs());
  //=> {alfred3: '/path/to/alfred-3-prefs', alfred4: undefined}
})();

If Alfred 3/4 does not exist, the value of alfred4 will be undefined. This function will never throw any error.

Idea 2

const {resolveAlfred3Prefs, resolveAlfred4Prefs} = require('resolve-alfred-refs');

(async () => {
  const alfred3 = await resolveAlfred3Prefs();
  console.log(alfred3);
  //=> '/path/to/alfred-3-prefs'

  const alfred4 = await resolveAlfred4Prefs();
  console.log(alfred4);
  //=> '/path/to/alfred-4-prefs'
})();

If Alfred 3/4 does not exist or the user doesn't have permission to access, the function will throw an error.

Idea 3

Make a new module for Alfred 4:

I created a new package resolve-alfred-4-refs (not published to npm yet) to resolve the preferences file for Alfred 4.

We can use this package in alfred-link directly.

@sindresorhus
Copy link
Collaborator

sindresorhus commented Jul 2, 2019

I would prefer:

const resolveAlfredRefs = require('resolve-alfred-refs');

(async () => {
  console.log(await resolveAlfredRefs());
  //=> {isAlfred4: true, path: '/path/to/alfred-4-prefs'}
})();

@deanishe
Copy link

deanishe commented Jul 5, 2019

Make a new module for Alfred 4

I don't think this is a good idea, at least not an Alfred 4-specific module. Alfred 4+ will all use the same directories (i.e. no more "Alfred X" and no more workflows breaking with every major update). It should mostly be a case of one (legacy) method for Alfred 3 and one new one for every later version.

You should use prefs.json first (which should work with Alfred 4, Alfred 5, etc.) and only fall back to the old method for Alfred 3 if prefs.json doesn't exist.

To the same ends, any JXA calls should use Application('com.runningwithcrayons.Alfred'), not Application('Alfred 4').

@SamVerschueren
Copy link
Owner

I agree with what @sindresorhus commented. Something in line with

const resolveAlfredRefs = require('resolve-alfred-refs');

(async () => {
  console.log(await resolveAlfredRefs());
  //=> {isAlfred4: true, path: '/path/to/alfred-4-prefs'}
})();

Or {version: '4', path: '/path/to/alfred-4-prefs'}. This way, we have an upgrade path if v5 etc. comes out.

@sindresorhus
Copy link
Collaborator

@SamVerschueren Sounds good. I don't think we even need the version number, I guess we can have it just in case.

@deanishe
Copy link

deanishe commented Jul 6, 2019

I don't think we even need the version number, I guess we can have it just in case.

You need the version number to abort an update to an incompatible version, don't you? Or is it already too late to do that when this module is called?

@SamVerschueren
Copy link
Owner

That could definitely be added to alfred-link. But it also means that every workflow should define the compatible Alfred version.

@deanishe
Copy link

deanishe commented Jul 6, 2019

But it also means that every workflow should define the compatible Alfred version.

I'm not familiar with the way you have this whole workflows-via-npm business working. The main issue to avoid, imo, is updating workflows to newer, incompatible versions.

If updating a workflow requires users to run npm themselves, I don't think it's a problem. (Well, it's their problem.)

You just want to avoid workflows overwriting themselves with incompatible versions.

@LitoMore
Copy link
Contributor

You should use prefs.json first (which should work with Alfred 4, Alfred 5, etc.) and only fall back to the old method for Alfred 3 if prefs.json doesn't exist. (@deanishe)

Good point.

So I think the API returns should be:

// If Alfred 4 or later
{path: '/path/to/prefs'}

// If Alfred 3
{version: '3', path: '/path/to/prefs'}


if (!exists) {
throw new Error(`Alfred preferences not found at location ${settings}`);
if (!(latestExists || v3Exists)) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it's easier to read if you did it like this

Suggested change
if (!(latestExists || v3Exists)) {
if (!latestExists && !v3Exists) {


const mv = (src, dest) => pify(fs.rename)(src, dest).catch(() => { });

test.before(async () => {
await mv(settings, `${settings}.back`);
await cp(path.join(__dirname, 'fixtures/com.runningwithcrayons.Alfred-Preferences-3.plist'), settings);
await cp(path.join(__dirname, 'fixtures/com.runningwithcrayons.Alfred-Preferences.plist'), settings);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should test both Alfred 3 and latest.

So maybe we can make it a test macro?

function macro(t, filename, expected) {
	t.is(eval(input), expected);
}

macro.title = (providedTitle, filename) => `resolves \`${filename}\``;

test(macro, 'Alfred-Preferences.plist', path.join(userHome, 'Documents/alfred/Alfred.alfredpreferences'));
test(macro, 'Alfred-Preferences-3.plist', path.join(userHome, 'Documents/alfred/Alfred.alfredpreferences'));

@SamVerschueren
Copy link
Owner

So I think the API returns should be:

// If Alfred 4 or later
{path: '/path/to/prefs'}

// If Alfred 3
{version: '3', path: '/path/to/prefs'}

It would be nice if we could retrieve the version from the plist file to always provide it. That way, we could enforce a engines.alfred setting in package.json so it fails to install if you are installing a Alfred 4 workflow for Alfred 3.

So something like this would be better

// If Alfred 3
{version: 3, path: '/path/to/prefs'}

// If Alfred 4
{version: 4, path: '/path/to/prefs'}

// If Alfred 5
{version: 5, path: '/path/to/prefs'}

(Not sure if versions are numeric though).

If that's not possible, the solution you provided is fine.

@LitoMore
Copy link
Contributor

LitoMore commented Aug 1, 2019

Hi @SamVerschueren, please review this pull request #8, it's the latest one. My pull request will close #5 and #6 when it merged.

It would be nice if we could retrieve the version from the plist file to always provide it. That way, we could enforce engines.alfred setting in package.json so it fails to install if you are installing an Alfred 4 workflow for Alfred 3. (@SamVerschueren)

Currently, we don't have a good way to get the version for Alfred 4 or later.

@karlsander
Copy link
Author

hey, sorry for not keeping up with the discussion. Does #8 already superseed this PR or should I get it into shape to be merged with the new suggested api?

@LitoMore
Copy link
Contributor

LitoMore commented Aug 1, 2019

@karlsander My new PR #8 will fix this issue. You could suspend or close current issue. I used GitHub issue keywords to close this issue. When my PR merges, your PR will also be closed at the same time.

@SamVerschueren
Copy link
Owner

No problem @karlsander, let's continue in #8

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

Successfully merging this pull request may close these issues.

None yet

5 participants