{"id":3220,"url":"https://github.com/scribd/Weaver","last_synced_at":"2025-08-06T13:32:21.518Z","repository":{"id":38083848,"uuid":"128474738","full_name":"scribd/Weaver","owner":"scribd","description":"Dependency Injection framework for Swift (iOS/macOS/Linux)","archived":false,"fork":false,"pushed_at":"2025-04-21T18:24:09.000Z","size":51715,"stargazers_count":768,"open_issues_count":16,"forks_count":34,"subscribers_count":26,"default_branch":"master","last_synced_at":"2025-06-26T22:41:22.888Z","etag":null,"topics":["ios","managed-by-terraform","mobile-build-tooling","swift"],"latest_commit_sha":null,"homepage":"https://github.com/scribd/Weaver","language":"Swift","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scribd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-04-06T22:02:17.000Z","updated_at":"2025-06-07T07:39:51.000Z","dependencies_parsed_at":"2023-02-16T10:16:03.071Z","dependency_job_id":"cd7b0e9b-eec4-43b7-82f4-a6937e90754c","html_url":"https://github.com/scribd/Weaver","commit_stats":{"total_commits":572,"total_committers":12,"mean_commits":"47.666666666666664","dds":"0.10139860139860135","last_synced_commit":"69f50d60e939f38583ad823ee719d63f0bf9396d"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/scribd/Weaver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scribd%2FWeaver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scribd%2FWeaver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scribd%2FWeaver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scribd%2FWeaver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scribd","download_url":"https://codeload.github.com/scribd/Weaver/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scribd%2FWeaver/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267327405,"owners_count":24069427,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-27T02:00:11.917Z","response_time":82,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ios","managed-by-terraform","mobile-build-tooling","swift"],"created_at":"2024-01-05T20:16:34.854Z","updated_at":"2025-08-06T13:32:21.504Z","avatar_url":"https://github.com/scribd.png","language":"Swift","readme":"![logo](https://docs.google.com/drawings/d/e/2PACX-1vTKZZc4z941kqokBegGiiD2SVWMHb7PHJ4ennMhBv9wq8B9NuD4Vwh2Fn6EmSXaFJO36A8Hs1dKwySS/pub?w=850\u0026h=234)\n\n\u003cp align=\"center\"\u003eDeclarative, easy-to-use and safe Dependency Injection framework for Swift (iOS/macOS/Linux)\u003c/p\u003e\n\n[![Build Status](https://travis-ci.com/scribd/Weaver.svg?branch=master)](https://travis-ci.com/scribd/Weaver)\n[![codecov](https://codecov.io/gh/scribd/Weaver/branch/master/graph/badge.svg)](https://codecov.io/gh/scribd/Weaver) \n[![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/scribd-weaver/Lobby)\n\n\u003ca href=\"https://youtu.be/Rxhc9VJBoOI\" alt=\"Watch the demo\" target=\"_blank\"\u003e\n\t\u003cimg src=\"weaver.gif\" alt=\"Watch the video\" width=\"960\" style=\"display: block; margin: 0 auto\" /\u003e\n\u003c/a\u003e\n\n## Features\n\n- [x] Dependency declaration via property wrappers or comments\n- [x] DI Containers auto-generation\n- [x] Dependency Graph compile time validation\n- [x] ObjC support\n- [x] Non-optional dependency resolution\n- [x] Type safety\n- [x] Injection with arguments\n- [x] Registration Scopes\n- [x] DI Container hierarchy\n- [x] Thread safe\n\n## Talks\n- [SF SLUG meet-up @Lyft: Maintaining a dependency graph with Weaver](https://www.youtube.com/watch?v=h3CMMbgozG0)\n\n## Tutorials\n\nIf you're looking for a step by step tutorial, check out these links.\n* [Part 1 - Basics](https://medium.com/scribd-data-science-engineering/dependency-injection-tutorial-with-weaver-on-ios-part-1-78265548dd00)\n* [Part 2 - Unit Testing](https://medium.com/scribd-data-science-engineering/dependency-injection-tutorial-with-weaver-on-ios-part-2-5212c716691b)\n* Part 3 - Multi target application (coming soon)\n\n## Dependency Injection\n\nDependency Injection basically means \"giving an object its instance variables\" [¹](#more-reading). It seems like it's not such a big deal, but as soon as a project gets bigger, it gets tricky. Initializers become too complex, passing down dependencies through several layers becomes time consuming and just figuring out where to get a dependency from can be hard enough to give up and finally use a singleton.\n\nHowever, Dependency Injection is a fundamental aspect of software architecture, and there is no good reason not to do it properly. That's where Weaver can help.\n\n## What is Weaver?\n\nWeaver is a declarative, easy-to-use and safe Dependency Injection framework for Swift.\n\n- **Declarative** because it allows developers to **declare dependencies via annotations** directly in the Swift code.\n- **Easy-to-use** because it **generates the necessary boilerplate code** to inject dependencies into Swift types.\n- **Safe** because **it's all happening at compile time**. If it compiles, it works.\n\n## How does Weaver work?\n\n```\n                                                                         |-\u003e validate() -\u003e valid/invalid \nswift files -\u003e scan() -\u003e [Token] -\u003e parse() -\u003e AST -\u003e link() -\u003e Graph -\u003e | \n                                                                         |-\u003e generate() -\u003e source code \n\n```\n\nWeaver scans the Swift sources of the project, looking for annotations, and generates an AST (abstract syntax tree). It uses [SourceKitten](https://github.com/jpsim/SourceKitten) which is backed by Apple's [SourceKit](https://github.com/apple/swift/tree/master/tools/SourceKit).\n\nThe AST then goes through a linking phase, which outputs a dependency graph.\n\nSome safety checks are then performed on the dependency graph in order to ensure that the generated code won't crash at runtime. Issues are friendly reported in Xcode to make their correction easier.\n\nFinally, Weaver generates the boilerplate code which can directly be used to make the dependency injections happen.\n\n## Installation\n\n### (1) - Weaver command\n\nWeaver can be installed using `Homebrew`, `CocodaPods` or manually.\n\n#### Binary form\n\nDownload the latest release with the prebuilt binary from [release tab](https://github.com/scribd/Weaver/releases). Unzip the archive into the desired destination and run `bin/weaver`\n\n#### [Homebrew](https://brew.sh)\n\n```bash\n$ brew install weaver\n```\n\n#### [CocoaPods](https://guides.cocoapods.org)\n\nAdd the following to your `Podfile`:\n\n```ruby\npod 'WeaverDI'\n```\n\nThis will download the Weaver binaries and dependencies in Pods/ during your next pod install execution and will allow you to invoke it via `${PODS_ROOT}/WeaverDI/weaver/bin/weaver` in your Script Build Phases.\n\nThis is the best way to install a specific version of Weaver since Homebrew cannot automatically install a specific version.\n\n### [Mint](https://github.com/yonaskolb/Mint)\n\nTo use Weaver via Mint, prefix the normal usage with mint run scribd/Weaver like so:\n\n```shell\nmint run scribd/Weaver version\n```\n\nTo use a specific version of Weaver, add the release tag like so:\n\n```shell\nmint run scribd/Weaver@1.0.7 version\n```\n\n#### Building from source\n\nDownload the latest release source code from the [release tab](https://github.com/scribd/Weaver/releases) or clone the repository.\n\nIn the project directory, run `brew update \u0026\u0026 brew bundle \u0026\u0026 make install` to build and install the command line tool.\n\n#### Check installation\n\nRun the following to check if Weaver has been installed correctly.\n\n```bash\n$ weaver swift --help\n\nUsage:\n\n    $ weaver swift\n\nOptions:\n    --project-path - Project's directory.\n    --config-path - Configuration path.\n    --main-output-path - Where the swift code gets generated.\n    --tests-output-path - Where the test helpers gets generated.\n    --input-path - Paths to input files.\n    --ignored-path - Paths to ignore.\n    --cache-path - Where the cache gets stored.\n    --recursive-off\n    --tests - Activates the test helpers' generation.\n    --testable-imports - Modules to imports in the test helpers.\n    --swiftlint-disable-all - Disables all swiftlint rules.\n```\n\n### (2) - Weaver build phase\n\nIn Xcode, add the following command to a command line build phase: \n\n```\nweaver swift --project-path $PROJECT_DIR/$PROJECT_NAME --main-output-path output/relative/path\n```\n\n**Important - Move this build phase above the `Compile Source` phase so that Weaver can generate the boilerplate code before compilation happens.**\n\n## Basic Usage\n\n*For a more complete usage example, please check out the [sample project](./Sample).*\n\nLet's implement a simple app displaying a list of movies. It will be composed of three noticeable objects: \n- `AppDelegate` where the dependencies are registered.\n- `MovieManager` providing the movies.\n- `MoviesViewController` showing a list of movies at the screen.\n\nLet's get into the code.\n\n**`AppDelegate` with comment annotations**:\n\n```swift\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n\n    private let dependencies = MainDependencyContainer.appDelegateDependencyResolver()\n    \n    // weaver: movieManager = MovieManager \u003c- MovieManaging\n    // weaver: movieManager.scope = .container\n    \n    // weaver: moviesViewController = MoviesViewController \u003c- UIViewController\n    // weaver: moviesViewController.scope = .container\n    \n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -\u003e Bool {\n        \n        window = UIWindow()\n\n        let rootViewController = dependencies.moviesViewController\n        window?.rootViewController = UINavigationController(rootViewController: rootViewController)\n        window?.makeKeyAndVisible()\n        \n        return true\n    }\n}\n```\n\n`AppDelegate` registers two dependencies:\n- `// weaver: movieManager = MovieManager \u003c- MovieManaging`\n- `// weaver: moviesViewController = MoviesViewController \u003c- UIViewController`\n\nThese dependencies are made accessible to any object built from `AppDelegate` because their scope is set to `container`:\n- `// weaver: movieManager.scope = .container`\n- `// weaver: moviesViewController.scope = .container`\n\nA dependency registration automatically generates the registration code and one accessor in `AppDelegateDependencyContainer`, which is why the `rootViewController` can be built:\n- `let rootViewController = dependencies.moviesViewController`.\n\n**`AppDelegate` with property wrapper annotations**:\n\nSince Weaver 1.0.1, you can use property wrappers instead of annotations in comments.\n\n```swift\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n    \n    // Must be declared first!\n    private let dependencies = MainDependencyContainer.appDelegateDependencyResolver()\n\n    @Weaver(.registration, type: MovieManager.self, scope: .container)\n    private var movieManager: MovieManaging\n\t\n    @Weaver(.registration, type: MoviesViewController.self, scope: .container)\n    private var moviesViewController: UIViewController\n    \n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -\u003e Bool {\n        \n        window = UIWindow()\n\n        window?.rootViewController = UINavigationController(rootViewController: moviesViewController)\n        window?.makeKeyAndVisible()\n        \n        return true\n    }\n}\n```\n\n- Note how dependencies can be accessed from the `self` instance directly.\n\n- Also note that the dependencies object must be declared and created prior to any other Weaver annotation. **Not doing so would immediately crash the application**. \n\n- It is possible to use comment and property wrapper annotations in the same type.\n\n**`MovieManager`**:\n\n```swift\nprotocol MovieManaging {\n    \n    func getMovies(_ completion: @escaping (Result\u003cPage\u003cMovie\u003e, MovieManagerError\u003e) -\u003e Void)\n}\n\nfinal class MovieManager: MovieManaging {\n\n    func getMovies(_ completion: @escaping (Result\u003cPage\u003cMovie\u003e, MovieManagerError\u003e) -\u003e Void) {\n        // fetches movies from the server...\n        completion(.success(movies))        \n    }\n}\n```\n\n**`MoviesViewController` with comment annotations**:\n\n```swift\nfinal class MoviesViewController: UIViewController {\n    \n    private let dependencies: MoviesViewControllerDependencyResolver\n    \n    private var movies = [Movie]()\n    \n    // weaver: movieManager \u003c- MovieManaging\n    \n    required init(injecting dependencies: MoviesViewControllerDependencyResolver) {\n        self.dependencies = dependencies\n        super.init(nibName: nil, bundle: nil)\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        // Setups the tableview... \n        \n        // Fetches the movies\n        dependencies.movieManager.getMovies { result in\n            switch result {\n            case .success(let page):\n                self.movies = page.results\n                self.tableView.reloadData()\n                \n            case .failure(let error):\n                self.showError(error)\n            }\n        }\n    }\n\n    // ... \n}\n```\n\n`MoviesViewController` declares a dependency reference: \n\n- `// weaver: movieManager \u003c- MovieManaging`\n\nThis annotation generates an accessor in `MoviesViewControllerDependencyResolver`, but no registration, which means `MovieManager` is not stored in `MoviesViewControllerDependencyContainer`, but in its parent (the container from which it was built). In this case, `AppDelegateDependencyContainer`.\n\n`MoviesViewController` also needs to declare a specific initializer:\n\n- `required init(injecting dependencies: MoviesViewControllerDependencyResolver)`\n\nThis initializer is used to inject the DI Container. Note that `MoviesViewControllerDependencyResolver` is a protocol, which means a fake version of the DI Container can be injected when testing.\n\n**`MoviesViewController` with property wrapper annotations**:\n\n```swift\nfinal class MoviesViewController: UIViewController {\n    \n    private var movies = [Movie]()\n\n    @Weaver(.reference)\n    private var movieManager: MovieManaging\n    \n    required init(injecting _: MoviesViewControllerDependencyResolver) {\n        super.init(nibName: nil, bundle: nil)\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        // Setups the tableview... \n        \n        // Fetches the movies\n        movieManager.getMovies { result in\n            switch result {\n            case .success(let page):\n                self.movies = page.results\n                self.tableView.reloadData()\n                \n            case .failure(let error):\n                self.showError(error)\n            }\n        }\n    }\n\n    // ... \n}\n```\n\n## API\n\n### Code Annotations\n\nWeaver allows you to declare dependencies by annotating the code with comments like `// weaver: ...` or property wrappers like `@Weaver(...) var ...`\n\nIt currently supports the following annotations:\n\n#### - Registration\n\n- Adds the dependency builder to the container.\n\n- Adds an accessor for the dependency to the container's resolver protocol.\n\nExample:\n\n```swift\n// weaver: dependencyName = DependencyConcreteType \u003c- DependencyProtocol\n\n@Weaver(.registration, type: DependencyConcreteType.self) \nvar dependencyName: DependencyProtocol\n```\nor \n\n```swift\n// weaver: dependencyName = DependencyConcreteType\n\n@Weaver(.registration) \nvar dependencyName: DependencyConcreteType\n```\n\n- `dependencyName`: Dependency's name. Used to make reference to the dependency in other objects and/or annotations.\n\n- `DependencyConcreteType`: Dependency's implementation type. Can be a `struct` or a `class`.\n\n- `DependencyProtocol`: Dependency's `protocol` if any. Optional, you can register a dependency with its concrete type only.\n\n#### - Reference\n\nAdds an accessor for the dependency to the container's protocol.\n\nExample:\n```swift\n// weaver: dependencyName \u003c- DependencyType\n\n@Weaver(.reference) \nvar dependencyName: DependencyType\n```\n\n`DependencyType`: Either the concrete or abstract type of the dependency. This also defines the type the dependency's accessor returns.\n\n#### - Parameter\n\nAdds a parameter to the container's resolver protocol. This means that the generated container needs to take these parameter at initialisation. It also means that all the concerned dependency accessors need to take this parameter.\n\nExample:\n\n```swift\n// weaver: parameterName \u003c= ParameterType\n\n@Weaver(.parameter) \nvar parameterName: ParameterType\n```\n\n#### - Scope\n\nSets the scope of a dependency. The default scope being `container`. Only works for registrations or weak parameters.\n\nThe `scope` defines a dependency lifecycle. Four scopes are available:\n\n- `transient`: Always creates a new instance when resolved.\n\n- `container`: Builds an instance at initialization of its container and lives as long as its container lives.\n\n- `weak`: A new instance is created when resolved the first time and then lives as long as its strong references are living.\n\n- `lazy`: A new instance is created when resolved the first time with the same lifetime than its container.\n\nExample:\n\n```swift\n// weaver: dependencyName.scope = .scopeValue\n\n@Weaver(.registration, scope: .scopeValue)\nvar dependencyName: DependencyType\n```\n\n`scopeValue`: Value of the scope. It can be one of the values described above.\n\n#### - Custom Builder\n\nOverrides a dependency's default initialization code.\n\nWorks for registration annotations only.\n\nExample:\n```swift\n// weaver: dependencyName.builder = DependencyType.make\n\n@Weaver(.registration, builder: DependencyType.make) \nvar dependencyName: DependencyType\n```\n\n`DependencyType.make`: Code overriding the dependency's initialization code taking `DependencyTypeInputDependencyResolver` as a parameter and returning `DependencyType` (e.g. `make`'s signature could be `static func make(_ dependencies: DependencyTypeInputDependencyResolver) -\u003e DependencyType`).\n\n**Warning - Make sure you don't do anything unsafe with the `DependencyResolver` parameter passed down in this method since it won't be caught by the dependency graph validator.**\n\n#### - Configuration\n\nSets a configuration attribute to the concerned object.\n\nExample:\n\n```swift\n// weaver: dependencyName.attributeName = aValue\n\n@Weaver(..., attributeName: aValue, ...) \nvar dependencyName: DependencyType\n```\n\n##### Configuration Attributes:\n\n- `isIsolated: Bool` (default: `false`): any object setting this to true is considered by Weaver as an object which isn't used in the project. An object flagged as isolated can only have isolated dependents. This attribute is useful to develop a feature wihout all the dependencies setup in the project.\n\n- `setter: Bool` (default: `false`): generates a setter (`setDependencyName(dependency)`) in the dependency container. **Note that a dependency using a setter has to be set manually before being accessed through a dependency resolver or it will crash.** \n\n- `objc: Bool` (default: `false`): generates an ObjC compliant resolver for a given dependency, allowing it be accessed from ObjC code.\n\n- `escaping: Bool` (default: `true` when applicable): asks Weaver to use `@escaping` when declaring a closure parameter.\n\n- `platforms: [Platform]` (default: `[]`): List of platforms for which Weaver is allowed to use the dependency. An empty list means any platform is allowed.\n\n#### Using protperty wrappers with parameters:\n\nTypes using parameter annotations need to take the said parameters as an input when being registered or referenced. This is particularly true when using property wrappers, because the signature of the annotation won't compile if not done correctly.\n\nFor example, the following shows how a type taking two parameters at initialization can be annotated:\n\n```swift\nfinal class MovieViewController {\n\n   @Weaver(.parameter) private var movieID: Int\n   \n   @Weaver(.parameter) private var movieTitle: String\n}\n```\n\nAnd how that same type can be registered and referenced:\n\n```swift\n@WeaverP2(.registration)\nprivate var movieViewController: (Int, String) -\u003e MovieViewController\n\n@WeaverP2(.reference)\nprivate var moviewViewController: (Int, String) -\u003e MovieViewController\n```\n\nNote that Weaver generates one property wrapper per amount of input parameters, so if a type takes one parameter `WeaverP1` shall be used, for two parameters, `WeaverP2`, and so on.\n\n#### Writing tests:\n\nWeaver can also generate a dependency container stub which can be used for testing. This feature is accessible by adding the option `--tests` to the command (e.g. `weaver swift --tests`).\n\n**To compile, the stub expects certain type doubles to be implemented.**\n\nFor example, given the following code:\n\n```swift\nfinal class MovieViewController {\n   @Weaver(.reference) private var movieManager: MovieManaging\n}\n```\n\nThe generated stub expects `MovieManagingDouble` to be implemented in order to compile.\n\nTesting `MoviewViewController` can then be written like the following:\n\n```swift\nfinal class MovieViewControllerTests: XCTestCase {\n\n\tfunc test_view_controller() {\n\t\tlet dependencies = MainDependencyResolverStub()\n\t\tlet viewController = dependencies.buildMovieViewController()\n\t\t\n\t\tviewController.viewDidLoad()\n\t\t\n\t\tXCTAssertEqual(dependencies.movieManagerDouble.didRequestMovies, true)\n\t}\n}\n```\n\n## Generate Swift Files\n\nTo generate the boilerplate code, the `swift` command shall be used.\n\n```bash\n$ weaver swift --help\n\nUsage:\n\n    $ weaver swift\n\nOptions:\n    --project-path - Project's directory.\n    --config-path - Configuration path.\n    --main-output-path - Where the swift code gets generated.\n    --tests-output-path - Where the test helpers gets generated.\n    --input-path - Paths to input files.\n    --ignored-path - Paths to ignore.\n    --cache-path - Where the cache gets stored.\n    --recursive-off\n    --allow-tests-to-init-real-dependencies - Makes dependency resolvers available to @Testable imports.\n    --tests - Activates the test helpers' generation.\n    --testable-imports - Modules to imports in the test helpers.\n    --swiftlint-disable-all - Disables all swiftlint rules.\n    --platform - Targeted platform.\n    --included-imports - Included imports.\n    --excluded-imports - Excluded imports.\n```\n\n### Example:\n\n```bash\nweaver swift --project-path $PROJECT_DIR/$PROJECT_NAME --main-output-path Generated\n```\n\n### Parameters:\n\n- `--project-path`: Acts like a base path for other relative paths like `config-path`, `output-path`, `template-path`, `input-path` and `ignored-path`. It defaults to the running directory.\n- `--config-path`: Path to a configuration file. By defaults, Weaver automatically detects `.weaver.yaml` and `.weaver.json` located at `project-path`.\n- `--main-output-path`: Path where the code will be generated. Defaults to `project-path`.\n- `--tests-output-path`: Path where the test utils code will be generated. Defaults to `project-path`.\n- `--input-path`: Path to the project's Swift code. Defaults to `project-path`. Variadic parameter, which means it can be set more than once. By default, Weaver recursively read any Swift file located under the `input-path`.\n- `--ignored-path`: Same than `input-path` but for ignoring files which shouldn't be parsed by Weaver. \n- `--recursive-off`: Deactivates recursivity for `input-path` and `ignored-path`.\n- `--tests` - Activates the test helpers' generation.\n- `--testable-imports` - Modules to imports in the test helpers. Variadic parameter, which means it can be set more than once.\n- `--swiftlint-disable-all` - Disables all swiftlint rules in generated files.\n- `--platform` - Platform for which the generated code will be compiled (iOS, watchOS, OSX, macOS or tvOS).\n- `--included-imports` - Modules which can be imported in generated files.\n- `--excluded-imports` - Modules which can't be imported in generated files.\n- `--allow_tests_to_init_real_dependencies` - Will declare every DependencyResolver with internal access level so `@Testable import`s can invoke them to initialize real dependencies in tests.\n\n### Configuration File:\n\nWeaver can read a configuration file rather than getting its parameters from the command line. It supports both `json` and `yaml` formats.\n\nTo configure Weaver with a file, write a file named `.weaver.yaml` or `.weaver.json` at the root of your project.\n\nParameters are named the same, but snakecased. They also work the same way with one exception, **`project_path` cannot be defined in a configuration. Weaver automatically set its value to the configuration file location**.\n\nFor example, the [sample project configuration](https://github.com/scribd/Weaver/blob/master/Sample/.sample.weaver.yaml) looks like:\n\n```yaml\nmain_output_path: Sample/Generated\ninput_paths:\n  - Sample\nignored_paths:\n  - Sample/Generated\n```\n\n## Caching \u0026 Cleaning\n\nIn order to avoid parsing the same swift files over and over again, Weaver has a cache system built in. It means that Weaver won't reprocess files which haven't been changed since last time they got processed.\n\nUsing this functionality is great in a development environment because it makes Weaver's build phase much faster most of the time. However, on a CI it is preferable to let Weaver process the Swift files everytime for safety, for which the clean command can be used.\n\nFor example, the following always processes all of the swift code:\n\n```bash\n$ weaver clean\n$ weaver swift \n```\n\n## Export Dependency Graph\n\nWeaver can ouput a JSON representation of the dependency graph of a project.\n\n```bash\n$ weaver json --help\nUsage:\n\n    $ weaver json\n\nOptions:\n    --project-path - Project's directory.\n    --config-path - Configuration path.\n    --pretty [default: false]\n    --input-path - Paths to input files.\n    --ignored-path - Paths to ignore.\n    --cache-path - Cache path.\n    --recursive-off\n    --platform - Selected platform\n```\n\nFor an output example, please check this [Gist](https://gist.github.com/trupin/9438713f8fae0a5a7f424eca1976f42b).\n\n## Migration guides\n\n- [From weaver 0.9.+ to 0.10.+](./Documentation/Migration_from_0.9.+_to_0.10.+.md)\n- [From weaver 0.10.+ to 0.11.+](./Documentation/Migration_from_0.10.+_to_0.11.+.md)\n- [From weaver 0.11.+ to 0.12.+](./Documentation/Migration_from_0.11.+_to_0.12.+.md)\n- [From weaver 0.12.+ to 1.+](https://github.com/scribd/Weaver/releases/tag/1.0.0)\n\n## More content...\n- [Weaver: A Painless Dependency Injection Framework For Swift](https://medium.com/scribd-data-science-engineering/weaver-a-painless-dependency-injection-framework-for-swift-7c4afad5ef6a)\n- [Dependency Injection Demisifyied, James Shore, 03/22/2006](http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html) ¹\n\n\n## Contributing\n\n1. [Fork it](https://github.com/Scribd/weaver/fork)\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create a new Pull Request\n\n## Releasing a new version\n\n1. Navigate to the Github Releases tab.\n2. Ensure that whatever changes need to be released are merged into master.\n3. Create a new release with a matching tag on the commit you want to release.\n4. Wait up to 3 hours for Homebrew to automatically detect the new version and [trigger a PR into homebrew-core like this one](https://github.com/Homebrew/homebrew-core/pull/220659).\n5. The new version will be available to use from Homebrew after that PR gets approved and merged.\n\n## License\n\nMIT license. See the [LICENSE file](./LICENSE) for details.\n","funding_links":[],"categories":["Libs","Swift","Dependency Injection","Dependency Injection [🔝](#readme)"],"sub_categories":["Dependency Injection","Getting Started","Web View"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscribd%2FWeaver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscribd%2FWeaver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscribd%2FWeaver/lists"}