/Sourcery

Meta-programming for Swift, stop writing boilerplate code.

Primary LanguageSwiftMIT LicenseMIT

CircleCI codecov docs Version License Platform

What is Sourcery?

Sourcery scans your source code, applies your personal templates and generates Swift code for you, allowing you to use meta-programming techniques to save time and decrease potential mistakes.

Using it offers many benefits:

  • Write less repetitive code and make it easy to adhere to DRY principle.
  • It allows you to create better code, one that would be hard to maintain without it, e.g. performing automatic property level difference in tests
  • Limits the risk of introducing human error when refactoring.
  • Sourcery doesn't use runtime tricks, in fact, it allows you to leverage compiler, even more, creating more safety.
  • Immediate feedback: Sourcery features built-in daemon support, enabling you to write your templates in real-time side-by-side with generated code.

Daemon demo

Sourcery is so meta that it is used to code-generate its boilerplate code

Table of Contents generated with DocToc

Why?

Swift features very limited runtime and no meta-programming features. Which leads our projects to contain boilerplate code.

Sourcery exists to allow Swift developers to stop doing the same thing over and over again while still maintaining strong typing, preventing bugs and leveraging compiler.

Have you ever?

  • Had to write equatable/hashable?
  • Had to write NSCoding support?
  • Had to implement JSON serialization?
  • Wanted to use Lenses?

If you did then you probably found yourself writing repetitive code to deal with those scenarios, does this feel right?

Even worse, if you ever add a new property to a type all of those implementations have to be updated, or you will end up with bugs. In those scenarios usually compiler will not generate the error for you, which leads to error prone code.

Installing

Binary form The easiest way to download the tool right now is to just grab a newest `.zip` distribution from [releases tab](https://github.com/krzysztofzablocki/Sourcery/releases).
Via CocoaPods If you're using CocoaPods, you can simply add pod 'Sourcery' to your Podfile.

This will download the Sourcery binaries and dependencies in Pods/. You just need to add $PODS_ROOT/Sourcery/bin/sourcery {source} {templates} {output} in your Script Build Phases.

Via Swift Package Manager If you're using SwiftPM, you can simply add 'Sourcery' to your manifest.

Sourcery is placed in Packages. After your first swift build, you can run .build/debug/sourcery {source} {templates} {output}.

From Source You can clone it from the repo and just run `Sourcery.xcworkspace`.

Usage

Sourcery is a command line tool sourcery, you can either run it manually or in a custom build phase using following command:

$ ./sourcery --sources <sources path> --templates <templates path> --output <output path> [--args arg1=value,arg2]

Command line options

  • --sources - Path to a source swift files. You can provide multiple paths using multiple --sources option.
  • --templates - Path to templates. File or Directory. You can provide multiple paths using multiple --templates options.
  • --output - Path to output. File or Directory. Default is current path.
  • --config - Path to config file. Directory. Default is current path.
  • --args - Additional arguments to pass to templates. Each argument can have explicit value or will have implicit true value. Arguments should be separated with , without spaces. Arguments are accessible in templates via argument.name
  • --watch [default: false] - Watch both code and template folders for changes and regenerate automatically.
  • --verbose [default: false] - Turn on verbose logging for ignored entities
  • --disableCache [default: false] - Turn off caching of parsed data
  • --prune [default: false] - Prune empty generated files

Configuration file

You can also provide arguments using .sourcery.yml file in project's root directory, like this:

sources:
  - <sources path>
  - <sources path>
templates:
  - <templates path>
  - <templates path>
output:
  <output path>
args:
  <name>: <value>

You can provide either sources paths or targets to scan:

project:
  file:
    <path to xcodeproj file>
  root:
    <path to project sources root>
  target:
    name: <target name>
    module: <module name> //required if different from target name

You can use several project or target objects to scan multiple targets from one project or to scan multiple projects.

Features

  • Stencil, Swift, JavaScript templates
  • Watch mode
  • Source annotations
  • Inline and per file code generation

For more information please read DOCUMENTATION.

Contributing

Contributions to Sourcery are welcomed and encouraged!

It is easy to get involved. Please see the Contributing guide for more details.

A list of contributors is available through GitHub.

To give clarity of what is expected of our community, Sourcery has adopted the code of conduct defined by the Contributor Covenant. This document is used across many open source communities, and I think it articulates my values well. For more, see the Code of Conduct.

License

Sourcery is available under the MIT license. See LICENSE for more information.

Attributions

This tool is powered by

Thank you! for:

  • Mariusz Ostrowski for creating the logo.
  • Artsy Eidolon team, because we use their codebase as a stub data for performance testing the parser.
  • Olivier Halligon for showing me his setup scripts for CLI tools which are powering our rakefile.

Other Libraries / Tools

If you want to generate code for asset related data like .xib, .storyboards etc. use SwiftGen. SwiftGen and Sourcery are complementary tools.

Make sure to check my other libraries and tools, especially:

  • KZPlayground - Powerful playgrounds for Swift and Objective-C
  • KZFileWatchers - Daemon for observing local and remote file changes, used for building other developer tools (Sourcery uses it)

You can follow me on twitter for news/updates about other projects I am creating.