Merge pull request #692 from tuist/document-helpers

Document project description helpers
This commit is contained in:
Pedro Piñera Buendía 2019-11-19 09:58:19 +01:00 committed by GitHub
commit 371a7f0d6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 166 additions and 2 deletions

View File

@ -73,7 +73,7 @@ bash <(curl -Ls https://install.tuist.io)
## Bootstrap your first project 🌀
```bash
tuist init --platform ios --product application
tuist init --platform ios
tuist generate # Generates Xcode project & workspace
```

View File

@ -15,6 +15,7 @@ export default {
menu: [
'Getting started',
'Project & Workspace',
'Project description helpers',
'Configuration',
'Dependencies',
'Setup',

View File

@ -33,7 +33,7 @@ cd MyApp
And then run:
```bash
tuist init --platform ios --product application
tuist init --platform ios
```
The `init` command will bootstrap an iOS application, which includes the `Info.plist` files, an `AppDelegate.swift,` a tests file, and a **`Project.swift` that contains the definition of the project.**

163
docs/usage/helpers.mdx Normal file
View File

@ -0,0 +1,163 @@
---
name: Project description helpers
---
import Message from '../components/message'
import { List } from 'semantic-ui-react'
# Project description helpers
## Motivation
One of the inconveniences of Xcode when we use it with large projects is that it doesn't allow reusing elements of the projects other than the build settings through `.xcconfig` files. Being able to reuse project definitions is useful for the following reasons:
- It eases the **maintenance** because changes can be applied in one place and all the projects get the changes automatically.
- It makes it possible to define **conventions** that new projects can conform to.
- Projects are more **consistent** and therefore the likelihood of broken builds due inconsistencies is significantly less.
- Adding a new projects becomes an easy task because we can reuse the existing logic.
Reusing code across manifest files is possible in Tuist thanks to the concept of **project description helpers**.
## Definition
Project description helpers are Swift files that get compiled into a framework, `ProjectDescriptionHelpers`, that manifest files can import.
<Message
info
title="Structure"
description="Tuist is not opinionated about the files structure and the content in them so it's up to you to give them a structure that makes sense for your project."
/>
You can import them into your manifest file by adding an import statement at the top of the file:
```swift
// Project.swift
import ProjectDescription
import ProjectDescriptionHelpers
```
## Location
Tuist traverses up the directories hierarchy until it finds a `Tuist` directory. Then it builds the helpers module including all the files under the `ProjectDescriptionHelpers` directory in the `Tuist` directory. Below you find an example of a project with helpers:
<List>
<List.Item>
<List.Icon name='folder' />
<List.Content>
<List.Header>Tuist</List.Header>
<List.Description>A global Tuist's directory</List.Description>
<List.List>
<List.Item>
<List.Icon name='folder' />
<List.Content>
<List.Header>ProjectDescriptionHelpers</List.Header>
<List.Description>A directory that contains all the helpers</List.Description>
<List.List>
<List.Item>
<List.Icon name='file'/>
<List.Content>
<List.Header>Project+Templates.swift</List.Header>
<List.Description>A helper that extends the Project with some templated initializers.</List.Description>
</List.Content>
</List.Item>
</List.List>
</List.Content>
</List.Item>
</List.List>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='folder' />
<List.Content>
<List.Header>Projects</List.Header>
<List.Description>A directory that contains all the projects</List.Description>
<List.List>
<List.Item>
<List.Icon name='folder' />
<List.Content>
<List.Header>App</List.Header>
<List.Description>A contains the app project</List.Description>
<List.List>
<List.Item>
<List.Icon name='file' />
<List.Content>
<List.Header>Project.swift</List.Header>
<List.Description>The app's Project.swift. It can import helpers.</List.Description>
</List.Content>
</List.Item>
</List.List>
</List.Content>
</List.Item>
<List.Item>
<List.Icon name='folder' />
<List.Content>
<List.Header>Settings</List.Header>
<List.Description>A contains the settings project</List.Description>
<List.List>
<List.Item>
<List.Icon name='file' />
<List.Content>
<List.Header>Project.swift</List.Header>
<List.Description>The settings' Project.swift. It can import helpers.</List.Description>
</List.Content>
</List.Item>
</List.List>
</List.Content>
</List.Item>
</List.List>
</List.Content>
</List.Item>
</List>
## Example
The snippets below contain an example of how we extend the `Project` model to add static constructors and how we use them from a `Project.swift` file:
**Project+Templates.swift**
```swift
import ProjectDescription
extension Project {
public static func featureFramework(name: String, dependencies: [TargetDependency] = []) -> Project {
return Project(name: name,
targets: [
Target(name: name,
platform: .iOS,
product: .framework,
bundleId: "io.tuist.\(name)",
infoPlist: "\(name).plist",
sources: ["Sources/\(name)/**"],
resources: ["Resources/\(name)/**",],
dependencies: dependencies),
Target(name: "\(name)Tests",
platform: .iOS,
product: .unitTests,
bundleId: "io.tuist.\(name)Tests",
infoPlist: "\(name)Tests.plist",
sources: ["Sources/\(name)Tests/**"],
resources: ["Resources/\(name)Tests/**",],
dependencies: [.target(name)])
])
}
}
```
**Project.swift**
```swift
import ProjectDescription
import ProjectDescriptionHelpers
let project = Project.featureFramework(name: "MyFeature")
```
<Message
info
title="Conventions"
description="Note how through the function we are defining conventions about the name of the targets, the bundle identifier, and the folders structure."
/>