Skip to content

Commit

Permalink
Document manifest files (#6197)
Browse files Browse the repository at this point in the history
* Document manifest files

* Explain why we include the project
  • Loading branch information
pepicrft committed Apr 16, 2024
1 parent 88a1763 commit 5e5536d
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 6 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ const guideSidebar = [
{
text: "Project",
items: [
{
text: "Manifests",
link: "/guide/project/manifests",
},
{
text: "Directory structure",
link: "/guide/project/directory-structure",
Expand Down
9 changes: 3 additions & 6 deletions docs/docs/guide/project/directory-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ Although Tuist projects are commonly used to supersede Xcode projects, they are

Tuist projects are **the most common type of project generated by Tuist.** They are used to build apps, frameworks, and libraries among others. Unlike Xcode projects, Tuist projects are defined in Swift, which makes them more flexible and easier to maintain. Tuist projects are also more declarative, which makes them easier to understand and reason about. The following structure shows a typical Tuist project that generates an Xcode project:

> [!INFO] MANIFEST FILES
> The definition files are referred to as **manifest files** throughout the documentation.
```bash
Tuist/
Config.swift
Expand All @@ -28,13 +25,13 @@ Workspace.swift
```

- **Tuist directory:** This directory has two purposes. First, it signals **where the root of the project is**. This allows constructing paths relative to the root of the project, and also also running Tuist commands from any directory within the project. Second, it's the container for the following files:
- **Config.swift:** This file contains configuration for Tuist that's shared across all the projects, workspaces, and environments. For example, it can be used to disable automatic generation of schemes, or to define the deployment target of the projects.
- [**Config.swift:**](/guide/project/manifests.html#config-swift) This file contains configuration for Tuist that's shared across all the projects, workspaces, and environments. For example, it can be used to disable automatic generation of schemes, or to define the deployment target of the projects.
- **ProjectDescriptionHelpers:** This directory contains Swift code that's shared across all the manifest files. Manifest files can `import ProjectDescriptionHelpers` to use the code defined in this directory. Sharing code is useful to avoid duplications and ensure consistency across the projects.
- **Package.swift:** This file contains Swift Package dependencies for Tuist to integrate them using Xcode projects and targets (like [CocoaPods](https://cococapods)) that are configurable and optimizable. Learn more [here](doc:dependencies).

- **Root directory**: The root directory of your project that also contains the `Tuist` directory.
- **Workspace.swift:** This manifest represents an Xcode workspace. It's used to group other projects and can also add additional files and schemes.
- **Project.swift:** This manifest represents an Xcode project. It's used to define the targets that are part of the project, and their dependencies.
- [**Workspace.swift:**](/guide/project/manifests.html#workspace-swift) This manifest represents an Xcode workspace. It's used to group other projects and can also add additional files and schemes.
- [**Project.swift:**](/guide/project/manifests.html#project-swift) This manifest represents an Xcode project. It's used to define the targets that are part of the project, and their dependencies.

When interacting with the above project, commands expect to find either a `Workspace.swift` or a `Project.swift` file in the working directory or the directory indicated via the `--path` flag. The manifest should be in a directory or subdirectory of a directory containing a `Tuist` directory, which represents the root of the project.

Expand Down
68 changes: 68 additions & 0 deletions docs/docs/guide/project/manifests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: Manifests
description: Learn about the manifest files that Tuist uses to define projects and workspaces and configure the generation process.
---

# Manifests

Tuist defaults to Swift files as the primary way to define projects and workspaces and configure the generation process. These files are referred to as **manifest files** throughout the documentation.

The decision of using Swift was inspired by the [Swift Package Manager](https://www.swift.org/documentation/package-manager/), which also uses Swift files to define packages. Thanks to the usage of Swift, we can leverage the compiler to validate the correctness of the content and reuse code across different manifest files, and Xcode to provide a first-class editing experience thanks to the syntax highlighting, auto-completion, and validation.

> [!NOTE] CACHING
> Since manifest files are Swift files that need to be compiled, Tuist caches the compilation results to speed up the parsing process. Therefore, you'll notice that the first time you run Tuist, it might take a bit longer to generate the project. Subsequent runs will be faster.
## Project.swift

The [`Project.swift`](/reference/project-description/project) manifest declares an Xcode project. The project gets generated in the same directory where the manifest file is located with the name indicated in the `name` property.

```swift
// Project.swift
let project = Project(
name: "App",
targets: [
// ....
]
)
```


> [!WARNING] ROOT VARIABLES
> The only variable that should be at the root of the manifest is `let project = Project(...)`. If you need to reuse code across various parts of the manifest, you can use Swift functions.
## Workspace.swift

By default, Tuist generates an [Xcode Workspace](https://developer.apple.com/documentation/xcode/projects-and-workspaces) containing the project being generated and the projects of its dependencies. If for any reason you'd like to customize the workspace to add additional projects or include files and groups, you can do so by defining a [`Workspace.swift`](/reference/project-description/workspace) manifest.

```swift
// Workspace.swift
import ProjectDescription

let workspace = Workspace(
name: "App-Workspace",
projects: [
"./App", // Path to directory containing the Project.swift file
]
)
```

> [!NOTE]
> Tuist will resolve the dependency graph and include the projects of the dependencies in the workspace. You don't need to include them manually. This is necessary for the build system to resolve the dependencies correctly.
### Multi or mono-project

A question that often comes up is whether to use a single project or multiple projects in a workspace. In a world without Tuist where a mono-project setup would lead to frequent Git conflicts the usage of workspaces is encouraged. However, since we don't recommend including the Tuist-generated Xcode projects in the Git repository, Git conflicts are not an issue. Therefore, the decision of using a single project or multiple projects in a workspace is up to you.

In the Tuist project we lean on mono-projects because the cold generation time is faster (fewer manifest files to compiler) and we leverage [project description helpers](/guide/project/code-sharing) as a unit of encapsulation. However, you might want to use Xcode projects as a unit of encapsulation to represent different domains of your application, which aligns more closely with the Xcode's recommended project structure.

## Config.swift

Tuist provides [sensible defaults](/contributors/principles.html#default-to-conventions) to simplify project configuration. However, you can customize the configuration by defining a [`Config.swift`](/reference/project-description/config) manifest under the `Tuist` directory, which is used by Tuist to determine the root of the project.

```swift
import ProjectDescription

let config = Config(
generationOptions: .options(enforceExplicitDependencies: true)
)
```

0 comments on commit 5e5536d

Please sign in to comment.