Tuist. Как перенести проект

от автора

Столкнулся с данной задачей и решил написать статью о том как начать работать с Tuist на своём примере.

Это первый этап на пути модуляризации проекта. Разобравшись с ним будет легче пройти остальные этапы. Наша задача запустить проект при помощи Tuist не потеряв настройки исходного проекта. Но обо всём по порядку.

Основная часть

Миграция состоит из нескольких шагов:

  • Подготовка директории проекта

  • Импорт настроек текущего проекта в отдельный файл

  • Конфигурация файла Project.swift

Подготовка директории проекта

Заходим на официальный сайт, ищем раздел миграции и выбираем Xcode project.

Что нам необходимо сделать?

  • Создать два файла в корне проекта (Project.swift и Tuist.swift).

  • Папку с файлом (Tuist -> Package.swift).

Итогом должна выйти такая структура.

Папка проекта

Папка проекта

В официальной документации есть код, который надо вставить в каждый файл для старта.

Открываем консоль, заходим в папку проекта и командуем.

tuist edit

Появляется привычный нам Xcode с файлами которые мы создавали.

Project.swift

Project.swift

Импорт настроек текущего проекта в отдельный файл

В документации для нас уже подготовили команду по извлечению настроек из проекта, берем ее и подставляем нужные нам значения.

  • Создаем папку куда положим настройки.

  • Извлекаем в эту папку настройки.

На месте MyApp.xcodeproj пишем проект из которого извлекаем. На месте xcconfigs/MyApp-Project.xcconfig пишем путь и название извлекаемого. Все действия выполняем из папки проекта.

mkdir -p xcconfigs/ tuist migration settings-to-xcconfig -p FirstMyApp.xcodeproj -x xcconfigs/MyApp-Project.xcconfig

Конфигурация файла Project.swift

Два этапа

  • Конфигурация проекта

  • Конфигурация таргета

Конфигурация проекта

Для удобства заполнения вызвал Project со всеми доступными параметрами.

Project.swift

Project.swift
  • name — название проекта, как пример выше «TestAppTuist»

  • options — тут интереснее, у меня выбрано два поля, иначе Tuist сгенерирует файлы помощники, которые позволяют безопасно обращаться к ресурсам. Например, картинки. В моем случае, это вызывало ошибку, так как с таким именем уже существовали структуры и менять наименования не хотелось.

    disableBundleAcessors: true, disableSynthesizedResourceAccessors: true
  • packages — тут мы указываем зависимости проекта (Project -> Package Dependencies)

    Если из удаленного репозитория:

    .remote(url: "https://github.com/ReactiveX/RxSwift/", requirement: .exact("6.8.0")),

    Если локальный пакет:

    .local(path: "./Modules/Core"),
  • settings — это настройки проекта, их мы извлекли в отдельную папку, осталось прописать путь. (Project -> Build Settings)

    let project = Project(     name: "TestAppTuist",     organizationName: nil,     classPrefix: nil,     options: .options(         disableBundleAccessors: true,         disableSynthesizedResourceAccessors: true     ),     packages: getPackageProject(),     settings: .settings(         configurations: [             .debug(name: "Debug", xcconfig: "./xcconfigs/test-app-tuist.xcconfig"),             .release(name: "Release", xcconfig: "./xcconfigs/test-app-tuist.xcconfig"),         ]     ), 
  • targets — тут указываем все таргеты в приложении. Подробнее будет ниже

  • sсhemes — настраиваются примерно так, раскрыт один параметр — RunAction

    schemes: [         .scheme(             name: "TestAppSheme",             shared: true,             hidden: false,             buildAction: .none,             testAction: .none,             runAction:                     .runAction(                         configuration: .configuration("Debug"),                         attachDebugger: true,                         customLLDBInitFile: "",                         preActions: [],                         postActions: [],                         executable: .target("TestAppTuist"),                         arguments: .arguments(                             environmentVariables: ["OS_ACTIVITY_MODE": .environmentVariable(value: "disable", isEnabled: true)],                             launchArguments: []                         ),                         options:                                 .options(                                     language: nil,                                     region: nil,                                     storeKitConfigurationPath: nil,                                     simulatedLocation: .moscow,                                     enableGPUFrameCaptureMode: .default                                 ),                         diagnosticsOptions: .options(),                         metalOptions: .options(),                         expandVariableFromTarget: .target("TestAppTuist"),                         launchStyle: .automatically                     ),             archiveAction: .none,             profileAction: .none,             analyzeAction: .none         ), 

Конфигурация таргета

Для удобства заполнения вызвал со всеми доступными параметрами.

  • name — имя таргета, в нашем случае оно аналогично имени проекта.

  • destinations — ios, macOs, tvOS. Тут есть странность, если указать iOS, то в поддерживаемых устройствах будет не только iPhone, если нужен только iPhone указываем так.

    destinations: [.iPhone],
  • product — тут указываем что это, app или test target и др.

  • bundleId — указываем bundleId проекта.

  • deploymentTargets — указываем поддерживаемую версию iOS.

  • infoPlist — тут можно создать по умолчанию, либо указать путь, где лежит ваш infoPlist.

  • sources — это путь к папке с файлами .swift. (Кладем все что тут Build Phases -> Compile Sources).

  • resources — путь к папке с различными ресурсами, (Кладем все что должно оказаться в Build Phases -> Copy Bundle Resources).

  • entitlements — тут указываем путь до файла .entitlements.

  • scripts — тут указываем скрипты если в проекте они имеются, выглядит так. Это пример с SwiftLint.

            scripts: [             .pre(                 script: """                 export PATH="$PATH:/opt/homebrew/bin"                  if which swiftlint >/dev/null; then                     swiftlint                 else                     echo "error: SwiftLint does not exist, download it from https://github.com/realm/SwiftLint"                     exit 1                 fi                 """,                 name: "SwiftLintScript"             )         ],
  • dependencies — тут указываем зависимости, берем из меню ниже. Тут внимательнее, эти зависимости должны быть уже добавлены в настройки Project.packages.

    Target dependencies

    Target dependencies
    .package(product: "YandexMapsMobile", type: .runtime),
  • settings — аналогично настройкам проекта, есть настройка таргета, можете извлечь по аналогии с настройкой проекта из начала этой статьи. Команда выглядит так.

    tuist migration settings-to-xcconfig -p MyApp.xcodeproj -t TargetX -x xcconfigs/TargetX.xcconfig
  • coreDataModels — если имеется CoreData, укажите пути к моделям.

  • environmentVariables — тут указана одна переменная, которая помогает держать консоль чуть чище. (Можно найти в настройках Scheme -> Arguments).

    environmentVariables: [   "OS_ACTIVITY_MODE" : "disable" ],

    Остальные параметры оставлены пустыми или по умолчанию.

Нам осталось только запустить.

tuist generate

Заключение

Это базовая настройка проекта с использованием Tuist. Благодаря ей можно начать переход к модульной системе. Буду рад советам и комментариям, так как только начинаю этот путь.


ссылка на оригинал статьи https://habr.com/ru/articles/913824/