├── Apps
├── Resources
│ ├── ru.lproj
│ │ ├── LaunchScreen.strings
│ │ ├── Localizable.strings
│ │ └── Localizable.stringsdict
│ ├── Colors.xcassets
│ │ ├── Contents.json
│ │ └── customGray.colorset
│ │ │ └── Contents.json
│ ├── macOS.xcassets
│ │ ├── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ ├── 128.png
│ │ │ ├── 16.png
│ │ │ ├── 256.png
│ │ │ ├── 32.png
│ │ │ ├── 512.png
│ │ │ ├── 64.png
│ │ │ ├── 256-1.png
│ │ │ ├── 32-1.png
│ │ │ ├── New Project (11)-1.png
│ │ │ ├── New Project (12).png
│ │ │ └── Contents.json
│ │ └── status-bar-icon.imageset
│ │ │ ├── letterboxd-decal-l-pos-rgb-500px.png
│ │ │ ├── letterboxd-decal-l-pos-rgb-500px@2x.png
│ │ │ ├── letterboxd-decal-l-pos-rgb-500px@3x.png
│ │ │ └── Contents.json
│ ├── en.lproj
│ │ ├── Localizable.strings
│ │ └── Localizable.stringsdict
│ ├── Base.lproj
│ │ ├── Localizable.strings
│ │ └── Localizable.stringsdict
│ └── LocalizationHelper.entitlements
├── TestsProjects
│ ├── Test1
│ │ ├── Test1
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── AccentColor.colorset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── en.lproj
│ │ │ │ └── Localizable.strings
│ │ │ ├── vi.lproj
│ │ │ │ └── Localizable.strings
│ │ │ ├── Test1.xcdatamodeld
│ │ │ │ ├── .xccurrentversion
│ │ │ │ └── Test1.xcdatamodel
│ │ │ │ │ └── contents
│ │ │ ├── ViewController.swift
│ │ │ ├── Base.lproj
│ │ │ │ ├── Main.storyboard
│ │ │ │ └── LaunchScreen.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── AppDelegate.swift
│ │ ├── Test1.xcodeproj
│ │ │ └── project.xcworkspace
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── Test1Tests
│ │ │ ├── Info.plist
│ │ │ └── Test1Tests.swift
│ │ └── Test1UITests
│ │ │ ├── Info.plist
│ │ │ └── Test1UITests.swift
│ ├── Test2
│ │ ├── Test2
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── AccentColor.colorset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── Resources
│ │ │ │ ├── en.lproj
│ │ │ │ │ └── Localizable.strings
│ │ │ │ └── vi.lproj
│ │ │ │ │ └── Localizable.strings
│ │ │ ├── Test2.xcdatamodeld
│ │ │ │ ├── .xccurrentversion
│ │ │ │ └── Test2.xcdatamodel
│ │ │ │ │ └── contents
│ │ │ ├── ViewController.swift
│ │ │ ├── Base.lproj
│ │ │ │ ├── Main.storyboard
│ │ │ │ └── LaunchScreen.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── AppDelegate.swift
│ │ ├── Test2.xcodeproj
│ │ │ └── project.xcworkspace
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── Test2Tests
│ │ │ ├── Info.plist
│ │ │ └── Test2Tests.swift
│ │ └── Test2UITests
│ │ │ ├── Info.plist
│ │ │ └── Test2UITests.swift
│ ├── Test3
│ │ ├── Test3
│ │ │ ├── 1
│ │ │ │ └── 1.1
│ │ │ │ │ └── 1.1.1
│ │ │ │ │ └── 1.1.1.2
│ │ │ │ │ ├── en.lproj
│ │ │ │ │ └── Localizable.strings
│ │ │ │ │ └── vi.lproj
│ │ │ │ │ └── Localizable.strings
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── AccentColor.colorset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── Test3.xcdatamodeld
│ │ │ │ ├── .xccurrentversion
│ │ │ │ └── Test3.xcdatamodel
│ │ │ │ │ └── contents
│ │ │ ├── ViewController.swift
│ │ │ ├── Base.lproj
│ │ │ │ ├── Main.storyboard
│ │ │ │ └── LaunchScreen.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── AppDelegate.swift
│ │ ├── Test3.xcodeproj
│ │ │ └── project.xcworkspace
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── Test3Tests
│ │ │ ├── Info.plist
│ │ │ └── Test3Tests.swift
│ │ └── Test3UITests
│ │ │ ├── Info.plist
│ │ │ └── Test3UITests.swift
│ ├── Test4
│ │ ├── Test4
│ │ │ ├── Assets.xcassets
│ │ │ │ ├── Contents.json
│ │ │ │ ├── AccentColor.colorset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── Test4.xcdatamodeld
│ │ │ │ ├── .xccurrentversion
│ │ │ │ └── Test4.xcdatamodel
│ │ │ │ │ └── contents
│ │ │ ├── ViewController.swift
│ │ │ ├── Base.lproj
│ │ │ │ ├── Main.storyboard
│ │ │ │ └── LaunchScreen.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── AppDelegate.swift
│ │ ├── Test4.xcodeproj
│ │ │ └── project.xcworkspace
│ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── Test4Tests
│ │ │ ├── Info.plist
│ │ │ └── Test4Tests.swift
│ │ └── Test4UITests
│ │ │ ├── Info.plist
│ │ │ └── Test4UITests.swift
│ └── TestWithTuist
│ │ ├── Tuist
│ │ ├── Config.swift
│ │ └── ProjectDescriptionHelpers
│ │ │ └── Project+Templates.swift
│ │ ├── Targets
│ │ ├── TestWithTuist
│ │ │ ├── Tests
│ │ │ │ └── AppTests.swift
│ │ │ ├── Sources
│ │ │ │ └── AppDelegate.swift
│ │ │ └── Resources
│ │ │ │ └── LaunchScreen.storyboard
│ │ ├── TestWithTuistUI
│ │ │ ├── Sources
│ │ │ │ └── TestWithTuistUI.swift
│ │ │ └── Tests
│ │ │ │ └── TestWithTuistUITests.swift
│ │ └── TestWithTuistKit
│ │ │ ├── Sources
│ │ │ └── TestWithTuistKit.swift
│ │ │ └── Tests
│ │ │ └── TestWithTuistKitTests.swift
│ │ ├── Project.swift
│ │ └── .gitignore
├── Sources
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── Extensions
│ │ ├── Typealiases.swift
│ │ ├── Strings+Extensions.swift
│ │ ├── Binding+Extensions.swift
│ │ └── XcodeProj+Extensions.swift
│ ├── Models
│ │ ├── Constants.swift
│ │ ├── AppState.swift
│ │ ├── LocalizationHelperError.swift
│ │ ├── Project
│ │ │ ├── TuistProject.swift
│ │ │ └── DefaultProject.swift
│ │ └── LocalizableFile.swift
│ ├── Services
│ │ ├── LocalizableFileService.swift
│ │ ├── XCodeProjectService.swift
│ │ ├── StringsFileGenerator.swift
│ │ └── FilePickerService.swift
│ ├── System
│ │ ├── Application.swift
│ │ ├── AppDelegate.swift
│ │ └── StatusBarController.swift
│ ├── Utilities
│ │ ├── CancelBag.swift
│ │ ├── Store.swift
│ │ └── Loadable.swift
│ ├── UI
│ │ ├── Link.swift
│ │ ├── OpenProject
│ │ │ └── OpenProjectView.swift
│ │ ├── Main
│ │ │ ├── MainViewModel.swift
│ │ │ └── MainView.swift
│ │ ├── BETextEditor.swift
│ │ ├── SelectLanguageView
│ │ │ └── SelectLanguageView.swift
│ │ └── Project
│ │ │ └── LocalizableFileView.swift
│ ├── Handlers
│ │ └── OpenProjectHandler.swift
│ ├── Injected
│ │ └── App+Resolver.swift
│ └── Repository
│ │ └── ProjectRepository.swift
├── Tests
│ ├── EditMeBeforeTesting.swift
│ ├── Utilities
│ │ └── TestProjectRepository.swift
│ ├── Extensions
│ │ └── PBXGroupTests.swift
│ └── Services
│ │ └── XcodeProjectServiceTests.swift
└── Info.plist
├── images
├── screenshot.png
├── translate-key.png
├── choose-languages.png
└── add-and-copy-to-clipboard.png
├── ruby
├── Localizable.strings
└── index.rb
├── release
└── LocalizationHelper.zip
├── Demo
├── LocalizationHelperDemo
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Preview Content
│ │ └── Preview Assets.xcassets
│ │ │ └── Contents.json
│ ├── en.lproj
│ │ └── Localizable.strings
│ ├── ar-LY.lproj
│ │ └── Localizable.strings
│ ├── es.lproj
│ │ └── Localizable.strings
│ ├── fr.lproj
│ │ └── Localizable.strings
│ ├── vi.lproj
│ │ └── Localizable.strings
│ ├── ru-RU.lproj
│ │ └── Localizable.strings
│ ├── LocalizationHelperDemoApp.swift
│ ├── ContentView.swift
│ └── Info.plist
├── LocalizationHelperDemo.xcodeproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── .gitignore
├── Kit
├── Tests
│ ├── Resources
│ │ └── Localizable.strings
│ ├── ConfigRepositoryTests.swift
│ └── StreamReaderTests.swift
└── Sources
│ ├── ConfigManager
│ ├── ConfigRepositoryError.swift
│ ├── Config.swift
│ ├── ConfigManager.swift
│ └── ConfigRepository.swift
│ ├── EventMonitor.swift
│ ├── GoogleTranslate.swift
│ └── StreamReader.swift
├── LICENSE.txt
├── .gitignore
├── .package.resolved
├── Project.swift
└── Tuist
└── ResourceSynthesizers
└── Strings.stencil
/Apps/Resources/ru.lproj/LaunchScreen.strings:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/images/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/images/screenshot.png
--------------------------------------------------------------------------------
/ruby/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
--------------------------------------------------------------------------------
/images/translate-key.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/images/translate-key.png
--------------------------------------------------------------------------------
/images/choose-languages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/images/choose-languages.png
--------------------------------------------------------------------------------
/Apps/Resources/Colors.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/release/LocalizationHelper.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/release/LocalizationHelper.zip
--------------------------------------------------------------------------------
/images/add-and-copy-to-clipboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/images/add-and-copy-to-clipboard.png
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Tuist/Config.swift:
--------------------------------------------------------------------------------
1 | import ProjectDescription
2 |
3 | let config = Config(
4 | generationOptions: []
5 | )
6 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/Sources/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1/vi.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Apps/Resources/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | p2p_wallet
4 |
5 | Created by Chung Tran on 10/23/20.
6 |
7 | */
8 | "hello" = "hello";
9 |
--------------------------------------------------------------------------------
/Apps/Resources/ru.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | p2p_wallet
4 |
5 | Created by Chung Tran on 10/23/20.
6 |
7 | */
8 | "hello" = "привет";
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2/Resources/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | Test2
4 |
5 | Created by Chung Tran on 20/07/2021.
6 |
7 | */
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2/Resources/vi.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | Test2
4 |
5 | Created by Chung Tran on 20/07/2021.
6 |
7 | */
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3/1/1.1/1.1.1/1.1.1.2/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3/1/1.1/1.1.1/1.1.1.2/vi.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 |
--------------------------------------------------------------------------------
/Apps/Resources/Base.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | p2p_wallet
4 |
5 | Created by Chung Tran on 10/23/20.
6 |
7 | */
8 | "hello" = "hello";
9 |
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/128.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/16.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/256.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/32.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/512.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/64.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/256-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/256-1.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/32-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/32-1.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/New Project (11)-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/New Project (11)-1.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/New Project (12).png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/AppIcon.appiconset/New Project (12).png
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/en.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 | "test" = "test";
9 | "hello" = "hello";
10 | "good" = "good";
11 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/ar-LY.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 | "test" = "اختبار";
9 | "hello" = "مرحبا";
10 | "good" = "حسن";
11 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/es.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 | "test" = "prueba";
9 | "hello" = "Hola";
10 | "good" = "bien";
11 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/fr.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 | "test" = "test";
9 | "hello" = "Bonjour";
10 | "good" = "bien";
11 |
--------------------------------------------------------------------------------
/Kit/Tests/Resources/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 | LocalizationHelper
4 |
5 | Created by Chung Tran on 15/04/2023.
6 |
7 | */
8 |
9 | "test"="test";
10 | "test\nnewline"="test\nnewline";
11 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/vi.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 | "test" = "kiểm tra";
9 | "hello" = "xin chào";
10 | "good" = "tốt";
11 |
--------------------------------------------------------------------------------
/Apps/Sources/Extensions/Typealiases.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Typealiases.swift
3 | // Bigvalut
4 | //
5 | // Created by Chung Tran on 27/06/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | public typealias Strings = L10n.Localizable
11 |
--------------------------------------------------------------------------------
/Apps/Resources/LocalizationHelper.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Apps/Sources/Models/Constants.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Constants.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 21/07/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | let LOCALIZABLE_STRINGS = "Localizable.strings"
11 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/ru-RU.lproj/Localizable.strings:
--------------------------------------------------------------------------------
1 | /*
2 | Localizable.strings
3 |
4 | Created with LocalizationHelper.
5 |
6 | */
7 |
8 | "test" = "контрольная работа";
9 | "hello" = "Привет";
10 | "good" = "хорошо";
11 |
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/status-bar-icon.imageset/letterboxd-decal-l-pos-rgb-500px.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/status-bar-icon.imageset/letterboxd-decal-l-pos-rgb-500px.png
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Targets/TestWithTuist/Tests/AppTests.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import XCTest
3 |
4 | final class TestWithTuistTests: XCTestCase {
5 | func test_twoPlusTwo_isFour() {
6 | XCTAssertEqual(2+2, 4)
7 | }
8 | }
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Targets/TestWithTuistUI/Sources/TestWithTuistUI.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public final class TestWithTuistUI {
4 | public static func hello() {
5 | print("Hello, from your UI framework")
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/status-bar-icon.imageset/letterboxd-decal-l-pos-rgb-500px@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/status-bar-icon.imageset/letterboxd-decal-l-pos-rgb-500px@2x.png
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/status-bar-icon.imageset/letterboxd-decal-l-pos-rgb-500px@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bigearsenal/XCodeLocalizationHelper/HEAD/Apps/Resources/macOS.xcassets/status-bar-icon.imageset/letterboxd-decal-l-pos-rgb-500px@3x.png
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Targets/TestWithTuistKit/Sources/TestWithTuistKit.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | public final class TestWithTuistKit {
4 | public static func hello() {
5 | print("Hello, from your Kit framework")
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Targets/TestWithTuistUI/Tests/TestWithTuistUITests.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import XCTest
3 |
4 | final class TestWithTuistUITests: XCTestCase {
5 | func test_example() {
6 | XCTAssertEqual("TestWithTuistUI", "TestWithTuistUI")
7 | }
8 | }
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Targets/TestWithTuistKit/Tests/TestWithTuistKitTests.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import XCTest
3 |
4 | final class TestWithTuistKitTests: XCTestCase {
5 | func test_example() {
6 | XCTAssertEqual("TestWithTuistKit", "TestWithTuistKit")
7 | }
8 | }
--------------------------------------------------------------------------------
/Apps/Sources/Services/LocalizableFileService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LocalizableFileService.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 21/07/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol LocalizableFileServiceType {
11 | var file: LocalizableFile {get}
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/Kit/Sources/ConfigManager/ConfigRepositoryError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ConfigReaderError.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 26/04/2023.
6 | //
7 |
8 | import Foundation
9 |
10 | enum ConfigRepositoryError: Error {
11 | case couldNotOpenFile
12 | case invalidFileFormat
13 | }
14 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1/Test1.xcdatamodeld/.xccurrentversion:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | _XCCurrentVersionName
6 | Test1.xcdatamodel
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2/Test2.xcdatamodeld/.xccurrentversion:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | _XCCurrentVersionName
6 | Test2.xcdatamodel
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3/Test3.xcdatamodeld/.xccurrentversion:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | _XCCurrentVersionName
6 | Test3.xcdatamodel
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4/Test4.xcdatamodeld/.xccurrentversion:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | _XCCurrentVersionName
6 | Test4.xcdatamodel
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1/Test1.xcdatamodeld/Test1.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2/Test2.xcdatamodeld/Test2.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3/Test3.xcdatamodeld/Test3.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4/Test4.xcdatamodeld/Test4.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/LocalizationHelperDemoApp.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LocalizationHelperDemoApp.swift
3 | // LocalizationHelperDemo
4 | //
5 | // Created by Chung Tran on 28/06/2021.
6 | //
7 |
8 | import SwiftUI
9 |
10 | @main
11 | struct LocalizationHelperDemoApp: App {
12 | var body: some Scene {
13 | WindowGroup {
14 | ContentView()
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Test1
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import UIKit
9 |
10 | class ViewController: UIViewController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | // Do any additional setup after loading the view.
15 | }
16 |
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Test2
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import UIKit
9 |
10 | class ViewController: UIViewController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | // Do any additional setup after loading the view.
15 | }
16 |
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Test3
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import UIKit
9 |
10 | class ViewController: UIViewController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | // Do any additional setup after loading the view.
15 | }
16 |
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Test4
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import UIKit
9 |
10 | class ViewController: UIViewController {
11 |
12 | override func viewDidLoad() {
13 | super.viewDidLoad()
14 | // Do any additional setup after loading the view.
15 | }
16 |
17 |
18 | }
19 |
20 |
--------------------------------------------------------------------------------
/Apps/Sources/System/Application.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Application.swift
3 | // LocalizationHelper_macos
4 | //
5 | // Created by Chung Tran on 28/06/2021.
6 | //
7 |
8 | import Cocoa
9 |
10 | class Application: NSApplication {
11 |
12 | let strongDelegate = AppDelegate()
13 |
14 | override init() {
15 | super.init()
16 | self.delegate = strongDelegate
17 | }
18 |
19 | required init?(coder: NSCoder) {
20 | fatalError("init(coder:) has not been implemented")
21 | }
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/Demo/LocalizationHelperDemo/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // LocalizationHelperDemo
4 | //
5 | // Created by Chung Tran on 28/06/2021.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct ContentView: View {
11 | var body: some View {
12 | Text("hello")
13 | .padding()
14 | }
15 | }
16 |
17 | struct ContentView_Previews: PreviewProvider {
18 | static var previews: some View {
19 | ContentView()
20 | .environment(\.locale, .init(identifier: "es"))
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Apps/Sources/Extensions/Strings+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Strings+Extensions.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 24/07/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | extension String {
11 | static var stringsFileHeader: String {
12 | """
13 | /*
14 | Localizable.strings
15 |
16 | Created with XCodeLocalizationHelper.
17 | https://github.com/bigearsenal/xcodelocalizationhelper
18 |
19 | */
20 |
21 |
22 | """
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/Apps/Sources/Models/AppState.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppState.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 19/07/2021.
6 | //
7 |
8 | import Foundation
9 | import Combine
10 |
11 | /// The struct that contains all shared data inside application
12 | struct AppState: Equatable {
13 | var project: Project?
14 |
15 | static var initial: Self {
16 | .init(project: nil)
17 | }
18 | }
19 |
20 | #if DEBUG
21 | extension AppState {
22 | static var preview: AppState {
23 | AppState()
24 | }
25 | }
26 | #endif
27 |
--------------------------------------------------------------------------------
/Apps/Sources/Extensions/Binding+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 27/12/2020.
6 | //
7 |
8 | import Foundation
9 | import SwiftUI
10 |
11 | extension Binding {
12 | func didSet(_ execute: @escaping (Value) -> Void) -> Binding {
13 | return Binding(
14 | get: {
15 | return self.wrappedValue
16 | },
17 | set: {
18 | self.wrappedValue = $0
19 | execute($0)
20 | }
21 | )
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Apps/Sources/Utilities/CancelBag.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CancelBag.swift
3 | // CountriesSwiftUI
4 | //
5 | // Created by Alexey Naumov on 04.04.2020.
6 | // Copyright © 2020 Alexey Naumov. All rights reserved.
7 | //
8 |
9 | import Combine
10 |
11 | final class CancelBag {
12 | fileprivate(set) var subscriptions = Set()
13 |
14 | func cancel() {
15 | subscriptions.removeAll()
16 | }
17 | }
18 |
19 | extension AnyCancellable {
20 |
21 | func store(in cancelBag: CancelBag) {
22 | cancelBag.subscriptions.insert(self)
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/status-bar-icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "letterboxd-decal-l-pos-rgb-500px.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "letterboxd-decal-l-pos-rgb-500px@2x.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "filename" : "letterboxd-decal-l-pos-rgb-500px@3x.png",
15 | "idiom" : "universal",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "author" : "xcode",
21 | "version" : 1
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/Apps/Tests/EditMeBeforeTesting.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | // LocalizationHelperTests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import Foundation
9 | import XcodeProj
10 |
11 | // FIXME: - REPLACE THIS URL BEFORE TESTING
12 | let repositoryLocalURL = "/Users/bigears/Documents/macos/XCodeLocalizationHelper"
13 |
14 | let homeUrl = repositoryLocalURL + "/Apps/TestsProjects/"
15 |
16 | let LOCALIZABLE_STRINGS = "Localizable.strings"
17 |
18 | func xcodeprojPath(fileName: String) -> String {
19 | homeUrl + fileName + "/" + fileName + ".xcodeproj"
20 | }
21 | func getXcodeProj(fileName: String) throws -> XcodeProj {
22 | try XcodeProj(pathString: xcodeprojPath(fileName: fileName))
23 | }
24 |
--------------------------------------------------------------------------------
/Apps/Sources/Models/LocalizationHelperError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Error.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 21/07/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | enum LocalizationHelperError: String, Swift.Error {
11 | case projectNotFound
12 | case targetNotFound
13 | case localizableStringsGroupNotFound
14 | case localizableStringsGroupFullPathNotFound
15 | case couldNotCreateLocalizableStringsGroup
16 | case resourcePathIsNotADirectory
17 | case resourcePathMustBeInsideProjectPath
18 | case lineReaderInitializingError
19 | }
20 |
21 | extension LocalizationHelperError: LocalizedError {
22 | var errorDescription: String? {
23 | self.rawValue
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Apps/Sources/Models/Project/TuistProject.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TuistProject.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 21/07/2021.
6 | //
7 |
8 | import Foundation
9 | import PathKit
10 |
11 | struct TuistProject: Equatable {
12 | var path: Path
13 | var resourcePath: Path
14 | var projectName: String
15 | }
16 |
17 | extension TuistProject {
18 | func localize(fileGenerator: FileGeneratorType, languageCode: String) throws
19 | {
20 | let path = resourcePath
21 | guard path.isDirectory else {
22 | throw LocalizationHelperError.resourcePathIsNotADirectory
23 | }
24 |
25 | try fileGenerator.generateFile(at: path + "\(languageCode).lproj", fileName: LOCALIZABLE_STRINGS, content: .stringsFileHeader)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Kit/Sources/ConfigManager/Config.swift:
--------------------------------------------------------------------------------
1 | //
2 | // XCodeLocalizationHelperConfig.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 26/04/2023.
6 | //
7 |
8 | import Foundation
9 |
10 | public struct Config: Codable {
11 | public init(automation: AutomationConfig) {
12 | self.automation = automation
13 | }
14 |
15 | public let automation: AutomationConfig
16 | }
17 |
18 | public struct AutomationConfig: Codable {
19 | public init(script: String, pathType: AutomationConfigPathType) {
20 | self.script = script
21 | self.pathType = pathType
22 | }
23 |
24 | public let script: String
25 | public let pathType: AutomationConfigPathType
26 | }
27 |
28 | public enum AutomationConfigPathType: String, Codable {
29 | case relative
30 | case absolute
31 | }
32 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Targets/TestWithTuist/Sources/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import TestWithTuistKit
3 | import TestWithTuistUI
4 |
5 | @main
6 | class AppDelegate: UIResponder, UIApplicationDelegate {
7 |
8 | var window: UIWindow?
9 |
10 | func application(
11 | _ application: UIApplication,
12 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
13 | ) -> Bool {
14 | window = UIWindow(frame: UIScreen.main.bounds)
15 | let viewController = UIViewController()
16 | viewController.view.backgroundColor = .white
17 | window?.rootViewController = viewController
18 | window?.makeKeyAndVisible()
19 | TestWithTuistKit.hello()
20 | TestWithTuistUI.hello()
21 |
22 | return true
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1UITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2UITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3UITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4UITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Apps/Sources/UI/Link.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Link.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 14/01/2021.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct Link: View {
11 | let url: String
12 | let description: String?
13 |
14 | var body: some View {
15 | Button(action: {
16 | if let url = URL(string: url) {
17 | NSWorkspace.shared.open(url)
18 | }
19 | }) {
20 | Text(description ?? url).underline()
21 | .foregroundColor(Color.blue)
22 | }
23 | .buttonStyle(PlainButtonStyle())
24 | .onHover { inside in
25 | if inside {
26 | NSCursor.pointingHand.push()
27 | } else {
28 | NSCursor.pop()
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Demo/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 | .idea/
9 |
10 | ## Various settings
11 | *.pbxuser
12 | !default.pbxuser
13 | *.mode1v3
14 | !default.mode1v3
15 | *.mode2v3
16 | !default.mode2v3
17 | *.perspectivev3
18 | !default.perspectivev3
19 | xcuserdata/
20 |
21 | ## Other
22 | *.moved-aside
23 | *.xccheckout
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 | *.dSYM.zip
30 | *.dSYM
31 |
32 | ## Playgrounds
33 | timeline.xctimeline
34 | playground.xcworkspace
35 |
36 | # Swift Package Manager
37 | #
38 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
39 | # Packages/
40 | # Package.pins
41 | # Package.resolved
42 | .build/
43 |
44 |
--------------------------------------------------------------------------------
/Kit/Sources/EventMonitor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EventMonitor.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 14/01/2021.
6 | //
7 |
8 | import Cocoa
9 |
10 | public class EventMonitor {
11 | private var monitor: Any?
12 | private let mask: NSEvent.EventTypeMask
13 | private let handler: (NSEvent?) -> Void
14 |
15 | public init(mask: NSEvent.EventTypeMask, handler: @escaping (NSEvent?) -> Void) {
16 | self.mask = mask
17 | self.handler = handler
18 | }
19 |
20 | deinit {
21 | stop()
22 | }
23 |
24 | public func start() {
25 | monitor = NSEvent.addGlobalMonitorForEvents(matching: mask, handler: handler) as! NSObject
26 | }
27 |
28 | public func stop() {
29 | if monitor != nil {
30 | NSEvent.removeMonitor(monitor!)
31 | monitor = nil
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Apps/Resources/Colors.xcassets/customGray.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0xBA",
9 | "green" : "0xA5",
10 | "red" : "0xA3"
11 | }
12 | },
13 | "idiom" : "universal"
14 | },
15 | {
16 | "appearances" : [
17 | {
18 | "appearance" : "luminosity",
19 | "value" : "dark"
20 | }
21 | ],
22 | "color" : {
23 | "color-space" : "srgb",
24 | "components" : {
25 | "alpha" : "1.000",
26 | "blue" : "1.000",
27 | "green" : "1.000",
28 | "red" : "1.000"
29 | }
30 | },
31 | "idiom" : "universal"
32 | }
33 | ],
34 | "info" : {
35 | "author" : "xcode",
36 | "version" : 1
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Apps/Sources/Handlers/OpenProjectHandler.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OpenProjectHandler.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 25/07/2021.
6 | //
7 |
8 | import Foundation
9 | import XcodeProj
10 | import PathKit
11 |
12 | protocol OpenProjectHandler {
13 | func openProject(_ project: Project) throws
14 | }
15 |
16 | extension OpenProjectHandler {
17 | func openDefaultProject(xcodeproj: XcodeProj, targetName: String, path: Path) throws {
18 | guard let target = xcodeproj.pbxproj.targets(named: targetName).first
19 | else {
20 | throw LocalizationHelperError.targetNotFound
21 | }
22 | try openProject(.default(.init(pxbproj: xcodeproj, target: target, path: path)))
23 | }
24 | }
25 |
26 | #if DEBUG
27 | struct OpenProjectHandler_Preview: OpenProjectHandler {
28 | func openProject(_ project: Project) throws {
29 | // do nothing
30 | }
31 | }
32 | #endif
33 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1Tests/Test1Tests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test1Tests.swift
3 | // Test1Tests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 | @testable import Test1
10 |
11 | class Test1Tests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 | }
16 |
17 | override func tearDownWithError() throws {
18 | // Put teardown code here. This method is called after the invocation of each test method in the class.
19 | }
20 |
21 | func testExample() throws {
22 | // This is an example of a functional test case.
23 | // Use XCTAssert and related functions to verify your tests produce the correct results.
24 | }
25 |
26 | func testPerformanceExample() throws {
27 | // This is an example of a performance test case.
28 | self.measure {
29 | // Put the code you want to measure the time of here.
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2Tests/Test2Tests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test2Tests.swift
3 | // Test2Tests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 | @testable import Test2
10 |
11 | class Test2Tests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 | }
16 |
17 | override func tearDownWithError() throws {
18 | // Put teardown code here. This method is called after the invocation of each test method in the class.
19 | }
20 |
21 | func testExample() throws {
22 | // This is an example of a functional test case.
23 | // Use XCTAssert and related functions to verify your tests produce the correct results.
24 | }
25 |
26 | func testPerformanceExample() throws {
27 | // This is an example of a performance test case.
28 | self.measure {
29 | // Put the code you want to measure the time of here.
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3Tests/Test3Tests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test3Tests.swift
3 | // Test3Tests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 | @testable import Test3
10 |
11 | class Test3Tests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 | }
16 |
17 | override func tearDownWithError() throws {
18 | // Put teardown code here. This method is called after the invocation of each test method in the class.
19 | }
20 |
21 | func testExample() throws {
22 | // This is an example of a functional test case.
23 | // Use XCTAssert and related functions to verify your tests produce the correct results.
24 | }
25 |
26 | func testPerformanceExample() throws {
27 | // This is an example of a performance test case.
28 | self.measure {
29 | // Put the code you want to measure the time of here.
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4Tests/Test4Tests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test4Tests.swift
3 | // Test4Tests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 | @testable import Test4
10 |
11 | class Test4Tests: XCTestCase {
12 |
13 | override func setUpWithError() throws {
14 | // Put setup code here. This method is called before the invocation of each test method in the class.
15 | }
16 |
17 | override func tearDownWithError() throws {
18 | // Put teardown code here. This method is called after the invocation of each test method in the class.
19 | }
20 |
21 | func testExample() throws {
22 | // This is an example of a functional test case.
23 | // Use XCTAssert and related functions to verify your tests produce the correct results.
24 | }
25 |
26 | func testPerformanceExample() throws {
27 | // This is an example of a performance test case.
28 | self.measure {
29 | // Put the code you want to measure the time of here.
30 | }
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/Project.swift:
--------------------------------------------------------------------------------
1 | import ProjectDescription
2 | import ProjectDescriptionHelpers
3 |
4 | /*
5 | +-------------+
6 | | |
7 | | App | Contains TestWithTuist App target and TestWithTuist unit-test target
8 | | |
9 | +------+-------------+-------+
10 | | depends on |
11 | | |
12 | +----v-----+ +-----v-----+
13 | | | | |
14 | | Kit | | UI | Two independent frameworks to share code and start modularising your app
15 | | | | |
16 | +----------+ +-----------+
17 |
18 | */
19 |
20 | // MARK: - Project
21 |
22 | // Creates our project using a helper function defined in ProjectDescriptionHelpers
23 | let project = Project.app(name: "TestWithTuist",
24 | platform: .iOS,
25 | additionalTargets: ["TestWithTuistKit", "TestWithTuistUI"])
26 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Othneil Drew
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/Apps/Sources/Injected/App+Resolver.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Resolver.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 24/07/2021.
6 | //
7 |
8 | @_exported import Resolver
9 |
10 | extension Resolver: ResolverRegistering {
11 | #if DEBUG
12 | static let mock = Resolver(parent: main)
13 | #endif
14 |
15 | public static func registerAllServices() {
16 | register {StringsFileGenerator() as FileGeneratorType}
17 | register {UserDefaultsProjectRepository() as ProjectRepositoryType}
18 | register {FilePickerService() as FilePickerServiceType}
19 | register {XCodeProjectService() as XCodeProjectServiceType}
20 |
21 | #if DEBUG
22 | // mock.register {FakeStringsFileGenerator() as FileGeneratorType}
23 | // mock.register {InMemoryProjectRepository.default as ProjectRepositoryType}
24 | // mock.register {MockFilePickerService() as FilePickerServiceType}
25 | // mock.register {OpenProjectHandler_Preview() as OpenProjectHandler}
26 |
27 | // register entire container as replacement for main
28 | // root = mock
29 | #endif
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Apps/Sources/System/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 10/17/20.
6 | //
7 |
8 | import Cocoa
9 | import SwiftUI
10 |
11 | @NSApplicationMain
12 | class AppDelegate: NSObject, NSApplicationDelegate {
13 |
14 | var window: NSWindow!
15 | var statusBar: StatusBarController?
16 | var popover = NSPopover()
17 |
18 | func applicationDidFinishLaunching(_ aNotification: Notification) {
19 | // Create the SwiftUI view that provides the window contents.
20 | let viewModel = MainViewModel()
21 | let contentView = MainView(viewModel: viewModel)
22 |
23 | // Set the SwiftUI's ContentView to the Popover's ContentViewController
24 | popover.contentSize = NSSize(width: 680, height: 300)
25 | popover.contentViewController = NSHostingController(rootView: contentView)
26 |
27 | // Initialising the status bar
28 | statusBar = StatusBarController(popover) { [weak viewModel] in
29 | viewModel?.refresh()
30 | }
31 | }
32 |
33 | func applicationWillTerminate(_ aNotification: Notification) {
34 | // Insert code here to tear down your application
35 | }
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Apps/Tests/Utilities/TestProjectRepository.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TestProjectRepository.swift
3 | // LocalizationHelperTests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import Foundation
9 | @testable import LocalizationHelper
10 | import PathKit
11 |
12 | struct TestProjectRepository: ProjectRepositoryType {
13 | let testName: String
14 |
15 | func getCurrentProject() -> Project? {
16 | switch testName {
17 | case let testName where testName.starts(with: "TestWithTuist"):
18 | // TuistProject
19 | let path = Path(homeUrl) + testName + "Targets" + testName + "Resources"
20 | return .tuist(.init(path: path, resourcePath: path, projectName: testName))
21 | case let testName where testName.starts(with: "Test"):
22 | // DefaultProject
23 | let proj = try! getXcodeProj(fileName: testName)
24 | let target = proj.pbxproj.targets(named: testName).first!
25 | return .default(.init(pxbproj: proj, target: target, path: Path(xcodeprojPath(fileName: testName))))
26 | default:
27 | return nil
28 | }
29 | }
30 |
31 | func setCurrentProject(_ project: Project) {}
32 |
33 | func clearCurrentProject() {}
34 | }
35 |
--------------------------------------------------------------------------------
/Apps/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 2.3
19 | CFBundleVersion
20 | 1
21 | LSMinimumSystemVersion
22 | 12.0
23 | NSHumanReadableCopyright
24 | Copyright ©. All rights reserved.
25 | NSPrincipalClass
26 | LocalizationHelper.Application
27 | LSApplicationCategoryType
28 | public.app-category.developer-tools
29 | UILaunchScreen
30 |
31 | LSUIElement
32 |
33 | NSMainStoryboardFile
34 | Main
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Kit/Tests/ConfigRepositoryTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ConfigRepositoryTests.swift
3 | // LocalizationHelperKitTests
4 | //
5 | // Created by Chung Tran on 26/04/2023.
6 | //
7 |
8 | import XCTest
9 | import LocalizationHelperKit
10 |
11 | final class ConfigRepositoryTests: XCTestCase {
12 |
13 | var repository: ConfigRepositoryImpl!
14 |
15 | override func setUpWithError() throws {
16 | repository = .init(projectDir: "/Users/chungtran/documents/ios/p2p-wallet-ios")
17 | }
18 |
19 | override func tearDownWithError() throws {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | }
22 |
23 | func testGetConfig() async throws {
24 | let config = try await repository.getConfig()
25 | XCTAssertEqual(config.automation.script, "swiftgen config run --config ${PROJECT_DIR}/swiftgen.yml")
26 | XCTAssertEqual(config.automation.pathType, .absolute)
27 | }
28 |
29 | func testSaveConfig() async throws {
30 | try await repository.saveConfig(
31 | .init(
32 | automation: .init(
33 | script: "swiftgen config run --config swiftgen.yml",
34 | pathType: .relative
35 | )
36 | )
37 | )
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Apps/Resources/Base.lproj/Localizable.stringsdict:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | %d hidden wallet
6 |
7 | NSStringLocalizedFormatKey
8 | %#@variable_0@
9 | variable_0
10 |
11 | NSStringFormatSpecTypeKey
12 | NSStringPluralRuleType
13 | NSStringFormatValueTypeKey
14 | d
15 | one
16 | %d hidden wallet
17 | other
18 | %d hidden wallets
19 |
20 |
21 | Wrong Pin-code, %d attempt(s) left
22 |
23 | NSStringLocalizedFormatKey
24 | %#@variable_0@
25 | variable_0
26 |
27 | NSStringFormatSpecTypeKey
28 | NSStringPluralRuleType
29 | NSStringFormatValueTypeKey
30 | d
31 | one
32 | Wrong Pin-code, %d attempt left
33 | other
34 | Wrong Pin-code, %d attempts left
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Apps/Resources/en.lproj/Localizable.stringsdict:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | %d hidden wallet
6 |
7 | NSStringLocalizedFormatKey
8 | %#@variable_0@
9 | variable_0
10 |
11 | NSStringFormatSpecTypeKey
12 | NSStringPluralRuleType
13 | NSStringFormatValueTypeKey
14 | d
15 | one
16 | %d hidden wallet
17 | other
18 | %d hidden wallets
19 |
20 |
21 | Wrong Pin-code, %d attempt(s) left
22 |
23 | NSStringLocalizedFormatKey
24 | %#@variable_0@
25 | variable_0
26 |
27 | NSStringFormatSpecTypeKey
28 | NSStringPluralRuleType
29 | NSStringFormatValueTypeKey
30 | d
31 | one
32 | Wrong Pin-code, %d attempt left
33 | other
34 | Wrong Pin-code, %d attempts left
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/Apps/Tests/Extensions/PBXGroupTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // PBXGroupTests.swift
3 | // LocalizationHelperKitTests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 | @testable import LocalizationHelper
10 |
11 | class PBXGroupTests: XCTestCase {
12 |
13 | func testGetGroupRecursively1() throws {
14 | let project = try getXcodeProj(fileName: "Test1")
15 |
16 | let group = project.pbxproj.rootObject?.mainGroup
17 | .group(named: LOCALIZABLE_STRINGS, recursively: true)
18 | XCTAssertNotNil(group)
19 | }
20 |
21 | func testGetGroupRecursively2() throws {
22 | let project = try getXcodeProj(fileName: "Test2")
23 |
24 | let group = project.pbxproj.rootObject?.mainGroup
25 | .group(named: LOCALIZABLE_STRINGS, recursively: true)
26 | XCTAssertNotNil(group)
27 | }
28 |
29 | func testGetGroupRecursively3() throws {
30 | let project = try getXcodeProj(fileName: "Test3")
31 |
32 | let group = project.pbxproj.rootObject?.mainGroup
33 | .group(named: LOCALIZABLE_STRINGS, recursively: true)
34 | XCTAssertNotNil(group)
35 | }
36 |
37 | func testGetGroupRecursively4() throws {
38 | let project = try getXcodeProj(fileName: "Test4")
39 |
40 | let group = project.pbxproj.rootObject?.mainGroup
41 | .group(named: LOCALIZABLE_STRINGS, recursively: true)
42 | XCTAssertNil(group)
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### macOS ###
2 | # General
3 | .DS_Store
4 | .AppleDouble
5 | .LSOverride
6 |
7 | # Icon must end with two
8 | Icon
9 |
10 | # Thumbnails
11 | ._*
12 |
13 | # Files that might appear in the root of a volume
14 | .DocumentRevisions-V100
15 | .fseventsd
16 | .Spotlight-V100
17 | .TemporaryItems
18 | .Trashes
19 | .VolumeIcon.icns
20 | .com.apple.timemachine.donotpresent
21 |
22 | # Directories potentially created on remote AFP share
23 | .AppleDB
24 | .AppleDesktop
25 | Network Trash Folder
26 | Temporary Items
27 | .apdisk
28 |
29 | ### Xcode ###
30 | # Xcode
31 | #
32 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
33 |
34 | ## User settings
35 | xcuserdata/
36 |
37 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
38 | *.xcscmblueprint
39 | *.xccheckout
40 |
41 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
42 | build/
43 | DerivedData/
44 | *.moved-aside
45 | *.pbxuser
46 | !default.pbxuser
47 | *.mode1v3
48 | !default.mode1v3
49 | *.mode2v3
50 | !default.mode2v3
51 | *.perspectivev3
52 | !default.perspectivev3
53 |
54 | ### Xcode Patch ###
55 | *.xcodeproj/*
56 | !*.xcodeproj/project.pbxproj
57 | !*.xcodeproj/xcshareddata/
58 | !*.xcworkspace/contents.xcworkspacedata
59 | /*.gcno
60 |
61 | ### Projects ###
62 | /*.xcodeproj
63 | /*.xcworkspace
64 |
65 | ### Tuist derived files ###
66 | graph.dot
67 | Derived/
68 |
69 | ### Tuist managed dependencies ###
70 | Tuist/Dependencies
71 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/TestWithTuist/.gitignore:
--------------------------------------------------------------------------------
1 | ### macOS ###
2 | # General
3 | .DS_Store
4 | .AppleDouble
5 | .LSOverride
6 |
7 | # Icon must end with two
8 | Icon
9 |
10 | # Thumbnails
11 | ._*
12 |
13 | # Files that might appear in the root of a volume
14 | .DocumentRevisions-V100
15 | .fseventsd
16 | .Spotlight-V100
17 | .TemporaryItems
18 | .Trashes
19 | .VolumeIcon.icns
20 | .com.apple.timemachine.donotpresent
21 |
22 | # Directories potentially created on remote AFP share
23 | .AppleDB
24 | .AppleDesktop
25 | Network Trash Folder
26 | Temporary Items
27 | .apdisk
28 |
29 | ### Xcode ###
30 | # Xcode
31 | #
32 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
33 |
34 | ## User settings
35 | xcuserdata/
36 |
37 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
38 | *.xcscmblueprint
39 | *.xccheckout
40 |
41 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
42 | build/
43 | DerivedData/
44 | *.moved-aside
45 | *.pbxuser
46 | !default.pbxuser
47 | *.mode1v3
48 | !default.mode1v3
49 | *.mode2v3
50 | !default.mode2v3
51 | *.perspectivev3
52 | !default.perspectivev3
53 |
54 | ### Xcode Patch ###
55 | *.xcodeproj/*
56 | !*.xcodeproj/project.pbxproj
57 | !*.xcodeproj/xcshareddata/
58 | !*.xcworkspace/contents.xcworkspacedata
59 | /*.gcno
60 |
61 | ### Projects ###
62 | *.xcodeproj
63 | *.xcworkspace
64 |
65 | ### Tuist derived files ###
66 | graph.dot
67 | Derived/
68 |
69 | ### Tuist managed dependencies ###
70 | Tuist/Dependencies
71 |
--------------------------------------------------------------------------------
/Apps/Sources/UI/OpenProject/OpenProjectView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OpenProjectView.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 24/07/2021.
6 | //
7 |
8 | import SwiftUI
9 |
10 | struct OpenProjectView: View {
11 | // MARK: - Nested type
12 | enum ProjectType: String {
13 | case `default`
14 | case tuist
15 | }
16 |
17 | // MARK: - State
18 | @State private var projectType = ProjectType.default
19 | let handler: OpenProjectHandler
20 |
21 | // MARK: - Body
22 | var body: some View {
23 | Group {
24 | Picker("", selection: $projectType) {
25 | Text("Default project").tag(ProjectType.default)
26 | Text("Tuist project").tag(ProjectType.tuist)
27 | }
28 | .pickerStyle(SegmentedPickerStyle())
29 | .padding()
30 |
31 | content
32 | .padding()
33 |
34 | Spacer()
35 | }
36 |
37 | }
38 |
39 | var content: AnyView {
40 | switch projectType {
41 | case .default:
42 | return AnyView(DefaultProjectView(handler: handler))
43 | case .tuist:
44 | return AnyView(TuistProjectView(handler: handler))
45 | }
46 | }
47 | }
48 |
49 | #if DEBUG
50 | struct OpenProjectView_Previews: PreviewProvider {
51 | static var previews: some View {
52 | OpenProjectView(handler: OpenProjectHandler_Preview())
53 | .frame(width: 500, height: 500)
54 | }
55 | }
56 | #endif
57 |
--------------------------------------------------------------------------------
/Apps/Resources/macOS.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "16.png",
5 | "idiom" : "mac",
6 | "scale" : "1x",
7 | "size" : "16x16"
8 | },
9 | {
10 | "filename" : "32.png",
11 | "idiom" : "mac",
12 | "scale" : "2x",
13 | "size" : "16x16"
14 | },
15 | {
16 | "filename" : "32-1.png",
17 | "idiom" : "mac",
18 | "scale" : "1x",
19 | "size" : "32x32"
20 | },
21 | {
22 | "filename" : "64.png",
23 | "idiom" : "mac",
24 | "scale" : "2x",
25 | "size" : "32x32"
26 | },
27 | {
28 | "filename" : "128.png",
29 | "idiom" : "mac",
30 | "scale" : "1x",
31 | "size" : "128x128"
32 | },
33 | {
34 | "filename" : "256.png",
35 | "idiom" : "mac",
36 | "scale" : "2x",
37 | "size" : "128x128"
38 | },
39 | {
40 | "filename" : "256-1.png",
41 | "idiom" : "mac",
42 | "scale" : "1x",
43 | "size" : "256x256"
44 | },
45 | {
46 | "filename" : "512.png",
47 | "idiom" : "mac",
48 | "scale" : "2x",
49 | "size" : "256x256"
50 | },
51 | {
52 | "filename" : "New Project (11)-1.png",
53 | "idiom" : "mac",
54 | "scale" : "1x",
55 | "size" : "512x512"
56 | },
57 | {
58 | "filename" : "New Project (12).png",
59 | "idiom" : "mac",
60 | "scale" : "2x",
61 | "size" : "512x512"
62 | }
63 | ],
64 | "info" : {
65 | "author" : "xcode",
66 | "version" : 1
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Apps/Sources/UI/Main/MainViewModel.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MainViewModel.swift
3 | // LocalizationHelper
4 | //
5 | // Created by Chung Tran on 24/07/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | @MainActor
11 | class MainViewModel: ObservableObject {
12 | // MARK: - Dependencies
13 | @Injected var projectService: XCodeProjectServiceType
14 |
15 | // MARK: - Properties
16 | @Published var appState: AppState = .initial
17 | var projectViewModel: ProjectViewModel!
18 |
19 | init() {
20 | try? openCurrentProject()
21 | }
22 |
23 | // MARK: - Methods
24 | func openCurrentProject() throws {
25 | let project = try projectService.openCurrentProject()
26 | var appState = appState
27 | appState.project = project
28 | self.appState = appState
29 | }
30 |
31 | func openProject(_ project: Project) throws {
32 | let project = try projectService.openProject(project)
33 | var appState = appState
34 | appState.project = project
35 | self.appState = appState
36 | }
37 |
38 | func closeProject() {
39 | guard let project = appState.project else {return}
40 | projectService.closeProject(project)
41 | var appState = appState
42 | appState.project = nil
43 | self.appState = appState
44 | }
45 |
46 | func refresh() {
47 | guard appState.project != nil else {
48 | return
49 | }
50 | projectViewModel?.refresh()
51 | }
52 | }
53 |
54 | extension MainViewModel: OpenProjectHandler {}
55 |
--------------------------------------------------------------------------------
/Apps/Sources/Extensions/XcodeProj+Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // XcodeProj+Extensions.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import Foundation
9 | import XcodeProj
10 | import PathKit
11 |
12 | extension PBXGroup {
13 | /// Returns group with the given name contained in the project.
14 | /// - Parameters:
15 | /// - name: group's name
16 | /// - recursively: should find recursively or not
17 | /// - Returns: group with the given name in the project
18 | func group(named name: String, recursively: Bool) -> PBXGroup? {
19 | // Non-recursively
20 | if !recursively {
21 | return group(named: name)
22 | }
23 |
24 | // If found
25 | if let group = group(named: name) {
26 | return group
27 | }
28 |
29 | // recursively find group
30 | for child in children where child is PBXGroup {
31 | if let group = (child as? PBXGroup)?.group(named: name, recursively: true) {
32 | return group
33 | }
34 | }
35 |
36 | return nil
37 | }
38 | }
39 |
40 | #if DEBUG
41 | extension XcodeProj {
42 | static var demoProject: (XcodeProj?, Path) {
43 | let repositoryLocalURL = "/Users/bigears/Documents/macos/XCodeLocalizationHelper"
44 | let homeUrl = Path(repositoryLocalURL + "/Apps/TestsProjects/")
45 | let test1 = homeUrl + "Test1" + "Test1.xcodeproj"
46 |
47 | return (try? XcodeProj(path: test1), test1)
48 | }
49 | }
50 | #endif
51 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test1/Test1UITests/Test1UITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test1UITests.swift
3 | // Test1UITests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 |
10 | class Test1UITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use recording to get started writing UI tests.
31 | // Use XCTAssert and related functions to verify your tests produce the correct results.
32 | }
33 |
34 | func testLaunchPerformance() throws {
35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
36 | // This measures how long it takes to launch your application.
37 | measure(metrics: [XCTApplicationLaunchMetric()]) {
38 | XCUIApplication().launch()
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test2/Test2UITests/Test2UITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test2UITests.swift
3 | // Test2UITests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 |
10 | class Test2UITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use recording to get started writing UI tests.
31 | // Use XCTAssert and related functions to verify your tests produce the correct results.
32 | }
33 |
34 | func testLaunchPerformance() throws {
35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
36 | // This measures how long it takes to launch your application.
37 | measure(metrics: [XCTApplicationLaunchMetric()]) {
38 | XCUIApplication().launch()
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test3/Test3UITests/Test3UITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test3UITests.swift
3 | // Test3UITests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 |
10 | class Test3UITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use recording to get started writing UI tests.
31 | // Use XCTAssert and related functions to verify your tests produce the correct results.
32 | }
33 |
34 | func testLaunchPerformance() throws {
35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
36 | // This measures how long it takes to launch your application.
37 | measure(metrics: [XCTApplicationLaunchMetric()]) {
38 | XCUIApplication().launch()
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Apps/TestsProjects/Test4/Test4UITests/Test4UITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Test4UITests.swift
3 | // Test4UITests
4 | //
5 | // Created by Chung Tran on 20/07/2021.
6 | //
7 |
8 | import XCTest
9 |
10 | class Test4UITests: XCTestCase {
11 |
12 | override func setUpWithError() throws {
13 | // Put setup code here. This method is called before the invocation of each test method in the class.
14 |
15 | // In UI tests it is usually best to stop immediately when a failure occurs.
16 | continueAfterFailure = false
17 |
18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
19 | }
20 |
21 | override func tearDownWithError() throws {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | func testExample() throws {
26 | // UI tests must launch the application that they test.
27 | let app = XCUIApplication()
28 | app.launch()
29 |
30 | // Use recording to get started writing UI tests.
31 | // Use XCTAssert and related functions to verify your tests produce the correct results.
32 | }
33 |
34 | func testLaunchPerformance() throws {
35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
36 | // This measures how long it takes to launch your application.
37 | measure(metrics: [XCTApplicationLaunchMetric()]) {
38 | XCUIApplication().launch()
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Apps/Sources/Services/XCodeProjectService.swift:
--------------------------------------------------------------------------------
1 | //
2 | // XCodeProjectService.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 25/07/2021.
6 | //
7 |
8 | import Foundation
9 |
10 | protocol XCodeProjectServiceType {
11 | func openCurrentProject() throws -> Project
12 | func openProject(_ project: Project) throws -> Project
13 | func localizeProject(_ project: Project, languageCode: String) throws
14 | func getLocalizableFiles(fromProject project: Project) throws -> [LocalizableFile]
15 | func closeProject(_ project: Project)
16 | }
17 |
18 | struct XCodeProjectService: XCodeProjectServiceType {
19 | // MARK: - Dependencies
20 | @Injected var stringsFileGenerator: FileGeneratorType
21 | @Injected var projectRepository: ProjectRepositoryType
22 |
23 | // MARK: - Methods
24 | func openCurrentProject() throws -> Project {
25 | guard let project = projectRepository.getCurrentProject()
26 | else {throw LocalizationHelperError.projectNotFound}
27 | return try openProject(project)
28 | }
29 |
30 | func openProject(_ project: Project) throws -> Project {
31 | projectRepository.setCurrentProject(project)
32 | return project
33 | }
34 |
35 | func localizeProject(_ project: Project, languageCode: String) throws {
36 | try project.localize(fileGenerator: stringsFileGenerator, languageCode: languageCode)
37 | }
38 |
39 | func getLocalizableFiles(fromProject project: Project) throws -> [LocalizableFile] {
40 | try project.getLocalizableFiles()
41 | }
42 |
43 | func closeProject(_ project: Project) {
44 | projectRepository.clearCurrentProject()
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/Apps/Sources/Utilities/Store.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Store.swift
3 | // LocalizationHelperKit
4 | //
5 | // Created by Chung Tran on 19/07/2021.
6 | //
7 |
8 | import SwiftUI
9 | import Combine
10 |
11 | typealias Store = CurrentValueSubject
12 |
13 | extension Store {
14 |
15 | subscript(keyPath: WritableKeyPath