Guidance On Platform-Specific Config Defaults


#1

Given:

It would be nice if:

  • Atom provided a way for me to specify different defaults for each platform
  • Atom provided a way for me to handle Windows / *nix paths consistently

Feels like we package authors need to get out in front of an official Windows release and ensure compatibility using an unofficial distribution - e.g. http://discuss.atom.io/t/releases-for-windows/8999/5.


#2

There are suggestions in the CONTRIBUTING.md on how to handle some platform-specific differences:

  • Beware of platform differences
    • Use require('atom').fs.getHomeDirectory() to get the home directory.
    • Use path.join() to concatenate filenames.
    • Temporary directory is not /tmp on Windows, use os.tmpdir() when
      possible

Using path.join() would seem to cover your second “it would be nice” point. This is an example of how to use it in code (taken from atom/benchmark/benchmark-helper.coffee):

path = require 'path'
window.benchmarkFixturesProject = new Project(path.join(__dirname, 'fixtures'))

And you could always have a Windows and Unix base path that you then joined the common parts onto. You could also do some sort of platform detection on load if the defaults aren’t initialized and give them the appropriate platform-specific default value.

There are lots of ways to solve this problem. Though perhaps someone could extend the Config class to handle what you’re talking about.


#3

@leedohm Thanks for the response! I already use path.join extensively for paths which I compute; I suppose path.normalize would make sense for absolute or relative paths that the user supplies.

I do think the defaults requires some special treatment in Atom core, as the settings view will visualize defaults with placeholders, and it’s desirable to not explicitly set a user’s settings just because they’re on Windows.

For example, GofmtPath [https://github.com/joefitzgerald/go-plus/blob/master/lib/go-plus.coffee#L14] is a preference that sets the path to an external executable. The default is OS X specific, and someone might override it to use goimports by setting the preference to $GOPATH/bin/goimports. Suppose:

  • The user is now on Windows
  • They set GofmtPath to %GOPATH%\bin\goimports
  • They use goimports for a while, then want to switch back to gofmt
  • They remove their preference for GofmtPath
  • Things are broken, because the default is a path to /usr/local/go/bin/gofmt which will not normalize to anything that exists at `c:\usr\local\go\bin\gofmt
  • They now have to explicitly set the path to gofmt

While I could detect an *nix path for that and then explicitly set the Windows equivalent, I think that is an anti-pattern and defeats the purpose of the defaults. Even if I did that, if the user removed the value, the package would no longer work again, as the defaults are *nix specific.

This seems like nitpicking, but I just think that to guarantee a good cross-platform experience, things like this should be in the core. Go has a very large Windows install base (I assume due to all the great Chinese gophers out there!), which is motivating me to address Windows support ahead of the curve.


#4

So … how would one go about specifying Windows vs. Unix defaults in their configDefaults?


#5

So … how would one go about specifying Windows vs. Unix defaults in their configDefaults?

That’s what I’m not sure of :smile:, and looking for architectural guidance. @kevinsawicki thoughts?

Is it possible to assign functions to each preference that might be platform specific that will allow setting of platform specific defaults? Would that even work? Are defaults loaded once and then never inspected again, or are they inspected on an ongoing basis?


#6

I think the configDeafults API will have to change to support this, nothing else really comes to mind as another way of achieving this.

Atom could check for either linuxConfigDefaults, win32ConfigDefault, and darwinConfigDefaults depending on the value of process.platform, or perhaps a configDefaults object with win32, darwin, or linux keys are handled specially. The second option wouldn’t be as backwards compatible as the first.


#7

I like the idea of configDefaults with a [platform]ConfigDefaults that overrides it.


#8

I like the idea of configDefaults with a [platform]ConfigDefaults that overrides it.

Agreed!


#9

I would assume that configDefaults would be the lowest priority, able to be overridden by the [platform]ConfigDefaults and then by the user’s own configuration?


#10

Yes, that was my thinking. This is actually along the lines of some thoughts I had for an overridable configuration layer system for things like syntax-specific or project-specific settings. I still need to write it up and post it.


#11

While having a ‘per platform with fallback’ default settings system is great (and I really think it is), it still comes down to how package owners will support it.
How do we deal with packages that may already have set osx defaults and the maintainers can’t/won’t test on other platforms ?
Can’t we detect some idioms in settings paths to at least warn the user that package X provides default for another system than his ?
I’m not an expert in OSs but using the 3 systems daily I feel that there’s some patterns that may be helpful. (/ vs \w: for root or /home vs /Users).
I didn’t had to deal much with that kind of problems with NodeJS, but isn’t there some utility that already deal with that kind of things ? (beyond what path module provides)


#12

We don’t? It’s up to the package owner to decide if they want to invest the time to make things work on different operating systems. This is part of the reason why I don’t include default keymappings in any of my packages because I don’t want to try to figure out how to please the vim, Emacs, Sublime Text, TextMate and Brief crowd all at once. I just provide the functionality and let them figure out which keys they want to map it to.

If Alice makes a package for Amiga and Bob wants it to work on BeOS, then there are always two options. Alice can do the work up front or Bob can do the work to extend Alice’s package. At least the layered config system would give Alice or Bob (or whomever steps up to do the work) some tools to make it easier so they don’t have to figure everything out from scratch.