Repository: samdmarshall/nslocalizer Branch: develop Commit: df086165d920 Files: 115 Total size: 242.3 KB Directory structure: gitextract_5412qdru/ ├── .codeclimate.yml ├── .github/ │ ├── ISSUE_TEMPLATE.md │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .gitmodules ├── Dangerfile ├── Gemfile ├── LICENSE ├── Makefile ├── circle.yml ├── contributing/ │ └── code-of-conduct.md ├── contributing.md ├── install_requirements.txt ├── nslocalizer/ │ ├── Executor/ │ │ ├── Executor.py │ │ └── __init__.py │ ├── Finder/ │ │ ├── CodeFinder.py │ │ ├── LanguageFinder.py │ │ ├── PathFinder.py │ │ └── __init__.py │ ├── Helpers/ │ │ ├── FileOperations.py │ │ ├── Logger.py │ │ ├── Switch.py │ │ ├── __init__.py │ │ └── xcrun.py │ ├── Language/ │ │ ├── Language.py │ │ ├── LanguageString.py │ │ └── __init__.py │ ├── Reporter/ │ │ ├── Reporter.py │ │ └── __init__.py │ ├── __init__.py │ ├── main.py │ ├── version.py │ ├── version_info.py │ └── xcodeproj/ │ ├── __init__.py │ ├── pbProj/ │ │ ├── PBXAggregateTarget.py │ │ ├── PBXAppleScriptBuildPhase.py │ │ ├── PBXApplicationReference.py │ │ ├── PBXApplicationTarget.py │ │ ├── PBXBuildFile.py │ │ ├── PBXBuildRule.py │ │ ├── PBXBundleReference.py │ │ ├── PBXBundleTarget.py │ │ ├── PBXContainerItemProxy.py │ │ ├── PBXCopyFilesBuildPhase.py │ │ ├── PBXExecutableFileReference.py │ │ ├── PBXFileReference.py │ │ ├── PBXFrameworkReference.py │ │ ├── PBXFrameworkTarget.py │ │ ├── PBXFrameworksBuildPhase.py │ │ ├── PBXGroup.py │ │ ├── PBXHeadersBuildPhase.py │ │ ├── PBXItem.py │ │ ├── PBXJavaArchiveBuildPhase.py │ │ ├── PBXLegacyTarget.py │ │ ├── PBXLibraryReference.py │ │ ├── PBXLibraryTarget.py │ │ ├── PBXNativeTarget.py │ │ ├── PBXProject.py │ │ ├── PBXReferenceProxy.py │ │ ├── PBXResourcesBuildPhase.py │ │ ├── PBXRezBuildPhase.py │ │ ├── PBXShellScriptBuildPhase.py │ │ ├── PBXSourcesBuildPhase.py │ │ ├── PBXStandAloneTarget.py │ │ ├── PBXTargetDependency.py │ │ ├── PBXToolTarget.py │ │ ├── PBXVariantGroup.py │ │ ├── PBXZipArchiveReference.py │ │ ├── PBX_Constants.py │ │ ├── PBX_Lookup.py │ │ ├── XCBuildConfiguration.py │ │ ├── XCConfigurationList.py │ │ ├── XCVersionGroup.py │ │ ├── __init__.py │ │ └── pbProj.py │ └── xcodeproj.py ├── nslocalizer.py ├── pylintrc ├── readme.md ├── requirements.txt ├── setup.py ├── tests/ │ ├── __init__.py │ ├── nslocalizer-example/ │ │ ├── Base.lproj/ │ │ │ └── Localizable.strings │ │ ├── de.lproj/ │ │ │ └── Localizable.strings │ │ ├── en.lproj/ │ │ │ └── Localizable.strings │ │ ├── es.lproj/ │ │ │ └── Localizable.strings │ │ ├── fr.lproj/ │ │ │ └── Localizable.strings │ │ ├── pylocalizer-example/ │ │ │ ├── AppDelegate.h │ │ │ ├── AppDelegate.m │ │ │ ├── Assets.xcassets/ │ │ │ │ └── AppIcon.appiconset/ │ │ │ │ └── Contents.json │ │ │ ├── Base.lproj/ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ ├── DetailViewController.h │ │ │ ├── DetailViewController.m │ │ │ ├── Info.plist │ │ │ ├── MasterViewController.h │ │ │ ├── MasterViewController.m │ │ │ ├── de.lproj/ │ │ │ │ ├── LaunchScreen.strings │ │ │ │ └── Main.strings │ │ │ ├── es.lproj/ │ │ │ │ ├── LaunchScreen.strings │ │ │ │ └── Main.strings │ │ │ ├── fr.lproj/ │ │ │ │ ├── LaunchScreen.strings │ │ │ │ └── Main.strings │ │ │ └── main.m │ │ └── pylocalizer-example.xcodeproj/ │ │ ├── project.pbxproj │ │ ├── project.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcuserdata/ │ │ │ └── Samantha.xcuserdatad/ │ │ │ └── UserInterfaceState.xcuserstate │ │ └── xcuserdata/ │ │ └── Samantha.xcuserdatad/ │ │ └── xcschemes/ │ │ ├── pylocalizer-example.xcscheme │ │ └── xcschememanagement.plist │ ├── nslocalizer_test.py │ └── test_runner.py ├── tools/ │ ├── checkout_by_version.sh │ ├── hooks/ │ │ └── pre-commit │ └── hooks-config.py └── tox.ini ================================================ FILE CONTENTS ================================================ ================================================ FILE: .codeclimate.yml ================================================ engines: radon: enabled: true duplication: enabled: true config: languages: - python exclude_fingerprints: FIXME: enabled: true ratings: paths: - nslocalizer/ exclude_paths: - examples/ - tests/ - tools/ - "*.md" - "*.yml" - "*.ini" - Makefile - Dangerfile - Gemfile - LICENSE - contributing/ - docs/ - setup.py - nslocalizer.py ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ **Type of issue**: [ Bug | Enhancement | Request ] --- **Related Files**: --- **Description**: --- **Crash Report**:
Summary Goes Here ``` ...crash report trace goes here... ```
--- **Sample File**:
`sample.pyconfig` ``` ...sample.pyconfig contents go here... ```
================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ **Title**: --- **Description**: ================================================ FILE: .gitignore ================================================ .DS_Store installed_files.txt build/ dist/ nslocalizer.egg-info/ .tox/ .coverage *.pyc __pycache__/ htmlcov/ .eggs/ lint_output.txt *_output.plist ================================================ FILE: .gitmodules ================================================ [submodule "docs"] path = docs url = https://samdmarshall@github.com/samdmarshall/pylocalizer.wiki.git ================================================ FILE: Dangerfile ================================================ # this dangerfile sets values that will be consumed by the global danger # file. The global dangerfile is run automatically after this repo-specific # file is run. The global dangerfile is located at: https://github.com/samdmarshall/danger # set the number of lines that must be changed before this classifies as a 'Big PR' @SDM_DANGER_BIG_PR_LINES = 75 # set the files to watch and warn about if there are changes made @SDM_DANGER_BUILD_FILES = ['Makefile', 'Gemfile', 'Dangerfile', 'circle.yml', '.codeclimate.yml', 'tox.ini', 'pylintrc'] # set the files to watch and warn about if there are @SDM_DANGER_INSTALL_REQUIREMENTS_FILES = ['requirements.txt', 'setup.py'] # set the files to watch and fail if there are changes @SDM_DANGER_IMMUTABLE_FILES = ['LICENSE', 'contributing.md', 'contributing/code-of-conduct.md'] # mark the paths that should be reported as part of the circle ci build artifacts @SDM_DANGER_REPORT_CIRCLE_CI_ARTIFACTS = Array[ { 'message'=> 'html coverage report', 'path'=> 'htmlcov/index.html' }, { 'message'=> 'linter report', 'path'=> 'lint_output.txt' } ] ================================================ FILE: Gemfile ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. source 'https://rubygems.org' gem 'danger' ================================================ FILE: LICENSE ================================================ Copyright (c) 2016, Samantha Marshall All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of Samantha Marshall nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: Makefile ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. # Variables # path to installation record that gets written when performing: # - make build2 # - make build3 INSTALLED_FILES_RECORD := ./installed_files.txt # names of the executables that are used as a part of this project PYTHON3_CMD := python3 TOX_CMD := tox COVERAGE_CMD := coverage DANGER_CMD := danger GEM_CMD := gem FIND_CMD := find RM_CMD := rm WHICH_CMD := which XARGS_CMD := xargs PRINTF_CMD := printf TOUCH_CMD := touch CP_CMD := cp CAT_CMD := cat PIP_CMD := pip PIP3_CMD := pip3 CCTREPORTER_CMD := codeclimate-test-reporter UNAME_CMD := uname EXIT_CMD := exit TPUT_CMD := tput TR_CMD := tr PYLINT_CMD := pylint BREW_CMD := brew PYENV_CMD := pyenv TOX_PYENV := tox-pyenv PYOBJC_CORE := pyobjc-core PYOBJC_COCOA := pyobjc-framework-Cocoa # invoke the specific executable command PYTHON3 = $(shell command -v $(PYTHON3_CMD) 2> /dev/null) TOX = $(shell command -v $(TOX_CMD) 2> /dev/null) COVERAGE = $(shell command -v $(COVERAGE_CMD) 2> /dev/null) DANGER = $(shell command -v $(DANGER_CMD) 2> /dev/null) GEM = $(shell command -v $(GEM_CMD) 2> /dev/null) FIND = $(shell command -v $(FIND_CMD) 2> /dev/null) RM = $(shell command -v $(RM_CMD) 2> /dev/null) WHICH = $(shell command -v $(WHICH_CMD) 2> /dev/null) XARGS = $(shell command -v $(XARGS_CMD) 2> /dev/null) PRINTF = $(shell command -v $(PRINTF_CMD) 2> /dev/null) TOUCH = $(shell command -v $(TOUCH_CMD) 2> /dev/null) CP = $(shell command -v $(CP_CMD) 2> /dev/null) CAT = $(shell command -v $(CAT_CMD) 2> /dev/null) PIP = $(shell command -v $(PIP_CMD) 2> /dev/null) PIP3 = $(shell command -v $(PIP3_CMD) 2> /dev/null) CCTREPORTER = $(shell command -v $(CCTREPORTER_CMD) 2> /dev/null) UNAME = $(shell command -v $(UNAME_CMD) 2> /dev/null) EXIT = $(shell command -v $(EXIT_CMD) 2> /dev/null) TPUT = $(shell command -v $(TPUT_CMD) 2> /dev/null) TR = $(shell command -v $(TR_CMD) 2> /dev/null) PYLINT = $(shell command -v $(PYLINT_CMD) 2> /dev/null) BREW = $(shell command -v $(BREW_CMD) 2> /dev/null) PYENV = $(shell command -v $(PYENV_CMD) 2> /dev/null) SYSTEM := $(shell $(UNAME) -s) ifeq ($(SYSTEM),Darwin) USER_FLAG := --user else USER_FLAG := endif TERM_COLUMNS := `$(TPUT) cols` DISPLAY_SEPARATOR := $(PRINTF) "%*.s\n" $(TERM_COLUMNS) " " | $(TR) ' ' '=' # Targets # --- checkfor = @$(PRINTF) "Checking for $1..."; \ if [ -z `$(WHICH) $1` ]; then \ $(PRINTF) " no\n"; \ $(EXIT) 1;\ else \ $(PRINTF) " yes\n"; \ fi check: $(call checkfor,$(WHICH_CMD)) $(call checkfor,$(CAT_CMD)) $(call checkfor,$(CP_CMD)) $(call checkfor,$(TPUT_CMD)) $(call checkfor,$(TR_CMD)) $(call checkfor,$(PRINTF_CMD)) $(call checkfor,$(TOUCH_CMD)) $(call checkfor,$(FIND_CMD)) $(call checkfor,$(XARGS_CMD)) $(call checkfor,$(RM_CMD)) $(call checkfor,$(BREW_CMD)) $(call checkfor,$(PYTHON3_CMD)) $(call checkfor,$(PIP3_CMD)) $(call checkfor,$(TOX_CMD)) $(call checkfor,$(COVERAGE_CMD)) $(call checkfor,$(PYLINT_CMD)) $(call checkfor,$(PYENV_CMD)) $(call checkfor,$(GEM_CMD)) $(call checkfor,$(DANGER_CMD)) @$(DISPLAY_SEPARATOR) # --- pipinstall = @$(PIP) install $1 $(USER_FLAG) pipthreeinstall = @$(PIP3_CMD) install $1 geminstall = @$(GEM) install $1 brewinstall = @$(BREW) install $1 pyenv_exec = @$(PYENV_CMD) $1 $2 install-deps: $(call brewinstall,$(PYENV_CMD)) $(call brewinstall,$(PYTHON3_CMD)) $(call checkfor,$(PIP3_CMD)) $(call pipthreeinstall,-r requirements.txt) @$(DISPLAY_SEPARATOR) $(call checkfor,$(GEM_CMD)) $(call geminstall,$(DANGER_CMD)) @$(DISPLAY_SEPARATOR) $(call pyenv_exec, install, 3.5.1) @$(DISPLAY_SEPARATOR) # --- # this is for installing any tools that we don't already have install-tools: check @$(PRINTF) "Installing git hooks..." @$(PYTHON2) ./tools/hooks-config.py @$(PRINTF) " done!\n" @$(DISPLAY_SEPARATOR) # --- removeall = $(RM) -rRf cleanlocation = @$(FIND) $1 $2 -print0 | $(XARGS) -0 $(removeall) clean: check @$(PRINTF) "Removing existing installation... " @$(TOUCH) $(INSTALLED_FILES_RECORD) @$(CAT) $(INSTALLED_FILES_RECORD) | $(XARGS) $(removeall) @$(removeall) ./nslocalizer.egg-info @$(removeall) ./build @$(removeall) ./dist @$(removeall) ./.tox @$(removeall) .coverage @$(removeall) ./htmlcov @$(removeall) ./.eggs $(call cleanlocation, ., -name ".DS_Store") $(call cleanlocation, ., -name "*.pyc") $(call cleanlocation, ., -name "__pycache__" -type d) $(call cleanlocation, ., -name "*_output.plist") @$(PRINTF) "done!\n" @$(DISPLAY_SEPARATOR) # --- build: clean $(PYTHON3) ./setup.py install --record $(INSTALLED_FILES_RECORD) @$(DISPLAY_SEPARATOR) # --- test: clean $(TOX) @$(DISPLAY_SEPARATOR) # --- upload_artifacts = @$(PRINTF) "Checking for path to upload artifacts..." ; \ if [ -d $1 ] ; then \ $(PRINTF) "uploading.\n" ; \ $(CP) -r ./htmlcov $1 ; \ $(CP) lint_output.txt $1 ; \ else \ $(PRINTF) "skipping.\n" ; \ fi run_cctreporter = @$(PRINTF) "Checking CI branch to upload coverage results... " ; \ if [ "$(CIRCLE_BRANCH)" = "develop" ]; then \ $(PRINTF) "OK.\n"; \ $(CCTREPORTER) --token $(value CIRCLECI_CODECLIMATE_TOKEN) ; \ else \ $(PRINTF) "skipping.\n"; \ fi checktest = @$(PRINTF) "Checking that coverage data exists... " ; \ if [ -e ./.coverage ] ; then \ $(PRINTF) "ok!\n" ; \ else \ $(PRINTF) "not found!\n" ; \ $(PRINTF) "Please run 'make test' before running 'make report'\n" ; \ exit 1 ; \ fi \ report: check @$(call checktest) $(COVERAGE) report @$(DISPLAY_SEPARATOR) @$(PRINTF) "Generating html report... " @$(COVERAGE) html @$(PRINTF) "done!\n" @$(PRINTF) "Generated html report is located at: ./htmlcov/index.html\n" ifdef CIRCLE_ARTIFACTS @$(DISPLAY_SEPARATOR) $(call upload_artifacts,$(CIRCLE_ARTIFACTS)) endif @$(DISPLAY_SEPARATOR) $(call run_cctreporter) @$(DISPLAY_SEPARATOR) # --- danger: check @$(PRINTF) "Running danger " ifdef CIRCLECI_DANGER_GITHUB_API_TOKEN @$(PRINTF) "(PR)... \n" @export DANGER_GITHUB_API_TOKEN=$(value CIRCLECI_DANGER_GITHUB_API_TOKEN) @$(DANGER) --verbose else @$(PRINTF) "(local)... \n" @$(DANGER) local --verbose endif @$(DISPLAY_SEPARATOR) # --- ci: test lint report danger # --- lint: check @$(TOUCH) lint_output.txt @$(PRINTF) "Running linter... " @$(PYLINT) --rcfile=pylintrc ./nslocalizer > lint_output.txt || : @$(PRINTF) " done!\n" @$(PRINTF) "Generated linter report: lint_output.txt\n" @$(DISPLAY_SEPARATOR) # --- .PHONY: danger lint ci report test build clean install-tools install-deps check ================================================ FILE: circle.yml ================================================ machine: environment: XCODE_SCHEME: CIRCLECI_IS_BROKEN XCODE_WORKSPACE: CIRCLECI_IS_BROKEN xcode: version: 7.3.1 pre: - export PATH=/usr/local/bin:$PATH:/Users/distiller/Library/Python/2.7/bin - pip install --user --ignore-installed --upgrade virtualenv - ln -s $HOME/Library/Python/2.7/bin/virtualenv /usr/local/bin/virtualenv - cd "$(brew --repository)" && git fetch && git reset --hard origin/master - brew update dependencies: override: - make install-deps - pyenv local 3.5.1 test: override: - make ci ================================================ FILE: contributing/code-of-conduct.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or electronic address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. ## Scope This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [INSERT EMAIL ADDRESS]. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] [homepage]: http://contributor-covenant.org [version]: http://contributor-covenant.org/version/1/4/ ================================================ FILE: contributing.md ================================================ # [Code of Conduct](./contributing/code-of-conduct.md) This project has and enforces a Code of Conduct. This must be adhered to at all times when engaging with maintainers not only on Github but also all other mediums (including social networks). The maintainers reserve the right to remove you from being able to contribute or comment on this project. --- # [Issues](../../wiki/github_issues) When a new issue is created it will use a template that will ask for all the relevant information. If there is something missing or confusing, please look at the contributing guidelines for Issues on the wiki. --- # [Pull Requests](../../wiki/github_prs) On each pull request, a new CI build will be dispatched. This will run the test suite and upload the results of the coverage report. This project uses a tool called Danger to analyze many aspects of a PR and report if anything about the PR breaks expectations that the repo has. If you are interested in what will be analyzed, then please look at the contributing guildelines for PRs on the wiki. --- You made it! If you have finished reading the contributing guide then you can put 🌈 in your issue or pull request to acknowledge that you have read this document and have done your best to adhere ================================================ FILE: install_requirements.txt ================================================ pyobjc-core >= 2.5.1 pyobjc-framework-Cocoa >= 2.5.1 pbPlist >= 1.0.4 langcodes >= 1.2.0 ================================================ FILE: nslocalizer/Executor/Executor.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os import re import sys from ..Helpers.Logger import Logger from ..Helpers.FileOperations import FileOperations from ..Language import Language from ..Reporter import Reporter from ..xcodeproj.xcodeproj import xcodeproj from ..Finder.LanguageFinder import LanguageFinder from ..Finder import CodeFinder class Executor(object): base_language = None additional_languages = None @classmethod def run(cls, arguments) -> None: has_set_flag = arguments.find_missing or arguments.find_unused can_run = arguments.project and len(arguments.target) > 0 and has_set_flag xcodeproj_file = None desired_targets = list() if can_run: Logger.write().info('Loading project file...') # parse project file project_file_path = os.path.normpath(arguments.project) xcodeproj_file = xcodeproj(project_file_path) Logger.write().info('Search for target "%s" in project "%s"' % (arguments.target, os.path.basename(project_file_path))) # find target desired_targets = [target for target in xcodeproj_file.project_file.targets() if target['name'] in arguments.target] else: Logger.write().error('Please specify a project (--project) with a valid target (--target), and at least one search flag (--find-unused, --find-missing).') # pragma: no cover if xcodeproj is not None and len(desired_targets) == len(arguments.target): missing_strings = dict() unused_strings = dict() if arguments.find_missing: missing_strings = cls.findMissingStrings(xcodeproj_file, desired_targets) # log data to xcode console Reporter.logMissingStrings(missing_strings, arguments.ignore, arguments.error) if arguments.find_unused: unused_strings = cls.findUnusedStrings(xcodeproj_file, desired_targets) # log data to xcode console Reporter.logUnusedStrings(unused_strings, arguments.error) else: # pragma: no cover missing_targets = [target for target in arguments.target if target not in desired_targets] Logger.write().info('Could not find target "%s" in the specified project file.' % '", "'.join(missing_targets)) @classmethod def findMissingStrings(cls, project, targets) -> dict: Logger.write().info('Finding strings that are missing from language files...') _ = targets base_language, additional_languages = cls.generateLanguages(project) missing_results = [string.processMapping(base_language, additional_languages) for string in base_language.strings] return dict(missing_results) @classmethod def findUnusedStrings(cls, project, targets) -> list: Logger.write().info('Finding strings that are unused but are in language files...') code_files = list() for target in targets: code_files.extend(CodeFinder.getCodeFileList(project.project_file, target)) base_language, _ = cls.generateLanguages(project) known_strings = set() for source_code_file in code_files: data = FileOperations.getData(source_code_file) if data is None: continue matches = re.findall(r'NSLocalizedString\(@?\"(.*?)\",', data) Logger.write().debug('%s: %i results' % (os.path.basename(source_code_file), len(matches))) known_strings.update(matches) unused_strings = [lstring for lstring in base_language.strings if lstring.string not in known_strings] for unused_string in unused_strings: unused_string.registerBase(base_language) return unused_strings @classmethod def generateLanguages(cls, project) -> (Language, {Language}): strings_files, stringsdict_files = LanguageFinder.getLocalizationFiles(project.project_file) languages = set([Language.Language(path) for path in strings_files]) for language in languages: language.loadStringsDictFile(stringsdict_files) if cls.base_language is None and cls.additional_languages is None: cls.additional_languages = set([language for language in languages if language.code != 'Base']) if len(cls.additional_languages) == len(languages): Logger.write().info('Could not find a "Base" language, assuming "English"...') cls.additional_languages = set([language for language in languages if language.code != 'en']) if len(cls.additional_languages) == len(languages): Logger.write().error('Unable to locate the "Base" language, please assign one in the project file!') sys.exit(1) other_languages = languages.difference(cls.additional_languages) cls.base_language = other_languages.pop() cls.base_language.findStrings() return (cls.base_language, cls.additional_languages) ================================================ FILE: nslocalizer/Executor/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: nslocalizer/Finder/CodeFinder.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from ..Helpers.Logger import Logger from ..xcodeproj.pbProj import pbProj from ..xcodeproj.pbProj.PBXSourcesBuildPhase import PBXSourcesBuildPhase from . import PathFinder def getCodeFileList(project, target) -> list: Logger.write().info('Finding Code files for target "%s"...' % target[pbProj.PBX_Constants.kPBX_TARGET_name]) build_phases = target.store[pbProj.PBX_Constants.kPBX_TARGET_buildPhases] source_phases = [build_phase for build_phase in build_phases if isinstance(build_phase, PBXSourcesBuildPhase)] all_build_files = list() for phase in source_phases: all_build_files.extend(phase.store[pbProj.PBX_Constants.kPBX_PHASE_files]) all_file_refs = [PathFinder.resolveFilePathForReference(project, build_file.store[pbProj.PBX_Constants.kPBX_BUILDFILE_fileRef]) for build_file in all_build_files] return all_file_refs ================================================ FILE: nslocalizer/Finder/LanguageFinder.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from ..Helpers.Logger import Logger from ..xcodeproj.pbProj import pbProj from ..xcodeproj.pbProj.PBXVariantGroup import PBXVariantGroup from . import PathFinder def FilterByName(items, name) -> PBXVariantGroup: matched_items = [item for item in items if item.store[pbProj.PBX_Constants.kPBX_REFERENCE_name] == name] if len(matched_items): matched_items = matched_items[0] else: matched_items = None return matched_items class LanguageFinder(object): localizable_strings = None localizable_stringsdict = None strings_file_refs = list() stringsdict_file_refs = list() @classmethod def getLocalizationFiles(cls, project) -> (dict, dict): if cls.localizable_strings is None or cls.localizable_stringsdict is None: variant_groups = [pbx_object for pbx_object in project.pbx_objects if isinstance(pbx_object, PBXVariantGroup)] # localizable.strings if cls.localizable_strings is None: Logger.write().info('Filtering for Localizable.strings files...') cls.localizable_strings = FilterByName(variant_groups, 'Localizable.strings') # localizable.stringsdict if cls.localizable_stringsdict is None: Logger.write().info('Filtering for Localizable.stringsdict files...') cls.localizable_stringsdict = FilterByName(variant_groups, 'Localizable.stringsdict') if len(cls.strings_file_refs) == 0 or len(cls.stringsdict_file_refs) == 0: Logger.write().info('Resolving language-specific file paths...') if len(cls.strings_file_refs) == 0 and cls.localizable_strings is not None: languages = cls.localizable_strings.store[pbProj.PBX_Constants.kPBX_REFERENCE_children] cls.strings_file_refs = [PathFinder.resolveFilePathForReference(project, language_file) for language_file in languages] else: Logger.write().info('Could not find any Localizable.strings files, continuing...') if len(cls.stringsdict_file_refs) == 0 and cls.localizable_stringsdict is not None: language_dicts = cls.localizable_stringsdict.store[pbProj.PBX_Constants.kPBX_REFERENCE_children] cls.stringsdict_file_refs = [PathFinder.resolveFilePathForReference(project, language_file_dict) for language_file_dict in language_dicts] else: Logger.write().info('Could not find any Localizable.stringsdict files, continuing...') return (cls.strings_file_refs, cls.stringsdict_file_refs) ================================================ FILE: nslocalizer/Finder/PathFinder.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os def resolveFilePathForReference(project, reference) -> str: file_path = reference.resolvePath(project) project_dir = os.path.dirname(os.path.dirname(project.pbx_file_path)) file_path = os.path.join(project_dir, file_path) norm_file_path = os.path.normpath(file_path) return norm_file_path ================================================ FILE: nslocalizer/Finder/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: nslocalizer/Helpers/FileOperations.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys from pbPlist import pbParser class FileOperations(object): @classmethod def getData(cls, file_path) -> object: data = None if os.path.isfile(file_path) is True: try: encoding = pbParser.GetFileEncoding(file_path) file_descriptor = pbParser.OpenFileWithEncoding(file_path, encoding) data = file_descriptor.read() file_descriptor.close() except IOError as exception: # pragma: no cover print('I/O error({0}): {1}'.format(exception.errno, exception.strerror)) except: # pragma: no cover print('Unexpected error:'+str(sys.exc_info()[0])) raise return data ================================================ FILE: nslocalizer/Helpers/Logger.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import logging class Singleton(type): _instances = {} def __call__(cls, *args, **kwargs): # pragma: no cover if cls not in cls._instances.keys(): cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) return cls._instances[cls] #These are the sequences need to get colored ouput RESET_SEQ = '\033[0m' BOLD_SEQ = '\033[1m' COLORS = { 'BLACK': '\033[1;30m', 'RED': '\033[1;31m', 'GREEN': '\033[1;32m', 'YELLOW': '\033[1;33m', 'BLUE': '\033[1;34m', 'MAGENTA': '\033[1;35m', 'CYAN': '\033[1;36m', 'WHITE': '\033[1;37m' } LEVELS = { 'WARNING': COLORS['YELLOW'], 'INFO': COLORS['BLACK'], 'DEBUG': COLORS['MAGENTA'], 'CRITICAL': COLORS['BLUE'], 'ERROR': COLORS['RED'] } class ColoredFormatter(logging.Formatter): def __init__(self, msg, use_color=True): logging.Formatter.__init__(self, msg) self.use_color = use_color def format(self, record): # pragma: no cover levelname = record.levelname if self.use_color and levelname in LEVELS: levelname_color = LEVELS[levelname] + levelname + RESET_SEQ record.levelname = levelname_color return logging.Formatter.format(self, record) class Logger(object): __metaclass__ = Singleton _internal_logger = None _debug_logging = False _use_ansi_codes = False def __init__(self, *args, **kwargs): # pragma: no cover pass @staticmethod def enableDebugLogger(is_debug_logger=False): Logger._debug_logging = is_debug_logger @staticmethod def disableANSI(disable_ansi=False): Logger._use_ansi_codes = not disable_ansi @staticmethod def setupLogger(): Logger._internal_logger = logging.getLogger('com.pewpewthespells.py.logging_helper') level = logging.DEBUG if Logger._debug_logging else logging.INFO Logger._internal_logger.setLevel(level) handler = logging.StreamHandler() handler.setLevel(level) # create formatter formatter = None if Logger._debug_logging is True: # pragma: no cover formatter = ColoredFormatter('[%(levelname)s][%(filename)s:%(lineno)s]: %(message)s', Logger._use_ansi_codes) else: formatter = ColoredFormatter('[%(levelname)s]: %(message)s', Logger._use_ansi_codes) # add formatter to ch handler.setFormatter(formatter) # add ch to logger Logger._internal_logger.addHandler(handler) @staticmethod def isVerbose(verbose_logging=False): if Logger._internal_logger is None: # pragma: no cover Logger.setupLogger() if not verbose_logging: Logger._internal_logger.setLevel(logging.WARNING) @staticmethod def isSilent(should_quiet=False): if Logger._internal_logger is None: # pragma: no cover Logger.setupLogger() if should_quiet: logging_filter = logging.Filter(name='com.pewpewthespells.py.logging_helper.shut_up') Logger._internal_logger.addFilter(logging_filter) @staticmethod def write(): if Logger._internal_logger is None: # pragma: no cover Logger.setupLogger() return Logger._internal_logger ================================================ FILE: nslocalizer/Helpers/Switch.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. # Original code taken from http://code.activestate.com/recipes/410692/ class Switch(object): def __init__(self, value): self.value = value self.fall = False def __iter__(self): """Return the match method once, then stop""" yield self.match raise StopIteration # pragma: no cover def match(self, *args): """Indicate whether or not to enter a case suite""" result = False if self.fall or not args: result = True elif self.value in args: # changed for v1.5, see below self.fall = True result = True return result ================================================ FILE: nslocalizer/Helpers/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: nslocalizer/Helpers/xcrun.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/pylocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os import sys import struct import hashlib import subprocess import CoreFoundation from .Logger import Logger from .Switch import Switch def hashStringForPath(path) -> str: """ Returns the hash for a project's DerivedData location. path is the filesystem path to the .xcodeproj file. """ hash_context = hashlib.md5() hash_context.update(path) md5_digest_hex = hash_context.digest() hash_path = [None] * 28 first_value = struct.unpack('>Q', md5_digest_hex[:8])[0] counter = 13 while counter >= 0: hash_path[counter] = chr((first_value % 26) + ord('a')) first_value = first_value / 26 counter -= 1 second_value = struct.unpack('>Q', md5_digest_hex[8:])[0] counter = 27 while counter > 13: hash_path[counter] = chr((second_value % 26) + ord('a')) second_value = second_value / 26 counter -= 1 hash_path_string = ''.join(hash_path) return hash_path_string def ResolveDerivedDataPath(project) -> str: default_dd_path = os.path.expanduser("~/Library/Developer/Xcode/DerivedData/") derived_data = CoreFoundation.CFPreferencesCopyAppValue('IDECustomDerivedDataLocation', 'com.apple.dt.Xcode') # pylint: disable=no-member if derived_data is None: derived_data = default_dd_path else: if derived_data[0] != '/': derived_data = os.path.join(project.path, derived_data) return derived_data def ResolveBuildLocation(project, sym_root) -> str: build_dir_path = '' derived_data = ResolveDerivedDataPath(project) location_style = CoreFoundation.CFPreferencesCopyAppValue('IDEBuildLocationStyle', 'com.apple.dt.Xcode') # pylint: disable=no-member for case in Switch(location_style): if case('Unique'): xcodeproj_path = os.path.join(project.projectRoot.obj_path, project.name) unique_path = hashStringForPath(xcodeproj_path) # this is missing the configuration path. project_dir_name = os.path.splitext(project.name)[0]+'-'+unique_path+'/Build/Products/' build_dir_path = os.path.join(derived_data, project_dir_name) break if case('Shared'): shared_path = CoreFoundation.CFPreferencesCopyAppValue('IDESharedBuildFolderName', 'com.apple.dt.Xcode') # pylint: disable=no-member build_dir_path = os.path.join(derived_data, shared_path) break if case('Custom'): location_type = CoreFoundation.CFPreferencesCopyAppValue('IDECustomBuildLocationType', 'com.apple.dt.Xcode') # pylint: disable=no-member custom_path = CoreFoundation.CFPreferencesCopyAppValue('IDECustomBuildProductsPath', 'com.apple.dt.Xcode') # pylint: disable=no-member for case in Switch(location_type): if case('RelativeToDerivedData'): build_dir_path = os.path.join(derived_data, custom_path) break if case('RelativeToWorkspace'): build_dir_path = os.path.join(project.path.base_path, custom_path) break if case('Absolute'): build_dir_path = custom_path break if case(): break if case('DeterminedByTargets'): # this is missing the configuration path build_dir_path = os.path.join(project.projectRoot.obj_path, sym_root) break if case(): # pragma: no cover break return build_dir_path def IntermediatesBuildLocation(project, target_name, config_name, sym_root) -> str: build_dir_path = ResolveBuildLocation(project, sym_root) project_name = project.name.split('.')[0] project_dir_path = os.path.join(build_dir_path, project_name+'.build') config_dir_path = os.path.join(project_dir_path, config_name) target_dir_path = os.path.join(config_dir_path, target_name+'.build') return target_dir_path def ProductsBuildLocation(project, sym_root) -> str: """ Returns the full path to the location of the build products. project is the project that the build product is in. sym_root is the value of $(SYMROOT) for the current configuration """ # this needs to also take CONFIGURATION_DIR build_dir_path = ResolveBuildLocation(project, sym_root) return build_dir_path def resolvePathFromLocation(location_string, path, base_path) -> str: path_string = '' path_type, item_path = location_string.split(':') for case in Switch(path_type): if case('group'): path = os.path.join(base_path, path) path_string = os.path.join(path, item_path) break if case('absolute'): path_string = item_path break if case('developer'): path_string = os.path.join(resolve_developer_path(), item_path) break if case('container'): path_string = os.path.join(base_path, item_path) break if case(): # pragma: no cover Logger.write().error('Invalid item path name!') path_string = item_path break return path_string def make_subprocess_call(call_args, shell_state=False) -> (str, int): error = 0 output = '' try: output = subprocess.check_output(call_args, shell=shell_state) error = 0 except subprocess.CalledProcessError as exception: # pragma: no cover output = str(exception.output) error = exception.returncode return (output, error) def make_xcrun_with_args(args_tuple) -> str: xcrun_result = make_subprocess_call((('xcrun',) + args_tuple)) if xcrun_result[1] != 0: # pragma: no cover Logger.write().error('[xcrun]: Error in exec!') sys.exit() xcrun_output = str(xcrun_result[0]).rstrip('\n') return xcrun_output def resolve_sdk_path(sdk_name) -> str: return make_xcrun_with_args(('--show-sdk-path', '--sdk', sdk_name)) def resolve_developer_path() -> str: xcrun_result = make_subprocess_call(('xcode-select', '-p')) if xcrun_result[1] != 0: # pragma: no cover Logger.write().error('[xcrun]: Please run Xcode first!') sys.exit() developer_path = str(xcrun_result[0]).rstrip('\n') return developer_path DEVELOPER_DIR = os.environ.get('DEVELOPER_DIR') if DEVELOPER_DIR: Logger.write().info('DEVELOPER_DIR environment variable is already set, existing value "%s" will be used.' % (DEVELOPER_DIR)) else: os.environ['DEVELOPER_DIR'] = resolve_developer_path() ================================================ FILE: nslocalizer/Language/Language.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os import langcodes from pbPlist import pbPlist from .LanguageString import LanguageString from ..Helpers.Logger import Logger from ..Helpers.FileOperations import FileOperations def GetLanguageCodeFromPath(path) -> str: dirname = os.path.dirname(path) basename = os.path.basename(dirname) locale, _ = os.path.splitext(basename) return locale def FindLineIndex(data, string) -> int: line_index = 0 localized_string_entry = '"'+str(string)+'"' if data is not None: position = data.find(localized_string_entry) line_index = data[:position].count('\n') + 1 return line_index def LoadStrings(file_path) -> list: strings_file_contents = pbPlist.PBPlist(file_path) results = [LanguageString(localized_string_key, strings_file_contents.root[localized_string_key]) for localized_string_key in list(strings_file_contents.root.keys())] return results class Language(object): def __init__(self, strings_file_path): self.code = GetLanguageCodeFromPath(strings_file_path) self.name = langcodes.LanguageData(language=self.code).language_name() self.strings_file = strings_file_path self.stringsdict_file = None self.stringsdict = None self.strings = LoadStrings(self.strings_file) def findStrings(self) -> None: strings_missing_line_numbers = [lstring for lstring in self.strings if lstring.line_number == 0] if len(strings_missing_line_numbers): Logger.write().info('Resolving line numbers...') data = FileOperations.getData(self.strings_file) for lstring in strings_missing_line_numbers: lstring.line_number = FindLineIndex(data, lstring.string) def loadStringsDictFile(self, stringsdict_file_array) -> None: for stringsdict_file in stringsdict_file_array: dict_locale = GetLanguageCodeFromPath(stringsdict_file) if self.code == dict_locale: self.stringsdict_file = stringsdict_file break if self.stringsdict_file is not None: self.stringsdict = LoadStrings(self.stringsdict_file) def __repr__(self) -> str: # pragma: no cover return '<%s : %s>' % (type(self).__name__, self.name) ================================================ FILE: nslocalizer/Language/LanguageString.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. def HasStringForLanguage(string, language) -> bool: result = False for lang_string in language.strings: result = (string == lang_string.string) if result is True: break return result class LanguageString(object): def __init__(self, string_key, string_value): self.line_number = 0 self.string = string_key self.value = string_value self.base = None self.mapping = dict() def __repr__(self) -> str: # pragma: no cover return str(self.string) def registerBase(self, base_language): self.base = base_language def processMapping(self, base_language, additional_languages) -> (object, list): self.registerBase(base_language) results = [(language, HasStringForLanguage(self.string, language)) for language in additional_languages] self.mapping = dict(results) missing_keys = [key for key in self.mapping if self.mapping[key] is False] return (self, missing_keys) ================================================ FILE: nslocalizer/Language/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: nslocalizer/Reporter/Reporter.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. def log(file_name, line_number, type_string, message_string) -> None: message = '%s:%s: %s: %s' % (file_name, line_number, type_string, message_string) ascii_message = message.encode('ascii', 'replace') display_message = ascii_message.decode('ascii', 'ignore') print(display_message) def logError(file_name, line_number, message_string) -> None: log(file_name, line_number, 'error', message_string) def logWarning(file_name, line_number, message_string) -> None: log(file_name, line_number, 'warning', message_string) def logMissingStrings(warnings_dictionary, ignore_languages, is_error=False) -> None: keys = list(warnings_dictionary.keys()) keys.sort(key=lambda string: string.line_number) for key in keys: locale_names = [language.name for language in warnings_dictionary.get(key) if language.code not in ignore_languages] if len(locale_names): message = ', '.join(locale_names) message_string = 'String "%s" missing for: %s' % (key.string, message) if is_error is False: logWarning(key.base.strings_file, key.line_number, message_string) else: logError(key.base.strings_file, key.line_number, message_string) def logUnusedStrings(unused_strings_list, is_error=False) -> None: unused_strings_list.sort(key=lambda string: string.line_number) for unused_string in unused_strings_list: message = 'String "%s" is not used' % unused_string.string if is_error is False: logWarning(unused_string.base.strings_file, unused_string.line_number, message) else: logError(unused_string.base.strings_file, unused_string.line_number, message) ================================================ FILE: nslocalizer/Reporter/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. ================================================ FILE: nslocalizer/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .main import main from .version import __version__ as PYLOCALIZER_VERSION __version__ = PYLOCALIZER_VERSION ================================================ FILE: nslocalizer/main.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import sys import argparse from .version import __version__ as PYLOCALIZER_VERSION from .Helpers.Logger import Logger from .Executor.Executor import Executor # Main def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser(description='nslocalizer is a tool for identifying unused or missing localization string usage in Xcode projects') parser.add_argument( '--version', help='Displays the version information', action='version', version=PYLOCALIZER_VERSION ) parser.add_argument( '--project', metavar='', help='specify the path to the .xcodeproj file', required=True, action='store' ) parser.add_argument( '--target', metavar='', help='specify the name of targets to analyze, this accepts multiple target names', type=str, default=list(), required=True, action='store', nargs='*' ) parser.add_argument( '--find-missing', help='look for localized strings that are missing from any of the .strings files', default=False, action='store_true' ) parser.add_argument( '--find-unused', help='look for localized strings that are not used in the code', default=False, action='store_true' ) parser.add_argument( '--quiet', help='Silences all logging output', default=False, action='store_true' ) parser.add_argument( '--verbose', help='Adds verbosity to logging output', default=False, action='store_true' ) parser.add_argument( '--ignore', help='Specify languages to ignore (by code; eg: German = de).', type=str, default=list(), nargs='*' ) parser.add_argument( '--no-ansi', help='Disables the ANSI color codes as part of the logger', default=False, action='store_true' ) parser.add_argument( '--error', help='Changes warnings to errors', default=False, action='store_true' ) parser.add_argument( '--debug', help=argparse.SUPPRESS, default=False, action='store_true' ) args = parser.parse_args(argv) # perform the logging modifications before we do any other operations Logger.disableANSI(args.no_ansi) Logger.enableDebugLogger(args.debug) Logger.isVerbose(args.verbose) Logger.isSilent(args.quiet) ignored_locales = ', '.join(args.ignore) Logger.write().info('Ignoring languages: %s' % ignored_locales) Executor.run(args) if __name__ == "__main__": # pragma: no cover main() ================================================ FILE: nslocalizer/version.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import version_info __version__ = '1.0.2 ('+version_info.remote_origin+' @ '+version_info.commit_hash+')' ================================================ FILE: nslocalizer/version_info.py ================================================ remote_origin = 'ssh://github.com/samdmarshall/nslocalizer' commit_hash = '14d376e' ================================================ FILE: nslocalizer/xcodeproj/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from ..Helpers import Logger from ..Helpers import xcrun ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXAggregateTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Target class PBXAggregateTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXAppleScriptBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXAppleScriptBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXApplicationReference.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Reference class PBXApplicationReference(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXApplicationTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Target class PBXApplicationTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXBuildFile.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBXItem class PBXBuildFile(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_BUILDFILE_fileRef, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXBuildRule.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBXItem class PBXBuildRule(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXBundleReference.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Reference class PBXBundleReference(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXBundleTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Target class PBXBundleTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXContainerItemProxy.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBXItem class PBXContainerItemProxy(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_CONTAINERITEMPROXY_containerPortal, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXCopyFilesBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXCopyFilesBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXExecutableFileReference.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Reference class PBXExecutableFileReference(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXFileReference.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Reference class PBXFileReference(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXFrameworkReference.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Reference class PBXFrameworkReference(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXFrameworkTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Target class PBXFrameworkTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXFrameworksBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXFrameworksBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXGroup.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBX_Base_Reference class PBXGroup(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_REFERENCE_children, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXHeadersBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXHeadersBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXItem.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/pylocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os import collections from . import PBX_Constants from ...Helpers import xcrun def getGraphNodeWithIdentifier(identifier, project): found_object = project.objectForIdentifier(identifier) if found_object and not found_object.resolved: found_object.resolveGraph(project) return found_object class PBXItem(collections.MutableMapping): def __init__(self, identifier, dictionary): self.isa = dictionary.get(PBX_Constants.kPBX_isa, None) self.identifier = identifier self.store = dict() self.key_storage = set() self.update(dictionary) # use the free update to set keys self.resolved = False def __getitem__(self, key): return self.store[key] def __setitem__(self, key, value): if key not in self.key_storage: self.key_storage.add(key) self.store[key] = value def __delitem__(self, key): if key in self.key_storage: self.key_storage.remove(key) del self.store[key] def __iter__(self): return self.key_storage.__iter__() def __len__(self): return self.key_storage.__len__() def __str__(self): return self.__repr__()+'\n'+self.store.__str__()+'\n' def __contains__(self, item): return item in self.key_storage def __getattr__(self, attrib): return getattr(self.store, attrib) def __hash__(self): return hash(self.identifier) def __repr__(self): return '<%s : %s>' % (self.isa, self.identifier) def resolveGraphNodeForKey(self, key, project): identifier = self.get(key, None) if not isinstance(identifier, PBXItem): found_object = getGraphNodeWithIdentifier(identifier, project) if found_object: self[key] = found_object def resolveGraphNodesForArray(self, key, project): identifier_array = self.get(key, None) resolved_array = list() for identifier in identifier_array: resolved_item = getGraphNodeWithIdentifier(identifier, project) if resolved_item: resolved_array.append(resolved_item) else: resolved_array.append(identifier) self[key] = resolved_array def resolveGraph(self, project): self.resolved = True _ = project class PBX_Base_Target(PBXItem): def __init__(self, identifier, dictionary): super(PBX_Base_Target, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(PBX_Base_Target, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_TARGET_buildConfigurationList, project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_TARGET_buildPhases, project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_TARGET_dependencies, project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_TARGET_productReference, project) class PBX_Base_Phase(PBXItem): def __init__(self, identifier, dictionary): super(PBX_Base_Phase, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(PBX_Base_Phase, self).resolveGraph(project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_PHASE_files, project) def resolvePathTypeFromSource(source): result = None lookup = { '': 'resolveAbsolutePath', '': 'resolveGroupPath', 'SOURCE_ROOT': 'resolveSourceRootPath', 'DEVELOPER_DIR': 'resolveDeveloperDirPath', 'BUILT_PRODUCTS_DIR': 'resolveBuildProductsPath', 'SDKROOT': 'resolveSDKPath', } if source in list(lookup.keys()): result = lookup[source] return result class PBX_Base_Reference(PBXItem): def __init__(self, identifier, dictionary): super(PBX_Base_Reference, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(PBX_Base_Reference, self).resolveGraph(project) def findParent(self, project): parent = None results = [pbx_object for pbx_object in project.pbx_objects if isinstance(pbx_object, PBX_Base_Reference) and PBX_Constants.kPBX_REFERENCE_children in list(pbx_object.keys())] for item in results: child_results = [ref for ref in item[PBX_Constants.kPBX_REFERENCE_children] if self.identifier == ref.identifier] if len(child_results) > 0: parent = item break return parent def resolveAbsolutePath(self, project): # pylint: disable=no-self-use,unused-argument return '' def resolveGroupPath(self, project): file_path = '' parent = self.findParent(project) if parent is not None: grandparent_path = parent.resolvePath(project) file_path = os.path.join(grandparent_path, '') return file_path def resolveSourceRootPath(self, project): # pylint: disable=no-self-use project_dir = os.path.dirname(os.path.dirname(project.pbx_file_path)) return project_dir def resolveDeveloperDirPath(self, project): # pylint: disable=no-self-use _ = project return xcrun.resolve_developer_path() def resolveSDKPath(self, project): # pylint: disable=no-self-use _ = project sdk_name = os.environ.get('SDKROOT') if sdk_name == '': raise ValueError('Unable to get a value for SDKROOT, please make sure to run this inside of Xcode!') return xcrun.resolve_sdk_path(sdk_name) def resolvePath(self, project): source = self.store[PBX_Constants.kPBX_REFERENCE_sourceTree] source_func = resolvePathTypeFromSource(source) parent_path = getattr(self, source_func)(project) current_path = '' if PBX_Constants.kPBX_REFERENCE_path in list(self.store.keys()): current_path = self.store[PBX_Constants.kPBX_REFERENCE_path] file_path = os.path.join(parent_path, current_path) return file_path ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXJavaArchiveBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXJavaArchiveBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXLegacyTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Target class PBXLegacyTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXLibraryReference.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Reference class PBXLibraryReference(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXLibraryTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Target class PBXLibraryTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXNativeTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBX_Base_Target class PBXNativeTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_TARGET_buildRules, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXProject.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBXItem class PBXProject_ProjectReference(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def __repr__(self): return self.store.__repr__() def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_PROJECTREF_ProjectRef, project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_PROJECTREF_ProductGroup, project) class PBXProject(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_TARGET_buildConfigurationList, project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_PROJECT_mainGroup, project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_PROJECT_productRefGroup, project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_PROJECT_targets, project) project_references = self.get(PBX_Constants.kPBX_PROJECT_projectReferences, None) if project_references: resolved_references = list() for reference in project_references: project_reference = PBXProject_ProjectReference(None, reference) project_reference.resolveGraph(project) resolved_references.append(project_reference) self[PBX_Constants.kPBX_PROJECT_projectReferences] = resolved_references ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXReferenceProxy.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBXItem class PBXReferenceProxy(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_PROXY_remoteRef, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXResourcesBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXResourcesBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXRezBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXRezBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXShellScriptBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXShellScriptBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXSourcesBuildPhase.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Phase class PBXSourcesBuildPhase(PBX_Base_Phase): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXStandAloneTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBX_Base_Target class PBXStandAloneTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_TARGET_buildRules, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXTargetDependency.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBXItem class PBXTargetDependency(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_TARGETDEP_target, project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_TARGETDEP_targetProxy, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXToolTarget.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Target class PBXToolTarget(PBX_Base_Target): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXVariantGroup.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBX_Base_Reference class PBXVariantGroup(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_REFERENCE_children, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBXZipArchiveReference.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from .PBXItem import PBX_Base_Reference class PBXZipArchiveReference(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBX_Constants.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. kPBX_rootObject = 'rootObject' kPBX_objects = 'objects' kPBX_archiveVersion = 'archiveVersion' kPBX_objectVersion = 'objectVersion' kPBX_classes = 'classes' kPBX_ProjectRef = 'ProjectRef' kPBX_isa = 'isa' kPBX_TARGET_name = 'name' kPBX_TARGET_productName = 'productName' kPBX_TARGET_buildConfigurationList = 'buildConfigurationList' kPBX_TARGET_buildPhases = 'buildPhases' kPBX_TARGET_dependencies = 'dependencies' kPBX_TARGET_productReference = 'productReference' kPBX_TARGET_buildSettings = 'buildSettings' kPBX_TARGET_productInstallPath = 'productInstallPath' kPBX_TARGET_productSettingsXML = 'productSettingsXML' kPBX_TARGET_shouldUseHeadermap = 'shouldUseHeadermap' kPBX_TARGET_buildRules = 'buildRules' kPBX_TARGET_passBuildSettingsInEnvironment = 'passBuildSettingsInEnvironment' kPBX_TARGET_buildArgumentsString = 'buildArgumentsString' kPBX_TARGET_buildToolPath = 'buildToolPath' kPBX_TARGET_buildWorkingDirectory = 'buildWorkingDirectory' kPBX_TARGET_settingsToExpand = 'settingsToExpand' kPBX_TARGET_settingsToPassInEnvironment = 'settingsToPassInEnvironment' kPBX_TARGET_settingsToPassOnCommandLine = 'settingsToPassOnCommandLine' kPBX_TARGET_productType = 'productType' kPBX_TARGET_buildProperties = 'buildProperties' kPBX_PHASE_buildActionMask = 'buildActionMask' kPBX_PHASE_files = 'files' kPBX_PHASE_runOnlyForDeploymentPostprocessing = 'runOnlyForDeploymentPostprocessing' kPBX_PHASE_contextName = 'contextName' kPBX_PHASE_isSharedContext = 'isSharedContext' kPBX_PHASE_dstPath = 'dstPath' kPBX_PHASE_dstSubfolderSpec = 'dstSubfolderSpec' kPBX_PHASE_shellScript = 'shellScript' kPBX_PHASE_shellPath = 'shellPath' kPBX_PHASE_inputPaths = 'inputPaths' kPBX_PHASE_outputPaths = 'outputPaths' kPBX_PHASE_showEnvVarsInLog = 'showEnvVarsInLog' kPBX_REFERENCE_path = 'path' kPBX_REFERENCE_name = 'name' kPBX_REFERENCE_refType = 'refType' kPBX_REFERENCE_sourceTree = 'sourceTree' kPBX_REFERENCE_lastKnownFileType = 'lastKnownFileType' kPBX_REFERENCE_fileEncoding = 'fileEncoding' kPBX_REFERENCE_explicitFileType = 'explicitFileType' kPBX_REFERENCE_includeInIndex = 'includeInIndex' kPBX_REFERENCE_children = 'children' kPBX_BUILDFILE_fileRef = 'fileRef' kPBX_BUILDFILE_settings = 'settings' kPBX_PROXY_remoteRef = 'remoteRef' kPBX_PROJECT_mainGroup = 'mainGroup' kPBX_PROJECT_targets = 'targets' kPBX_PROJECT_attributes = 'attributes' kPBX_PROJECT_compatibilityVersion = 'compatibilityVersion' kPBX_PROJECT_developmentRegion = 'developmentRegion' kPBX_PROJECT_hasScannedForEncodings = 'hasScannedForEncodings' kPBX_PROJECT_knownRegions = 'knownRegions' kPBX_PROJECT_productRefGroup = 'productRefGroup' kPBX_PROJECT_projectReferences = 'projectReferences' kPBX_PROJECTREF_ProductGroup = 'ProductGroup' kPBX_PROJECTREF_ProjectRef = 'ProjectRef' kPBX_TARGETDEP_target = 'target' kPBX_TARGETDEP_targetProxy = 'targetProxy' kPBX_CONTAINERITEMPROXY_remoteGlobalIDString = 'remoteGlobalIDString' kPBX_CONTAINERITEMPROXY_containerPortal = 'containerPortal' kPBX_XCBUILDCONFIG_baseConfigurationReference = 'baseConfigurationReference' kPBX_XCCONFIGURATION_buildConfigurations = 'buildConfigurations' kPBX_XCVersionGroup_currentVersion = 'currentVersion' ================================================ FILE: nslocalizer/xcodeproj/pbProj/PBX_Lookup.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from . import PBXItem from . import PBXAggregateTarget from . import PBXAppleScriptBuildPhase from . import PBXApplicationReference from . import PBXApplicationTarget from . import PBXBuildFile from . import PBXBuildRule from . import PBXBundleReference from . import PBXBundleTarget from . import PBXContainerItemProxy from . import PBXCopyFilesBuildPhase from . import PBXExecutableFileReference from . import PBXFileReference from . import PBXFrameworkReference from . import PBXFrameworksBuildPhase from . import PBXFrameworkTarget from . import PBXGroup from . import PBXHeadersBuildPhase from . import PBXJavaArchiveBuildPhase from . import PBXLegacyTarget from . import PBXLibraryReference from . import PBXLibraryTarget from . import PBXNativeTarget from . import PBXProject from . import PBXReferenceProxy from . import PBXResourcesBuildPhase from . import PBXRezBuildPhase from . import PBXShellScriptBuildPhase from . import PBXSourcesBuildPhase from . import PBXStandAloneTarget from . import PBXTargetDependency from . import PBXToolTarget from . import PBXVariantGroup from . import PBXZipArchiveReference from . import XCBuildConfiguration from . import XCConfigurationList from . import XCVersionGroup PBX_TYPE_TABLE = { 'PBXAggregateTarget': PBXAggregateTarget.PBXAggregateTarget, 'PBXAppleScriptBuildPhase': PBXAppleScriptBuildPhase.PBXAppleScriptBuildPhase, 'PBXApplicationReference': PBXApplicationReference.PBXApplicationReference, 'PBXApplicationTarget': PBXApplicationTarget.PBXApplicationTarget, 'PBXBuildFile': PBXBuildFile.PBXBuildFile, 'PBXBuildRule': PBXBuildRule.PBXBuildRule, 'PBXBundleReference': PBXBundleReference.PBXBundleReference, 'PBXBundleTarget': PBXBundleTarget.PBXBundleTarget, 'PBXContainerItemProxy': PBXContainerItemProxy.PBXContainerItemProxy, 'PBXCopyFilesBuildPhase': PBXCopyFilesBuildPhase.PBXCopyFilesBuildPhase, 'PBXExecutableFileReference': PBXExecutableFileReference.PBXExecutableFileReference, 'PBXFileReference': PBXFileReference.PBXFileReference, 'PBXFrameworkReference': PBXFrameworkReference.PBXFrameworkReference, 'PBXFrameworksBuildPhase': PBXFrameworksBuildPhase.PBXFrameworksBuildPhase, 'PBXFrameworkTarget': PBXFrameworkTarget.PBXFrameworkTarget, 'PBXGroup': PBXGroup.PBXGroup, 'PBXHeadersBuildPhase': PBXHeadersBuildPhase.PBXHeadersBuildPhase, 'PBXJavaArchiveBuildPhase': PBXJavaArchiveBuildPhase.PBXJavaArchiveBuildPhase, 'PBXLegacyTarget': PBXLegacyTarget.PBXLegacyTarget, 'PBXLibraryReference': PBXLibraryReference.PBXLibraryReference, 'PBXLibraryTarget': PBXLibraryTarget.PBXLibraryTarget, 'PBXNativeTarget': PBXNativeTarget.PBXNativeTarget, 'PBXProject': PBXProject.PBXProject, 'PBXReferenceProxy': PBXReferenceProxy.PBXReferenceProxy, 'PBXResourcesBuildPhase': PBXResourcesBuildPhase.PBXResourcesBuildPhase, 'PBXRezBuildPhase': PBXRezBuildPhase.PBXRezBuildPhase, 'PBXShellScriptBuildPhase': PBXShellScriptBuildPhase.PBXShellScriptBuildPhase, 'PBXSourcesBuildPhase': PBXSourcesBuildPhase.PBXSourcesBuildPhase, 'PBXStandAloneTarget': PBXStandAloneTarget.PBXStandAloneTarget, 'PBXTargetDependency': PBXTargetDependency.PBXTargetDependency, 'PBXToolTarget': PBXToolTarget.PBXToolTarget, 'PBXVariantGroup': PBXVariantGroup.PBXVariantGroup, 'PBXZipArchiveReference': PBXZipArchiveReference.PBXZipArchiveReference, 'XCBuildConfiguration': XCBuildConfiguration.XCBuildConfiguration, 'XCConfigurationList': XCConfigurationList.XCConfigurationList, 'XCVersionGroup': XCVersionGroup.XCVersionGroup, } def PBX_Type_Resolver(identifier, dictionary): object_type = dictionary.get(PBX_Constants.kPBX_isa, None) result = None if object_type: result = PBX_TYPE_TABLE.get(object_type, PBXItem.PBXItem)(identifier, dictionary) return result ================================================ FILE: nslocalizer/xcodeproj/pbProj/XCBuildConfiguration.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBXItem class XCBuildConfiguration(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_XCBUILDCONFIG_baseConfigurationReference, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/XCConfigurationList.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBXItem class XCConfigurationList(PBXItem): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_XCCONFIGURATION_buildConfigurations, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/XCVersionGroup.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import PBX_Constants from .PBXItem import PBX_Base_Reference class XCVersionGroup(PBX_Base_Reference): def __init__(self, identifier, dictionary): super(self.__class__, self).__init__(identifier, dictionary) def resolveGraph(self, project): super(self.__class__, self).resolveGraph(project) self.resolveGraphNodesForArray(PBX_Constants.kPBX_REFERENCE_children, project) self.resolveGraphNodeForKey(PBX_Constants.kPBX_XCVersionGroup_currentVersion, project) ================================================ FILE: nslocalizer/xcodeproj/pbProj/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import sys import os import pbPlist ================================================ FILE: nslocalizer/xcodeproj/pbProj/pbProj.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import pbPlist from . import PBX_Constants from . import PBX_Lookup class PBXProj(object): def __init__(self, file_path): plist = pbPlist.pbPlist.PBPlist(file_path) contents = plist.root.nativeType() self.pbx_objects = set() self.pbx_identifier = None self.pbx_root_object = None self.pbx_object_version = 0 self.pbx_archive_version = 0 if contents is not None: # get the path that we read from self.pbx_file_path = plist.file_path # get the root object identifier self.pbx_identifier = contents.get(PBX_Constants.kPBX_rootObject, None) # get the archive version number archive_version = contents.get(PBX_Constants.kPBX_archiveVersion, None) if archive_version: self.pbx_archive_version = int(archive_version) # get the object version number object_version = contents.get(PBX_Constants.kPBX_objectVersion, None) if object_version: self.pbx_object_version = int(object_version) # get the classes self.pbx_classes = contents.get(PBX_Constants.kPBX_classes, None) # get all the objects objects_dict = contents.get(PBX_Constants.kPBX_objects, None) self.pbx_objects = [PBX_Lookup.PBX_Type_Resolver(entry, value) for entry, value in list(objects_dict.items())] self.pbx_root_object = self.objectForIdentifier(self.pbx_identifier) self.pbx_root_object.resolveGraph(self) def __repr__(self): rep_string = '<%s : INVALID OBJECT>' % (self.__class__.__name__) if self.isValid(): rep_string = '<%s : %s : %s>' % (self.__class__.__name__, self.pbx_identifier, self.pbx_file_path) return rep_string def __attrs(self): return (self.pbx_identifier, self.pbx_file_path) def __eq__(self, other): return isinstance(other, PBXProj) and self.pbx_identifier == other.pbx_identifier and self.pbx_file_path == other.pbx_file_path def __hash__(self): return hash(self.__attrs()) def isValid(self): return self.pbx_identifier is not None def objectForIdentifier(self, identifier): """ Returns the parsed object from the project file for matching identifier, if no matching object is found it will return None. """ result = None if self.isValid(): filter_results = [pbx_object for pbx_object in self.pbx_objects if pbx_object.identifier == identifier] if len(filter_results): result = filter_results[0] return result def projects(self): """ This method returns a set of 'xcodeproj' objects that represents any referenced xcodeproj files in this project. """ subprojects = set() if self.isValid(): subprojects = [path for path in self.__subproject_paths()] return subprojects def __subproject_paths(self): """ This method is for returning a list of paths to referenced project files in this xcodeproj file. """ paths = list() if self.isValid(): project_references = self.pbx_root_object.get(PBX_Constants.kPBX_PROJECT_projectReferences, None) if project_references: paths = [project_dict[PBX_Constants.kPBX_PROJECTREF_ProjectRef] for project_dict in project_references] return paths def targets(self): """ This method will return a list of build targets that are associated with this xcodeproj. """ targets = list() if self.isValid(): target_list = self.pbx_root_object.get(PBX_Constants.kPBX_PROJECT_targets, None) if target_list: targets.extend(target_list) return targets ================================================ FILE: nslocalizer/xcodeproj/xcodeproj.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os from .pbProj import pbProj from ..Helpers.Logger import Logger class xcodeproj(object): def __init__(self, xcodeproj_file_path): if os.path.exists(xcodeproj_file_path): if xcodeproj_file_path.endswith(('.xcodeproj', '.pbproj')): self.file_path = xcodeproj_file_path # loading the pbxproj pbxproj_file_path = os.path.join(self.file_path, 'project.pbxproj') if os.path.exists(pbxproj_file_path): self.project_file = pbProj.PBXProj(pbxproj_file_path) else: # pragma: no cover Logger.write().error('Could not find the pbxproj file!') else: # pragma: no cover Logger.write().error('Not a Xcode project file!') else: # pragma: no cover Logger.write().error('Could not find the Xcode project file!') def projects(self): return self.project_file.projects() ================================================ FILE: nslocalizer.py ================================================ #!/usr/bin/python import nslocalizer def main(): nslocalizer.main() if __name__ == "__main__": main() ================================================ FILE: pylintrc ================================================ [MASTER] # Add files or directories to the blacklist. They should be base names, not # paths. ignore= # Add files or directories matching the regex patterns to the blacklist. The # regex matches against base names, not paths. ignore-patterns= # Pickle collected data for later comparisons. persistent=yes # List of plugins (as comma separated values of python modules names) to load, # usually to register additional checkers. load-plugins= # Use multiple processes to speed up Pylint. jobs=1 # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. unsafe-load-any-extension=no # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code extension-pkg-whitelist= # Allow optimization of some AST trees. This will activate a peephole AST # optimizer, which will apply various small optimizations. For instance, it can # be used to obtain the result of joining multiple strings with the addition # operator. Joining a lot of strings can lead to a maximum recursion error in # Pylint and this flag can prevent that. It has one side effect, the resulting # AST will be different than the one from reality. This option is deprecated # and it will be removed in Pylint 2.0. optimize-ast=no [MESSAGES CONTROL] # Only show warnings with the listed confidence levels. Leave empty to show # all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED confidence= # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option # multiple time (only on the command line, not in the configuration file where # it should appear only once). See also the "--disable" option for examples. #enable= # Disable the message, report, category or checker with the given id(s). You # can either give multiple identifiers separated by comma (,) or put this # option multiple times (only on the command line, not in the configuration # file where it should appear only once).You can also use "--disable=all" to # disable everything first and then reenable specific checks. For example, if # you want to run only the similarities checker, you can use "--disable=all # --enable=similarities". If you want to run only the classes checker, but have # no Warning level messages displayed, use"--disable=all --enable=classes # --disable=W" disable=missing-docstring,too-many-lines,locally-disabled,too-many-ancestors [REPORTS] # Set the output format. Available formats are text, parseable, colorized, msvs # (visual studio) and html. You can also give a reporter class, eg # mypackage.mymodule.MyReporterClass. output-format=text # Put messages in a separate file for each module / package specified on the # command line instead of printing them on stdout. Reports (if any) will be # written in a file name "pylint_global.[txt|html]". This option is deprecated # and it will be removed in Pylint 2.0. files-output=no # Tells whether to display a full report or only the messages reports=yes # Python expression which should return a note less than 10 (10 is the highest # note). You have access to the variables errors warning, statement which # respectively contain the number of errors / warnings messages and the total # number of statements analyzed. This is used by the global evaluation report # (RP0004). evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) # Template used to display messages. This is a python new-style format string # used to format the message information. See doc for all details #msg-template= [BASIC] # Good variable names which should always be accepted, separated by a comma good-names=Run,_ # Bad variable names which should always be refused, separated by a comma bad-names=foo,bar,baz,toto,tutu,tata,i,j,k,idx # Colon-delimited sets of names that determine each other's naming style when # the name regexes allow several styles. name-group= # Include a hint for the correct naming format with invalid-name include-naming-hint=no # List of decorators that produce properties, such as abc.abstractproperty. Add # to this list to register other decorators that produce valid properties. property-classes=abc.abstractproperty # Regular expression matching correct function names function-rgx=[A-Za-z_][a-zA-Z0-9_]{2,40}$ # Naming hint for function names function-name-hint=[A-Za-z_][a-zA-Z0-9_]{2,40}$ # Regular expression matching correct variable names variable-rgx=[a-z_][a-z0-9_]{2,30}$ # Naming hint for variable names variable-name-hint=[a-z_][a-z0-9_]{2,30}$ # Regular expression matching correct constant names const-rgx=(([A-Za-z_][A-Za-z0-9_]*)|(__.*__))$ # Naming hint for constant names const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ # Regular expression matching correct attribute names attr-rgx=[a-z_][a-z0-9_]{2,30}$ # Naming hint for attribute names attr-name-hint=[a-z_][a-z0-9_]{2,30}$ # Regular expression matching correct argument names argument-rgx=[a-z_][a-z0-9_]{2,30}$ # Naming hint for argument names argument-name-hint=[a-z_][a-z0-9_]{2,30}$ # Regular expression matching correct class attribute names class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ # Naming hint for class attribute names class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ # Regular expression matching correct inline iteration names inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ # Naming hint for inline iteration names inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ # Regular expression matching correct class names class-rgx=[a-zA-Z0-9_]+$ # Naming hint for class names class-name-hint=[a-zA-Z0-9_]+$ # Regular expression matching correct module names module-rgx=(([a-z_][a-z0-9_]*)|([A-Za-z][a-zA-Z0-9_]+))$ # Naming hint for module names module-name-hint=(([a-z_][a-z0-9_]*)|([A-Za-z][a-zA-Z0-9]+))$ # Regular expression matching correct method names method-rgx=[a-z_][a-zA-Z0-9_]{2,40}$ # Naming hint for method names method-name-hint=[a-zA-Z0-9_]{2,40}$ # Regular expression which should only match function or class names that do # not require a docstring. no-docstring-rgx=^_ # Minimum line length for functions/classes that require docstrings, shorter # ones are exempt. docstring-min-length=0 [ELIF] # Maximum number of nested blocks for function / method body max-nested-blocks=5 [FORMAT] # Maximum number of characters on a single line. max-line-length=100000 # Regexp for a line that is allowed to be longer than the limit. ignore-long-lines=^\s*(# )??$ # Allow the body of an if to be on the same line as the test if there is no # else. single-line-if-stmt=no # List of optional constructs for which whitespace checking is disabled. `dict- # separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. # `trailing-comma` allows a space between comma and closing bracket: (a, ). # `empty-line` allows space-only lines. no-space-check=trailing-comma,dict-separator # Maximum number of lines in a module max-module-lines=0 # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 # tab). indent-string=' ' # Number of spaces of indent required inside a hanging or continued line. indent-after-paren=4 # Expected format of line ending, e.g. empty (any line ending), LF or CRLF. expected-line-ending-format= [LOGGING] # Logging modules to check that the string format arguments are in logging # function parameter format logging-modules=logging [MISCELLANEOUS] # List of note tags to take in consideration, separated by a comma. notes=FIXME,XXX,TODO [SIMILARITIES] # Minimum lines number of a similarity. min-similarity-lines=10 # Ignore comments when computing similarities. ignore-comments=yes # Ignore docstrings when computing similarities. ignore-docstrings=yes # Ignore imports when computing similarities. ignore-imports=yes [SPELLING] # Spelling dictionary name. Available dictionaries: none. To make it working # install python-enchant package. spelling-dict= # List of comma separated words that should not be checked. spelling-ignore-words= # A path to a file that contains private dictionary; one word per line. spelling-private-dict-file= # Tells whether to store unknown words to indicated private dictionary in # --spelling-private-dict-file option instead of raising a message. spelling-store-unknown-words=no [TYPECHECK] # Tells whether missing members accessed in mixin class should be ignored. A # mixin class is detected if its name ends with "mixin" (case insensitive). ignore-mixin-members=yes # List of module names for which member attributes should not be checked # (useful for modules/projects where namespaces are manipulated during runtime # and thus existing member attributes cannot be deduced by static analysis. It # supports qualified module names, as well as Unix pattern matching. ignored-modules= # List of class names for which member attributes should not be checked (useful # for classes with dynamically set attributes). This supports the use of # qualified names. ignored-classes=optparse.Values,thread._local,_thread._local # List of members which are set dynamically and missed by pylint inference # system, and so shouldn't trigger E1101 when accessed. Python regular # expressions are accepted. generated-members= # List of decorators that produce context managers, such as # contextlib.contextmanager. Add to this list to register other decorators that # produce valid context managers. contextmanager-decorators=contextlib.contextmanager [VARIABLES] # Tells whether we should check for unused import in __init__ files. init-import=no # A regular expression matching the name of dummy variables (i.e. expectedly # not used). dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy # List of additional names supposed to be defined in builtins. Remember that # you should avoid to define new builtins when possible. additional-builtins= # List of strings which can identify a callback function by name. A callback # name must start or end with one of those strings. callbacks=cb_,_cb # List of qualified module names which can have objects that can redefine # builtins. redefining-builtins-modules=six.moves,future.builtins [CLASSES] # List of method names used to declare (i.e. assign) instance attributes. defining-attr-methods=__init__,__new__,setUp # List of valid names for the first argument in a class method. valid-classmethod-first-arg=cls # List of valid names for the first argument in a metaclass class method. valid-metaclass-classmethod-first-arg=mcs # List of member names, which should be excluded from the protected access # warning. exclude-protected=_asdict,_fields,_replace,_source,_make [DESIGN] # Maximum number of arguments for function / method max-args=5 # Argument names that match this expression will be ignored. Default to name # with leading underscore ignored-argument-names=_.* # Maximum number of locals for function / method body max-locals=15 # Maximum number of return / yield for function / method body max-returns=1 # Maximum number of branch for function / method body max-branches=12 # Maximum number of statements in function / method body max-statements=50 # Maximum number of parents for a class (see R0901). max-parents=7 # Maximum number of attributes for a class (see R0902). max-attributes=10 # Minimum number of public methods for a class (see R0903). min-public-methods=0 # Maximum number of public methods for a class (see R0904). max-public-methods=20 # Maximum number of boolean expressions in a if statement max-bool-expr=3 [IMPORTS] # Deprecated modules which should not be used, separated by a comma deprecated-modules=regsub,TERMIOS,Bastion,rexec # Create a graph of every (i.e. internal and external) dependencies in the # given file (report RP0402 must not be disabled) import-graph= # Create a graph of external dependencies in the given file (report RP0402 must # not be disabled) ext-import-graph= # Create a graph of internal dependencies in the given file (report RP0402 must # not be disabled) int-import-graph= # Force import order to recognize a module as part of the standard # compatibility libraries. known-standard-library=os,re,sys,argparse,logging # Force import order to recognize a module as part of a third party library. known-third-party= # Analyse import fallback blocks. This can be used to support both Python 2 and # 3 compatible code, which means that the block might have code that exists # only in one or another interpreter, leading to false positives when analysed. analyse-fallback-blocks=no [EXCEPTIONS] # Exceptions that will emit a warning when being caught. Defaults to # "Exception" overgeneral-exceptions=Exception ================================================ FILE: readme.md ================================================ nslocalizer =========== [![Code Climate](https://img.shields.io/codeclimate/github/samdmarshall/nslocalizer.svg)](https://codeclimate.com/github/samdmarshall/nslocalizer) [![Test Coverage](https://img.shields.io/codeclimate/coverage/github/samdmarshall/nslocalizer.svg)](https://codeclimate.com/github/samdmarshall/nslocalizer/coverage) [![CircleCI branch](https://img.shields.io/circleci/project/samdmarshall/nslocalizer/develop.svg)](https://circleci.com/gh/samdmarshall/nslocalizer/tree/develop) [![Dependency Status](https://dependencyci.com/github/samdmarshall/nslocalizer/badge)](https://dependencyci.com/github/samdmarshall/nslocalizer) This is a command line tool that is used for discovering missing and unused localization strings in Xcode projects. ## Contributing and Code of Conduct [![License](https://img.shields.io/badge/License-3--Clause%20BSD-blue.svg)](./LICENSE) This project and related material has a Code of Conduct that is listed in the [contributing.md](./contributing.md) file. This must be read and adhered to when interacting with this project. Additionally this code is released under a 3-clause BSD license that you can read [here](./LICENSE). ## Requirements ![Python](https://img.shields.io/badge/Python3-3.5.0-brightgreen.svg) This tool is built and tested against Python 3.5.0. Module | Version ----------|----------- pbPlist | >=1.0 pyobjc-core | >= 2.5.1 pyobjc-framework-Cocoa | >= 2.5.1 langcodes | >= 1.2.0 ## Installation Via pip and python 3 $ pip3 install nslocalizer To install the tool from the repo, clone from Github then run the `make build` command. ## Usage To use **nslocalizer** to generate warnings about missing or unused NSLocalizedStrings, you will have to pass it a project and target as input: $ nslocalizer --project --target There are a number of flags that can be passed to modify the behavior of **pyconfig**: Flags | Usage -------------------|----------------------------------------------------------- `--version` | Displays the version of **nslocalizer** and exits `--find-missing` | Finds any strings that are missing translations for any of the supported languages `--find-unused` | Finds any strings that are unused in the code `--quiet` | Silences all logging output `--verbose` | Logs additional information `--ignore ` | Will silence warnings for any of the languages listed to be ignored > Note: Both `--find-missing` and `--find-unused` flags can be supplied to the same invocation of `nslocalizer`. ## Example Find missing translation strings: ``` $ nslocalizer --project Foo.xcodeproj --target MyNewApp --find-missing /Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:327: warning: String "foo_setup_twitter_integation" missing for: German, Traditional Chinese, European Portuguese, Spanish /Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:356: warning: String "foo_setup_facebook_integation" missing for: German, Traditional Chinese, European Portuguese, Swedish, Polish, Latin American Spanish, British English, Brazilian Portuguese ``` Find unused translation strings: ``` $ nslocalizer --project Foo.xcodeproj --target MyNewApp --find-unused /Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:327: warning: String "foo_setup_twitter_integation" is not used /Users/Samantha/Projects/Foo/Foo/Assets/Base.lproj/Localizable.strings:356: warning: String "foo_setup_facebook_integation" is not used ``` ## Integration **nslocalizer** is intended to be used as part of a build of the Xcode project file. To integrate you will have to add a new "run script" phase to your target and then invoke as such: ``` nslocalizer --project $PROJECT_DIR/YourProject.xcodeproj --target $TARGET_NAME --find-missing --find-unused ``` ================================================ FILE: requirements.txt ================================================ coverage >= 4 tox >= 2.3.1 tox_pyenv >= 1.0.3 codeclimate-test-reporter >= 0.1.2 pylint >= 1.6.1 pyobjc-core >= 2.5.1 pyobjc-framework-Cocoa >= 2.5.1 pbPlist >= 1.0.4 langcodes >= 1.2.0 ================================================ FILE: setup.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from setuptools import setup import sys if sys.version_info < (3,0): print('This tool requires at least Python 3.0. Please run `brew install python3` first.') sys.exit() setup( name = 'nslocalizer', version = '1.0.2', description = 'Tool for finding missing and unused NSLocalizdStrings', url = 'https://github.com/samdmarshall/nslocalizer', author = 'Samantha Marshall', author_email = 'hello@pewpewthespells.com', license = 'BSD 3-Clause', packages = [ 'nslocalizer', 'nslocalizer/Helpers', 'nslocalizer/xcodeproj', 'nslocalizer/xcodeproj/pbProj', 'nslocalizer/Language', 'nslocalizer/Executor', 'nslocalizer/Finder', 'nslocalizer/Reporter', ], entry_points = { 'console_scripts': [ 'nslocalizer = nslocalizer:main' ] }, test_suite = 'tests', zip_safe = False, install_requires = [ 'pyobjc-core', 'pyobjc-framework-Cocoa', 'pbPlist', 'langcodes', ] ) ================================================ FILE: tests/__init__.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. from . import test_runner ================================================ FILE: tests/nslocalizer-example/Base.lproj/Localizable.strings ================================================ /* Localizable.strings pylocalizer-example Created by Samantha Marshall on 7/27/16. Copyright © 2016 Samantha Marshall. All rights reserved. */ ================================================ FILE: tests/nslocalizer-example/de.lproj/Localizable.strings ================================================ /* Localizable.strings pylocalizer-example Created by Samantha Marshall on 7/27/16. Copyright © 2016 Samantha Marshall. All rights reserved. */ ================================================ FILE: tests/nslocalizer-example/en.lproj/Localizable.strings ================================================ /* Localizable.strings pylocalizer-example Created by Samantha Marshall on 7/27/16. Copyright © 2016 Samantha Marshall. All rights reserved. */ ================================================ FILE: tests/nslocalizer-example/es.lproj/Localizable.strings ================================================ /* Localizable.strings pylocalizer-example Created by Samantha Marshall on 7/27/16. Copyright © 2016 Samantha Marshall. All rights reserved. */ ================================================ FILE: tests/nslocalizer-example/fr.lproj/Localizable.strings ================================================ /* Localizable.strings pylocalizer-example Created by Samantha Marshall on 7/27/16. Copyright © 2016 Samantha Marshall. All rights reserved. */ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/AppDelegate.h ================================================ // // AppDelegate.h // pylocalizer-example // // Created by Samantha Marshall on 7/27/16. // Copyright © 2016 Samantha Marshall. All rights reserved. // #import @interface AppDelegate : UIResponder @property (strong, nonatomic) UIWindow *window; @end ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/AppDelegate.m ================================================ // // AppDelegate.m // pylocalizer-example // // Created by Samantha Marshall on 7/27/16. // Copyright © 2016 Samantha Marshall. All rights reserved. // #import "AppDelegate.h" #import "DetailViewController.h" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController; UINavigationController *navigationController = [splitViewController.viewControllers lastObject]; navigationController.topViewController.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem; splitViewController.delegate = self; return YES; } - (void)applicationWillResignActive:(UIApplication *)application { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - (void)applicationDidEnterBackground:(UIApplication *)application { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - (void)applicationWillEnterForeground:(UIApplication *)application { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - (void)applicationDidBecomeActive:(UIApplication *)application { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - (void)applicationWillTerminate:(UIApplication *)application { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } #pragma mark - Split view - (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController { if ([secondaryViewController isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[DetailViewController class]] && ([(DetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) { // Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded. return YES; } else { return NO; } } @end ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "images" : [ { "idiom" : "iphone", "size" : "29x29", "scale" : "2x" }, { "idiom" : "iphone", "size" : "29x29", "scale" : "3x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "2x" }, { "idiom" : "iphone", "size" : "40x40", "scale" : "3x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "2x" }, { "idiom" : "iphone", "size" : "60x60", "scale" : "3x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "1x" }, { "idiom" : "ipad", "size" : "29x29", "scale" : "2x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "1x" }, { "idiom" : "ipad", "size" : "40x40", "scale" : "2x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "1x" }, { "idiom" : "ipad", "size" : "76x76", "scale" : "2x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/Base.lproj/Main.storyboard ================================================ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/DetailViewController.h ================================================ // // DetailViewController.h // pylocalizer-example // // Created by Samantha Marshall on 7/27/16. // Copyright © 2016 Samantha Marshall. All rights reserved. // #import @interface DetailViewController : UIViewController @property (strong, nonatomic) id detailItem; @property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel; @end ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/DetailViewController.m ================================================ // // DetailViewController.m // pylocalizer-example // // Created by Samantha Marshall on 7/27/16. // Copyright © 2016 Samantha Marshall. All rights reserved. // #import "DetailViewController.h" @interface DetailViewController () @end @implementation DetailViewController #pragma mark - Managing the detail item - (void)setDetailItem:(id)newDetailItem { if (_detailItem != newDetailItem) { _detailItem = newDetailItem; // Update the view. [self configureView]; } } - (void)configureView { // Update the user interface for the detail item. if (self.detailItem) { self.detailDescriptionLabel.text = [self.detailItem description]; } } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self configureView]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType APPL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1 LSRequiresIPhoneOS UILaunchStoryboardName LaunchScreen UIMainStoryboardFile Main UIRequiredDeviceCapabilities armv7 UIStatusBarTintParameters UINavigationBar Style UIBarStyleDefault Translucent UISupportedInterfaceOrientations UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/MasterViewController.h ================================================ // // MasterViewController.h // pylocalizer-example // // Created by Samantha Marshall on 7/27/16. // Copyright © 2016 Samantha Marshall. All rights reserved. // #import @class DetailViewController; @interface MasterViewController : UITableViewController @property (strong, nonatomic) DetailViewController *detailViewController; @end ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/MasterViewController.m ================================================ // // MasterViewController.m // pylocalizer-example // // Created by Samantha Marshall on 7/27/16. // Copyright © 2016 Samantha Marshall. All rights reserved. // #import "MasterViewController.h" #import "DetailViewController.h" @interface MasterViewController () @property NSMutableArray *objects; @end @implementation MasterViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.navigationItem.leftBarButtonItem = self.editButtonItem; UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; self.navigationItem.rightBarButtonItem = addButton; self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController]; } - (void)viewWillAppear:(BOOL)animated { self.clearsSelectionOnViewWillAppear = self.splitViewController.isCollapsed; [super viewWillAppear:animated]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)insertNewObject:(id)sender { if (!self.objects) { self.objects = [[NSMutableArray alloc] init]; } [self.objects insertObject:[NSDate date] atIndex:0]; NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; } #pragma mark - Segues - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([[segue identifier] isEqualToString:@"showDetail"]) { NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; NSDate *object = self.objects[indexPath.row]; DetailViewController *controller = (DetailViewController *)[[segue destinationViewController] topViewController]; [controller setDetailItem:object]; controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem; controller.navigationItem.leftItemsSupplementBackButton = YES; } } #pragma mark - Table View - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.objects.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; NSDate *object = self.objects[indexPath.row]; cell.textLabel.text = [object description]; return cell; } - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the specified item to be editable. return YES; } - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { if (editingStyle == UITableViewCellEditingStyleDelete) { [self.objects removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; } else if (editingStyle == UITableViewCellEditingStyleInsert) { // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view. } } @end ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/de.lproj/LaunchScreen.strings ================================================ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/de.lproj/Main.strings ================================================ /* Class = "UILabel"; text = "Detail view content goes here"; ObjectID = "0XM-y9-sOw"; */ "0XM-y9-sOw.text" = "Detail view content goes here"; /* Class = "UITableViewController"; title = "Master"; ObjectID = "7bK-jq-Zjz"; */ "7bK-jq-Zjz.title" = "Master"; /* Class = "UILabel"; text = "Title"; ObjectID = "Arm-wq-HPj"; */ "Arm-wq-HPj.text" = "Title"; /* Class = "UIViewController"; title = "Detail"; ObjectID = "JEX-9P-axG"; */ "JEX-9P-axG.title" = "Detail"; /* Class = "UINavigationController"; title = "Master"; ObjectID = "RMx-3f-FxP"; */ "RMx-3f-FxP.title" = "Master"; /* Class = "UINavigationItem"; title = "Master"; ObjectID = "Zdf-7t-Un8"; */ "Zdf-7t-Un8.title" = "Master"; /* Class = "UINavigationItem"; title = "Detail"; ObjectID = "mOI-FS-AaM"; */ "mOI-FS-AaM.title" = "Detail"; ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/es.lproj/LaunchScreen.strings ================================================ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/es.lproj/Main.strings ================================================ /* Class = "UILabel"; text = "Detail view content goes here"; ObjectID = "0XM-y9-sOw"; */ "0XM-y9-sOw.text" = "Detail view content goes here"; /* Class = "UITableViewController"; title = "Master"; ObjectID = "7bK-jq-Zjz"; */ "7bK-jq-Zjz.title" = "Master"; /* Class = "UILabel"; text = "Title"; ObjectID = "Arm-wq-HPj"; */ "Arm-wq-HPj.text" = "Title"; /* Class = "UIViewController"; title = "Detail"; ObjectID = "JEX-9P-axG"; */ "JEX-9P-axG.title" = "Detail"; /* Class = "UINavigationController"; title = "Master"; ObjectID = "RMx-3f-FxP"; */ "RMx-3f-FxP.title" = "Master"; /* Class = "UINavigationItem"; title = "Master"; ObjectID = "Zdf-7t-Un8"; */ "Zdf-7t-Un8.title" = "Master"; /* Class = "UINavigationItem"; title = "Detail"; ObjectID = "mOI-FS-AaM"; */ "mOI-FS-AaM.title" = "Detail"; ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/fr.lproj/LaunchScreen.strings ================================================ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/fr.lproj/Main.strings ================================================ /* Class = "UILabel"; text = "Detail view content goes here"; ObjectID = "0XM-y9-sOw"; */ "0XM-y9-sOw.text" = "Detail view content goes here"; /* Class = "UITableViewController"; title = "Master"; ObjectID = "7bK-jq-Zjz"; */ "7bK-jq-Zjz.title" = "Master"; /* Class = "UILabel"; text = "Title"; ObjectID = "Arm-wq-HPj"; */ "Arm-wq-HPj.text" = "Title"; /* Class = "UIViewController"; title = "Detail"; ObjectID = "JEX-9P-axG"; */ "JEX-9P-axG.title" = "Detail"; /* Class = "UINavigationController"; title = "Master"; ObjectID = "RMx-3f-FxP"; */ "RMx-3f-FxP.title" = "Master"; /* Class = "UINavigationItem"; title = "Master"; ObjectID = "Zdf-7t-Un8"; */ "Zdf-7t-Un8.title" = "Master"; /* Class = "UINavigationItem"; title = "Detail"; ObjectID = "mOI-FS-AaM"; */ "mOI-FS-AaM.title" = "Detail"; ================================================ FILE: tests/nslocalizer-example/pylocalizer-example/main.m ================================================ // // main.m // pylocalizer-example // // Created by Samantha Marshall on 7/27/16. // Copyright © 2016 Samantha Marshall. All rights reserved. // #import #import "AppDelegate.h" int main(int argc, char * argv[]) { @autoreleasepool { return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); } } ================================================ FILE: tests/nslocalizer-example/pylocalizer-example.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 154465741D49592800243158 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 154465731D49592800243158 /* main.m */; }; 154465771D49592800243158 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 154465761D49592800243158 /* AppDelegate.m */; }; 1544657A1D49592800243158 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 154465791D49592800243158 /* MasterViewController.m */; }; 1544657D1D49592800243158 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1544657C1D49592800243158 /* DetailViewController.m */; }; 154465801D49592800243158 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 1544657E1D49592800243158 /* Main.storyboard */; }; 154465821D49592800243158 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 154465811D49592800243158 /* Assets.xcassets */; }; 154465851D49592800243158 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 154465831D49592800243158 /* LaunchScreen.storyboard */; }; 154465961D495A9C00243158 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 154465981D495A9C00243158 /* Localizable.strings */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 1544656F1D49592800243158 /* pylocalizer-example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "pylocalizer-example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 154465731D49592800243158 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 154465751D49592800243158 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 154465761D49592800243158 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 154465781D49592800243158 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = ""; }; 154465791D49592800243158 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = ""; }; 1544657B1D49592800243158 /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; 1544657C1D49592800243158 /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; 1544657F1D49592800243158 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 154465811D49592800243158 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 154465841D49592800243158 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 154465861D49592800243158 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 154465971D495A9C00243158 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = ""; }; 154465991D495A9D00243158 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; 1544659D1D495ADE00243158 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; }; 1544659E1D495AE600243158 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; 1544659F1D495AEB00243158 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 1544656C1D49592800243158 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 154465661D49592800243158 = { isa = PBXGroup; children = ( 154465981D495A9C00243158 /* Localizable.strings */, 154465711D49592800243158 /* pylocalizer-example */, 154465701D49592800243158 /* Products */, ); sourceTree = ""; }; 154465701D49592800243158 /* Products */ = { isa = PBXGroup; children = ( 1544656F1D49592800243158 /* pylocalizer-example.app */, ); name = Products; sourceTree = ""; }; 154465711D49592800243158 /* pylocalizer-example */ = { isa = PBXGroup; children = ( 154465751D49592800243158 /* AppDelegate.h */, 154465761D49592800243158 /* AppDelegate.m */, 154465781D49592800243158 /* MasterViewController.h */, 154465791D49592800243158 /* MasterViewController.m */, 1544657B1D49592800243158 /* DetailViewController.h */, 1544657C1D49592800243158 /* DetailViewController.m */, 1544657E1D49592800243158 /* Main.storyboard */, 154465811D49592800243158 /* Assets.xcassets */, 154465831D49592800243158 /* LaunchScreen.storyboard */, 154465861D49592800243158 /* Info.plist */, 154465721D49592800243158 /* Supporting Files */, ); path = "pylocalizer-example"; sourceTree = ""; }; 154465721D49592800243158 /* Supporting Files */ = { isa = PBXGroup; children = ( 154465731D49592800243158 /* main.m */, ); name = "Supporting Files"; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 1544656E1D49592800243158 /* pylocalizer-example */ = { isa = PBXNativeTarget; buildConfigurationList = 154465891D49592800243158 /* Build configuration list for PBXNativeTarget "pylocalizer-example" */; buildPhases = ( 1544656B1D49592800243158 /* Sources */, 1544656C1D49592800243158 /* Frameworks */, 1544656D1D49592800243158 /* Resources */, ); buildRules = ( ); dependencies = ( ); name = "pylocalizer-example"; productName = "pylocalizer-example"; productReference = 1544656F1D49592800243158 /* pylocalizer-example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ 154465671D49592800243158 /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0730; ORGANIZATIONNAME = "Samantha Marshall"; TargetAttributes = { 1544656E1D49592800243158 = { CreatedOnToolsVersion = 7.3.1; }; }; }; buildConfigurationList = 1544656A1D49592800243158 /* Build configuration list for PBXProject "pylocalizer-example" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, Base, fr, de, es, ); mainGroup = 154465661D49592800243158; productRefGroup = 154465701D49592800243158 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( 1544656E1D49592800243158 /* pylocalizer-example */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ 1544656D1D49592800243158 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( 154465851D49592800243158 /* LaunchScreen.storyboard in Resources */, 154465961D495A9C00243158 /* Localizable.strings in Resources */, 154465821D49592800243158 /* Assets.xcassets in Resources */, 154465801D49592800243158 /* Main.storyboard in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 1544656B1D49592800243158 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 154465771D49592800243158 /* AppDelegate.m in Sources */, 1544657A1D49592800243158 /* MasterViewController.m in Sources */, 154465741D49592800243158 /* main.m in Sources */, 1544657D1D49592800243158 /* DetailViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ 1544657E1D49592800243158 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( 1544657F1D49592800243158 /* Base */, ); name = Main.storyboard; sourceTree = ""; }; 154465831D49592800243158 /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( 154465841D49592800243158 /* Base */, ); name = LaunchScreen.storyboard; sourceTree = ""; }; 154465981D495A9C00243158 /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( 154465971D495A9C00243158 /* Base */, 154465991D495A9D00243158 /* en */, 1544659D1D495ADE00243158 /* fr */, 1544659E1D495AE600243158 /* de */, 1544659F1D495AEB00243158 /* es */, ); name = Localizable.strings; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 154465871D49592800243158 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; 154465881D49592800243158 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 9.3; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; 1544658A1D49592800243158 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = "pylocalizer-example/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.pewpewthespells.pylocalizer-example"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 1544658B1D49592800243158 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = "pylocalizer-example/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.pewpewthespells.pylocalizer-example"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 1544656A1D49592800243158 /* Build configuration list for PBXProject "pylocalizer-example" */ = { isa = XCConfigurationList; buildConfigurations = ( 154465871D49592800243158 /* Debug */, 154465881D49592800243158 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 154465891D49592800243158 /* Build configuration list for PBXNativeTarget "pylocalizer-example" */ = { isa = XCConfigurationList; buildConfigurations = ( 1544658A1D49592800243158 /* Debug */, 1544658B1D49592800243158 /* Release */, ); defaultConfigurationIsVisible = 0; }; /* End XCConfigurationList section */ }; rootObject = 154465671D49592800243158 /* Project object */; } ================================================ FILE: tests/nslocalizer-example/pylocalizer-example.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example.xcodeproj/xcuserdata/Samantha.xcuserdatad/xcschemes/pylocalizer-example.xcscheme ================================================ ================================================ FILE: tests/nslocalizer-example/pylocalizer-example.xcodeproj/xcuserdata/Samantha.xcuserdatad/xcschemes/xcschememanagement.plist ================================================ SchemeUserState pylocalizer-example.xcscheme orderHint 0 SuppressBuildableAutocreation 1544656E1D49592800243158 primary ================================================ FILE: tests/nslocalizer_test.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import os import unittest from nslocalizer import main class nslocalizerTestCases(unittest.TestCase): def test_missing_strings(self): example_path = os.path.join(os.path.dirname(__file__), 'nslocalizer-example/pylocalizer-example.xcodeproj') main(['--project', example_path, '--target', 'pylocalizer-example', '--find-missing']) self.assertTrue(True) def test_unused_strings(self): example_path = os.path.join(os.path.dirname(__file__), 'nslocalizer-example/pylocalizer-example.xcodeproj') main(['--project', example_path, '--target', 'pylocalizer-example', '--find-unused']) self.assertTrue(True) ================================================ FILE: tests/test_runner.py ================================================ # Copyright (c) 2016, Samantha Marshall (http://pewpewthespells.com) # All rights reserved. # # https://github.com/samdmarshall/nslocalizer # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # 3. Neither the name of Samantha Marshall nor the names of its contributors may # be used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED # OF THE POSSIBILITY OF SUCH DAMAGE. import unittest from . import nslocalizer_test if __name__ == '__main__': testsuite = unittest.TestLoader() testsuite.addTest(nslocalizer_test.nslocalizerTestCases) unittest.TextTestRunner(verbosity=1).run(testsuite) ================================================ FILE: tools/checkout_by_version.sh ================================================ #!/bin/bash commit_hash="$1" actual_commit=`git rev-list --all --parents | grep ". $commit_hash" | awk '{print $1}'` git checkout $actual_commit ================================================ FILE: tools/hooks/pre-commit ================================================ #!/bin/sh git_path=`git rev-parse --show-toplevel` pushd $git_path commit_hash=`git rev-parse --short HEAD` remote_origin=`git ls-remote --get-url` echo "remote_origin = '$remote_origin'\ncommit_hash = '$commit_hash'" > ./nslocalizer/version_info.py git add ./nslocalizer/version_info.py popd ================================================ FILE: tools/hooks-config.py ================================================ #!/usr/bin/env python import sys import os import filecmp import shutil import stat # Copies the commit-msg file into the .git/hooks directory to be executed by # git during commits if it does not already exist or if the file has been changed. # Files in the .git/hooks are not tracked, so any updates to commit-msg must # occur in the root and be copied over. base_git_hooks_path = '.git/hooks/' base_tools_hooks_path = './tools/hooks/' hooks = [ 'pre-commit' ] if not os.path.exists(base_git_hooks_path): os.mkdir(base_git_hooks_path) for hook in hooks: tools_hook_path = os.path.join(base_tools_hooks_path, hook) git_hook_path = os.path.join(base_git_hooks_path, hook) shutil.copy2(tools_hook_path, git_hook_path) st = os.stat(git_hook_path) os.chmod(git_hook_path, st.st_mode | stat.S_IEXEC) ================================================ FILE: tox.ini ================================================ [tox] platform = darwin envlist = py35 [testenv] whitelist_externals = coverage deps = coverage sitepackages = True commands = coverage run --source=./nslocalizer/ setup.py test