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

Plug in/Extension architecture #256

Open
castus opened this issue May 2, 2018 · 6 comments
Open

Plug in/Extension architecture #256

castus opened this issue May 2, 2018 · 6 comments

Comments

@castus
Copy link

castus commented May 2, 2018

I love this tool. I want to use it to format code in my organization. We have some custom rules that are easy to write, but when I do it, I will lose ability to update this tool from your repository. Did you thought about custom rules, that every user can write and use it apart from the tool itself?

From what I saw it is be very difficult in the current architecture, but maybe it is easy, maybe there is something that I cannot see ;)

I have an idea, that is not perfect, but will allow me to have my custom rules and update the repo independently:

  1. General purpose is to keep custom rules file in ~/.swiftformat/CustomRules.swift
    1.1. That file is a simple
import Foundation
extension FormatRules {
    // Custom rules go here
}
  1. In the repository you have a file called CustomRulesTemplate.swift which is a blank file. That file is bind to targets in Xcode.
  2. In build phases there are two custom bash scripts. One before compilation, one after it.
    Before compilation script checks for ~/.swiftformat/CustomRules.swift and if it exists it copies all the content to CustomRulesTemplate.swift
    After compilation script erases all contents from CustomRulesTemplate.swift to not produce any git differences.

With this approach I can easily checkout your repo and then build Command Line Tool with custom rules.

What do you think about it?
If you like it, I can make a PR.

@nicklockwood
Copy link
Owner

@castus can you give some examples of the sort of rules you'd want to write?

@castus
Copy link
Author

castus commented May 3, 2018

Yes of course:

  1. Linebreak at the very top of the file.
  2. Linebreak after calling super.xxx()
  3. Linebreak before return. There shoudn't be blank line when there is only one return in the scope, for ex. { return }
  4. Linebreak after guard's else scope
  5. Linebreak inside class, extension or struct, for ex:
class Foo {
\n
    func init(){}
}

@nicklockwood
Copy link
Owner

@castus OK that makes sense. Some of those rules could probably just be added to the standard list as off-by-default, but a few are probably too esoteric for general use.

I think it would probably be sufficient just to add the CustomRules.swift file, without needing the template and build script. That file would never change, so anyone who has added custom rules shouldn't run into conflicts when updating from git.

Another option would be to build a dylib and have SwiftFormat load it at runtime, but I guess that would be a lot more complex, and there would be issues with ABI compatibility and code signing, etc.

@castus
Copy link
Author

castus commented May 10, 2018

@nicklockwood could you point what rules you think can be added to the standard list? I will try to make PR with them.

The idea with the CustomRules.swift is great, I will make a PR with this change as well.

@nicklockwood
Copy link
Owner

@castus so, IIUC rule 3 would convert something like:

guard foo else {
  return
}

to

guard foo else { return }

I can imagine a lot of teams wanting this rule, although I've also seen the argument that it should always be the former so that you can put a breakpoint against the return line. So I think a rule that can be configured to convert either way would be useful. If you'd like to have a go at that I'd appreciate it (don't worry about adding the config to switch between modes - I can do that part).

Rule number 5 clashes with the existing blankLinesAtStartOfScope rule, so I probably just need to add an option to insert the line instead of remove it. I'm not sure what the best way to define the options for that are though - any ideas?

@nicklockwood
Copy link
Owner

@castus actually, re 5 - someone else has already done some thinking about that: #254

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

No branches or pull requests

2 participants