Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Monorepo w Allegro

Monorepo w Allegro

Prezentacja opowie o ewolucji projektu Allegro na platformę iOS. Historia zaczyna się ponad 6 lat temu od małego projektu w jednym repozytorium. Z czasem aplikacja rozrosła się i projekt rozbito na wiele repozytoriów. Dzisiaj, przy jeszcze większej skali, ponownie używamy jednego repozytorium. Podczas prezentacji poznacie strukturę projektu aplikacji Allegro, proces jej budowania i testowania. Dowiecie się o plusach i minusach stosowanych rozwiązań oraz naszych planach na przyszłość.

Aleksander Grzyb

September 24, 2018
Tweet

More Decks by Aleksander Grzyb

Other Decks in Programming

Transcript

  1. Monorepo w Allegro
    Allegro Tech Talks #12, Poznań
    Aleksander Grzyb, iOS Developer

    View full-size slide

  2. 4
    Poznań
    8 osób

    View full-size slide

  3. 5
    Poznań
    8 osób
    Wrocław
    5 osób

    View full-size slide

  4. 6
    Poznań
    8 osób
    Wrocław
    5 osób
    Warszawa
    9 osób

    View full-size slide

  5. 7
    github.com/AlDanial/cloc
    --------------------------------------------------------------------------------
    Language             Files        Lines        Blank      Comment         Code
    --------------------------------------------------------------------------------
    Objective-C           3939       397898        81232        31898       284768
    C/C++ Header          3813       232674        39049        43800       149825
    JSON                   838       137764          770            0       136994
    Swift                 2538       178624        33677        15496       129451
    Markdown               104        13464         3899            0         9565
    Bourne Shell            48         3633          453          302         2878
    Plain Text              14         1123          192            0          931
    PHP                      1          849          182            6          661
    Ruby                     5          608           74           15          519
    Python                   6          440          101           27          312
    CSS                      1          425           85          161          179
    Awk                      1           60            4           13           43
    YAML                     1           29            5            0           24
    HTML                     2           23            3            0           20
    --------------------------------------------------------------------------------
    Total                11311       967614       159726        91718       716170
    --------------------------------------------------------------------------------
    --------------------------------------------------------------------------------
    Language             Files        Lines        Blank      Comment         Code
    --------------------------------------------------------------------------------
    Objective-C           3939       397898        81232        31898       284768
    C/C++ Header          3813       232674        39049        43800       149825
    Swift                 2538       178624        33677        15496       129451

    View full-size slide

  6. 8
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  7. 9
    Separacja i reużywalność

    Produktywność
    Odpowiedzialność


    View full-size slide

  8. 10
    Produktywność

    Separacja i reużywalność

    Odpowiedzialność

    View full-size slide

  9. 11
    Odpowiedzialność

    Separacja i reużywalność
    Produktywność


    View full-size slide

  10. 12
    Stopień realizacji
    Czas

    View full-size slide

  11. 13
    //
    // main.m
    // Allegro
    //
    // Created by Jakub Kuzimski on 22.08.2012.
    // Copyright (c) 2012 Jakub Kuzimski. All rights reserved.
    //
    #import
    #import "APAppDelegate.h"
    int main(int argc, char *argv[]) {
    @autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([APAppDelegate class]));
    }
    }
    22.08.2012

    View full-size slide

  12. 15
    Separacja i reużywalność

    Produktywność
    Odpowiedzialność


    View full-size slide

  13. 16
    Separacja i reużywalność
    Produktywność


    Odpowiedzialność

    View full-size slide

  14. 17
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  15. 18
    Allegro
    Strona oferty
    Strona główna
    Proces zakupowy
    Networking
    UI

    View full-size slide

  16. 19
    Strona oferty

    View full-size slide

  17. 20
    Strona oferty

    View full-size slide

  18. 21
    Strona oferty

    View full-size slide

  19. 22
    Strona oferty

    View full-size slide

  20. 23
    Strona oferty

    View full-size slide

  21. 24
    Strona oferty

    View full-size slide

  22. 25
    OfferDetails.podspec
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end

    View full-size slide

  23. 26
    OfferDetails.podspec
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }

    View full-size slide

  24. 27
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    OfferDetails.podspec

    View full-size slide

  25. 28
    Pod::Spec.new do |spec|
    spec.name = "OfferDetails"
    spec.version = "2.0.0"
    spec.summary = "Module is presenting offer details and related information."
    spec.source_files = ["OfferDetails/OfferDetails/**/*.{h,m,swift}"]
    spec.resource_bundle = { "Resources" => ["OfferDetails/OfferDetails/**/*.{xib,storyboard,lproj,xcassets}"] }
    spec.dependency "CoreModule", ">= 1"
    spec.dependency "AllegroCommons", ">= 2.4.0"
    spec.dependency "AllegroDynamicText", ">= 1.1.1"
    spec.dependency "NYTPhotoViewer", ">= 1.0.1"
    spec.dependency "JGProgressHUD", "1.4"
    spec.dependency "INSPullToRefresh", "1.1.5"
    spec.dependency "AllegroNetworking", ">= 2.6.0"
    spec.dependency "Metrum", ">= 0.22.0"
    end
    spec.version = "2.0.0"
    OfferDetails.podspec

    View full-size slide

  26. 29
    Allegro/Podfile
    source "https://allegro_git/pods.specs.git"
    source "https://github.com/CocoaPods/Specs"
    target "Allegro" do
    pod "Registration", "1.5.0"
    pod "Cart", "3.1.2"
    pod "OfferDetails", "2.0.0"
    (...)
    end

    pod update OfferDetails
    pod "OfferDetails", "2.0.0"

    View full-size slide

  27. 30
    Allegro/Podfile
    source "https://allegro_git/pods.specs.git"
    source "https://github.com/CocoaPods/Specs"
    target "Allegro" do
    pod "Registration", "1.5.0"
    pod "Cart", "3.1.2"
    pod "OfferDetails", "2.0.0"
    (...)
    end

    pod update OfferDetails
    source "https://allegro_git/pods.specs.git"

    View full-size slide

  28. 31
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  29. 32
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  30. 33
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  31. 34
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  32. 35
    Allegro
    Strona oferty
    Proces zakupowy
    Networking
    1.0.0

    View full-size slide

  33. 36
    Allegro
    Strona oferty
    Proces zakupowy
    Networking
    1.0.1
    Networking
    1.0.0

    View full-size slide

  34. 37
    Allegro
    Strona oferty
    Proces zakupowy
    Networking
    1.0.1

    View full-size slide

  35. 38
    Allegro
    Strona oferty
    Proces zakupowy
    Wyszukiwanie
    Rejestracja
    Networking
    1.0.0
    Networking
    1.0.5
    UI
    2.0.0
    UI
    2.2.0
    UI
    2.1.0
    Networking
    1.1.0

    View full-size slide

  36. 40
    1. Przenieść kod z modułu strony oferty do AllegroCommons.

    View full-size slide

  37. 41
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.

    View full-size slide

  38. 42
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.
    3. Wydać nowe AllegroCommons.

    View full-size slide

  39. 43
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.
    3. Wydać nowe AllegroCommons.
    4. Uaktualnić AllegroCommons w module oferty.

    View full-size slide

  40. 44
    1. Przenieść kod z modułu strony oferty do AllegroCommons.
    2. Założyć PR do repozytorium AllegroCommons.
    3. Wydać nowe AllegroCommons.
    4. Uaktualnić AllegroCommons w module oferty.
    5. Uaktualnić AllegroCommons w module procesu zakupowego.

    View full-size slide

  41. 45
    (...)
    <<<<<<< HEAD
    PODFILE CHECKSUM: 15f6bd662808121403ea733c7263b90e7b912840
    =======
    PODFILE CHECKSUM: 4c795d243895a6e7905e0606b06679090f723b4a
    >>>>>>> develop
    └── Allegro
    ├── Allegro
    ├── Allegro.xcodeproj
    ├── Allegro.xcworkspace
    ├── AllegroStubbedUITests
    ├── AllegroTests
    ├── Podfile
    ├── Podfile.lock
    ├── Pods.xcodeproj
    ├── Pods
    │ ├── ...
    │ ├── Manifest.lock
    │ └── ...
    └── fastlane
    Allegro/Podfile.lock
    ├── Podfile.lock
    ├── Pods.xcodeproj
    │ ├── Manifest.lock

    View full-size slide

  42. 47
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View full-size slide

  43. 48
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View full-size slide

  44. 49
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View full-size slide

  45. 50
    Konflikty w plikach CocoaPods

    Piekło wersjonowania

    Wydzielenie reużywalnego kodu

    View full-size slide

  46. 54
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search
    └── fastlane
    └── Fastfile

    View full-size slide

  47. 55
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search
    └── fastlane
    └── Fastfile
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane

    View full-size slide

  48. 56
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search
    └── fastlane
    └── Fastfile
    ├── AllegroModules
    │ ├── Cart
    │ ├── Comments
    │ ├── CrossSell
    │ ├── ListingModule
    │ ├── LoyaltyProgram
    │ ├── MyOrders
    │ ├── Networking
    │ ├── Observed
    │ ├── OfferComparison
    │ ├── OfferDetails
    │ ├── Opbox
    │ ├── Origami
    │ ├── Registration
    │ ├── Routings
    │ └── Search

    View full-size slide

  49. 57
    git remote add MODULE-origin https://allegro_git/iosmodules/MODULE.git
    git fetch MODULE-origin
    git merge --allow-unrelated-histories MODULE-origin/develop
    git remote remove MODULE-origin
    git push origin

    View full-size slide

  50. 58
    git remote add MODULE-origin https://allegro_git/iosmodules/MODULE.git
    git fetch MODULE-origin
    git merge --allow-unrelated-histories MODULE-origin/develop
    git remote remove MODULE-origin
    git push origin
    --allow-unrelated-histories

    View full-size slide

  51. 59
    (...)
    target :OfferDetails do
    project '../AllegroModules/OfferDetails/OfferDetails.xcodeproj'
    workspace 'Allegro'
    pod_OfferDetailsDependencies
    target :OfferDetailsTests do
    inherit! :search_paths
    pod_FBSnapshotTest
    pod_CommonPodsForTargetsWithTests
    end
    end
    (...)
    ├── Allegro
    │ ├── Allegro
    │ ├── Allegro.xcodeproj
    │ ├── Allegro.xcworkspace
    │ ├── AllegroStubbedUITests
    │ ├── AllegroTests
    │ ├── Podfile
    │ ├── Podfile.lock
    │ ├── Pods
    │ └── fastlane
    ├── AllegroModules
    │ ├── ...
    │ ├── OfferDetails
    │ │ ├── OfferDetails
    │ │ ├── OfferDetails.xcodeproj
    │ │ ├── OfferDetailsTests
    │ │ └── fastlane
    │ ├── ...
    └── fastlane
    └── Fastfile
    Allegro/Podfile
    │ ├── Podfile

    View full-size slide

  52. 62
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile

    View full-size slide

  53. 63
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")

    View full-size slide

  54. 64
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")

    View full-size slide

  55. 65
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end

    View full-size slide

  56. 66
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end

    View full-size slide

  57. 67
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    fastlane/Fastfile
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    ["AllegroModules/OfferDetails",
    "AllegroModules/Origami",
    "AllegroModules/CrossSell",
    "Allegro/Pods/Metrum",
    "AllegroModules/Networking",
    "Allegro/Pods/AllegroCommons"]

    View full-size slide

  58. 68
    sh "git fetch origin -u +#{destination_branch}:#{destination_branch}"
    destination_branch_commit = sh("git ls-remote https://allegro.git #{destination_branch} | awk '{print $1;}'")
    branch_commit = sh("git rev-parse HEAD")
    changed_files_paths = sh("git diff --name-only #{diff_range}").split("\n")
    changed_files_paths.each do |changed_file_path|
    projects_list.each do |project|
    project.diff_detection_paths.each do |diff_detection_path|
    if changed_file_path.start_with? diff_detection_path
    projects_to_test.add(project)
    end
    end
    end
    end
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end
    fastlane/Fastfile
    projects_to_test.each do |project_to_test|
    Dir.chdir(project_to_test.path) do
    runner.execute(project_to_test.test_action, :ios)
    end
    end

    View full-size slide

  59. 72
    ├── Allegro
    ├── AllegroModules
    ├── Toolset
    │ ├── SwiftFormat
    │ │ ├── run_swiftformat.sh
    │ │ ├── run_swiftformat_in_modules.sh
    │ │ └── swiftformat-0.30.2
    │ ├── SwiftLint
    │ │ ├── run_swiftlint.sh
    │ │ └── swiftlint-0.25.0
    │ └── clang-format
    │ ├── clang-format
    │ ├── reformat_all.sh
    │ └── run_clang_format.sh
    └── ...
    github.com/nicklockwood/SwiftFormat github.com/realm/SwiftLint clang.llvm.org/docs/ClangFormat.html

    View full-size slide

  60. 73
    ├── Allegro
    ├── AllegroModules
    ├── Configuration
    │ ├── Project-Debug.xcconfig
    │ ├── Project-Lab.xcconfig
    │ ├── Project-Release.xcconfig
    │ └── Project-Shared.xcconfig
    └── ...

    View full-size slide

  61. 75
    Allegro/Podfile
    post_install do | installer |
    Dir["../AllegroModules/*/"].map { |a| File.basename(a) }.each do |filePath|
    Dir.glob(File.join("Pods", "**", "Pods-#{filePath}.debug.xcconfig")).each do |file|
    File.open(file, 'a') { |f| f.puts "\n#include \"../../Configuration/Project-Debug.xcconfig\" " }
    end
    (...)
    end
    (...)
    end

    View full-size slide

  62. 76
    (...)
    PODS_PODFILE_DIR_PATH = ${SRCROOT}/../../Allegro
    PODS_ROOT = ${SRCROOT}/../../Allegro/Pods
    #include "../../Configuration/Project-Debug.xcconfig"
    Allegro/Pods/Target Support Files/Pods-OfferDetails/Pods-OfferDetails.debug.xcconfig
    #include "../../Configuration/Project-Debug.xcconfig"
    #include \"../../Configuration/Project-Debug.xcconfig\"
    Allegro/Podfile
    post_install do | installer |
    Dir["../AllegroModules/*/"].map { |a| File.basename(a) }.each do |filePath|
    Dir.glob(File.join("Pods", "**", "Pods-#{filePath}.debug.xcconfig")).each do |file|
    File.open(file, 'a') { |f| f.puts "\n#include \"../../Configuration/Project-Debug.xcconfig\" " }
    end
    (...)
    end
    (...)
    end

    View full-size slide

  63. 80
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  64. 81
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  65. 82
    Separacja i reużywalność
    Produktywność
    Odpowiedzialność



    View full-size slide

  66. 84
    https://engineering.shopify.com/blogs/engineering/mobile-tophatting-at-shopify-1

    View full-size slide

  67. 86
    Ciekawe źródła
    • Faster Together: Uber Engineering’s iOS Monorepo
    • Why Google Stores Billions of Lines of Code in a
    Single Repository
    • µFeatures Guidelines

    View full-size slide