nixenvironment 0.0.59 → 0.0.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +14 -14
- data/bin/Config +2 -2
- data/bin/nixenvironment +420 -842
- data/legacy/CleanWorkingCopy.sh +69 -0
- data/legacy/Deploy.sh +44 -0
- data/legacy/DeployAPK.py +58 -0
- data/legacy/DeployIPA.sh +125 -0
- data/legacy/DetectSCM.sh +11 -0
- data/legacy/GenerateCodeCoverageForXCTests.sh +134 -0
- data/legacy/GenerateCodeDuplicationReport.sh +24 -0
- data/legacy/IncrementBuildNumber.py +129 -0
- data/legacy/LoadBuildEnvVars.sh +116 -0
- data/legacy/MakeTag.sh +94 -0
- data/legacy/RemoveTemporaryFiles.sh +9 -0
- data/legacy/SaveRevision.sh +122 -0
- data/legacy/UnityBuildAndroid.py +84 -0
- data/legacy/UnityBuildAutomationScripts/CommandLineReader.cs +130 -0
- data/legacy/UnityBuildAutomationScripts/NIXBuilder.cs +105 -0
- data/legacy/UnityBuildEnvVars.py +41 -0
- data/legacy/VerifyBinarySigning.py +80 -0
- data/legacy/svn-clean.pl +246 -0
- data/legacy/svncopy.pl +1134 -0
- data/lib/nixenvironment.rb +5 -0
- data/lib/nixenvironment/archiver.rb +690 -0
- data/lib/nixenvironment/build_env_vars_loader.rb +24 -0
- data/lib/nixenvironment/cmd_executor.rb +33 -0
- data/lib/nixenvironment/config.rb +127 -14
- data/lib/nixenvironment/git.rb +107 -0
- data/lib/nixenvironment/plist.rb +52 -0
- data/lib/nixenvironment/version.rb +1 -1
- data/lib/nixenvironment/xcodebuild.rb +167 -0
- data/nixenvironment.gemspec +6 -0
- data/utils/XcodeIconTagger/IconTagger +0 -0
- data/utils/XcodeIconTagger/masks/OneLineMask.png +0 -0
- data/utils/XcodeIconTagger/masks/TwoLineMask.png +0 -0
- data/utils/aapt +0 -0
- data/utils/gcovr +986 -0
- data/utils/identitieslist +0 -0
- data/utils/simian-2.3.33.jar +0 -0
- metadata +118 -2
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/bin/sh -e
|
2
|
+
|
3
|
+
# Script generates code duplication report for Violations or DRY Jenkins plugins.
|
4
|
+
|
5
|
+
if [[ $# < 2 ]]
|
6
|
+
then
|
7
|
+
echo "usage: $0 EXCLUDE_PATTERN OUTPUT_FILENAME"
|
8
|
+
exit 1
|
9
|
+
fi
|
10
|
+
|
11
|
+
# load variables
|
12
|
+
patterns="$1"
|
13
|
+
output="$2"
|
14
|
+
excludes=""
|
15
|
+
|
16
|
+
for pattern in $(echo ${patterns} | tr "|" "\n")
|
17
|
+
do
|
18
|
+
excludes="${excludes} -excludes=/${pattern}"
|
19
|
+
done
|
20
|
+
|
21
|
+
currentScriptDir="$(dirname "$0")"
|
22
|
+
source "${currentScriptDir}/LoadBuildEnvVars.sh"
|
23
|
+
|
24
|
+
java -jar "${currentScriptDir}/Utils/simian-2.3.33.jar" "**/*.m" "**/*.h" ${excludes} -threshold=5 -failOnDuplication- -formatter=xml:${output}
|
@@ -0,0 +1,129 @@
|
|
1
|
+
#!/usr/bin/python
|
2
|
+
|
3
|
+
# Created by Yuri Govorushchenko on 11/29/10.
|
4
|
+
# Copyright 2010 nix. All rights reserved.
|
5
|
+
|
6
|
+
import os
|
7
|
+
import sys
|
8
|
+
import optparse
|
9
|
+
import plistlib
|
10
|
+
import thread
|
11
|
+
from threading import Timer
|
12
|
+
from subprocess import Popen, PIPE
|
13
|
+
|
14
|
+
PLIST_BUILD_NUMBER_KEY = "CFBundleVersion"
|
15
|
+
DEFAULT_INCREMENT_STEP = 1
|
16
|
+
WAITING_TIME_FOR_REPOSITORY = 10.0
|
17
|
+
|
18
|
+
timer = None
|
19
|
+
|
20
|
+
def main():
|
21
|
+
parser = optparse.OptionParser(description='Script gets latest build number from repository, increments it and writes into local info plist file',
|
22
|
+
prog='IncrementBuildNumber')
|
23
|
+
|
24
|
+
parser.add_option("-f", "--plist", dest="plist_path", help="full path to project info plist file", metavar="PLIST")
|
25
|
+
parser.add_option("-u", "--username", dest="username", help="authorization username", metavar="USERNAME")
|
26
|
+
parser.add_option("-p", "--password", dest="password", help="authorization password", metavar="PASSWORD")
|
27
|
+
parser.add_option("-i", "--increment", dest="increment_step", help="increment step. Should be more than 0. Default value is 1.(optional)", metavar="INCREMENT_NUMBER")
|
28
|
+
|
29
|
+
(options, args) = parser.parse_args()
|
30
|
+
|
31
|
+
if options.plist_path is None or options.username is None or options.password is None:
|
32
|
+
parser.error('All arguments must be specified. Use option -h to see the usage.')
|
33
|
+
|
34
|
+
increment_step = DEFAULT_INCREMENT_STEP
|
35
|
+
|
36
|
+
if options.increment_step is not None:
|
37
|
+
parsed_increment_step = int(options.increment_step)
|
38
|
+
if parsed_increment_step > 1:
|
39
|
+
increment_step = parsed_increment_step
|
40
|
+
|
41
|
+
plist_path = options.plist_path
|
42
|
+
username = options.username
|
43
|
+
password = options.password
|
44
|
+
|
45
|
+
if not os.path.isfile(plist_path):
|
46
|
+
print_error('file does not exist: %s' % plist_path)
|
47
|
+
return 1
|
48
|
+
|
49
|
+
try:
|
50
|
+
head_build_number = get_head_build_number(plist_path, username, password)
|
51
|
+
write_build_number(head_build_number, plist_path)
|
52
|
+
update_file(plist_path, username, password)
|
53
|
+
write_build_number(head_build_number+increment_step, plist_path)
|
54
|
+
except Exception, e:
|
55
|
+
timer.cancel()
|
56
|
+
print_warning("Couldn't get current app build version from repository. App build version is not increased. (exception: %s)" % e)
|
57
|
+
|
58
|
+
return 0
|
59
|
+
|
60
|
+
def print_error(error_message):
|
61
|
+
""" Prints error message with predefined prefix.
|
62
|
+
|
63
|
+
Args:
|
64
|
+
error_message: Error message.
|
65
|
+
"""
|
66
|
+
|
67
|
+
XCODE_ERROR_PREFIX = 'error: ' # log messages with such prefix are highlighted in XCode as errors
|
68
|
+
|
69
|
+
print('%s%s' % (XCODE_ERROR_PREFIX, error_message))
|
70
|
+
|
71
|
+
def print_warning(warning_message):
|
72
|
+
""" Prints warning message with predefined prefix.
|
73
|
+
|
74
|
+
Args:
|
75
|
+
warning_message: Warning message.
|
76
|
+
"""
|
77
|
+
|
78
|
+
XCODE_WARNING_PREFIX = 'warning: ' # log messages with such prefix are highlighted in XCode as warning
|
79
|
+
|
80
|
+
print('%s%s' % (XCODE_WARNING_PREFIX, warning_message))
|
81
|
+
|
82
|
+
def get_head_build_number(plist_path, username, password):
|
83
|
+
url = get_svn_url_for_path(plist_path)
|
84
|
+
head_build_number = get_build_number_from_svn_plist(url, username, password)
|
85
|
+
|
86
|
+
return head_build_number
|
87
|
+
|
88
|
+
def get_svn_url_for_path(plist_path):
|
89
|
+
svn_info = Popen(["svn", "info", plist_path], stdin=PIPE, stdout=PIPE)
|
90
|
+
output = svn_info.communicate()[0]
|
91
|
+
|
92
|
+
SVN_INFO_URL_PREFIX = "URL: "
|
93
|
+
|
94
|
+
for line in output.split("\n"):
|
95
|
+
if line.startswith(SVN_INFO_URL_PREFIX):
|
96
|
+
url = line[len(SVN_INFO_URL_PREFIX):]
|
97
|
+
return url
|
98
|
+
|
99
|
+
def get_build_number_from_svn_plist(url, username, password):
|
100
|
+
svn_get = Popen(["svn", "cat", url, "--username", username, "--password", password], stdin=PIPE, stdout=PIPE)
|
101
|
+
|
102
|
+
global timer
|
103
|
+
timer = Timer(WAITING_TIME_FOR_REPOSITORY, timeout_waiting_for_repository, [svn_get])
|
104
|
+
timer.start()
|
105
|
+
|
106
|
+
output = svn_get.communicate()[0]
|
107
|
+
|
108
|
+
timer.cancel()
|
109
|
+
|
110
|
+
plist = plistlib.readPlistFromString(output)
|
111
|
+
|
112
|
+
return int(plist[PLIST_BUILD_NUMBER_KEY])
|
113
|
+
|
114
|
+
def update_file(plist_path, username, password):
|
115
|
+
plist_updating = Popen(["svn", "update", plist_path, "--username", username, "--password", password], stdin=PIPE, stdout=PIPE)
|
116
|
+
plist_updating.communicate()
|
117
|
+
|
118
|
+
def write_build_number(build_number, plist_path):
|
119
|
+
plist = plistlib.readPlist(plist_path)
|
120
|
+
plist[PLIST_BUILD_NUMBER_KEY] = str(build_number)
|
121
|
+
plistlib.writePlist(plist, plist_path)
|
122
|
+
|
123
|
+
def timeout_waiting_for_repository(svn_process):
|
124
|
+
print_warning("Timeout waiting for repository. App build version is not increased.")
|
125
|
+
|
126
|
+
svn_process.kill()
|
127
|
+
|
128
|
+
if __name__ == '__main__':
|
129
|
+
sys.exit(main())
|
@@ -0,0 +1,116 @@
|
|
1
|
+
#!/bin/sh -e
|
2
|
+
|
3
|
+
# Created by Yuri Govorushchenko on 7/5/11.
|
4
|
+
# Copyright 2010 nix. All rights reserved.
|
5
|
+
|
6
|
+
# Script loads variables specified in _last_revision.sh and _last_build_vars.sh and checks that all specified files and dirs exist.
|
7
|
+
|
8
|
+
#############
|
9
|
+
|
10
|
+
function checkFileExists {
|
11
|
+
if [ ! -f "$1" ]; then
|
12
|
+
echo "error: file '$1' must exist ($2)." 1>&2
|
13
|
+
exit 1
|
14
|
+
fi
|
15
|
+
}
|
16
|
+
|
17
|
+
function checkDirExists {
|
18
|
+
if [ ! -d "$1" ]; then
|
19
|
+
echo "error: directory '$1' must exist ($2)." 1>&2
|
20
|
+
exit 1
|
21
|
+
fi
|
22
|
+
}
|
23
|
+
|
24
|
+
function checkAppOrIPAProductExists {
|
25
|
+
if [ ! -d "${APP_PRODUCT}" ]; then
|
26
|
+
if [ ! -f "${IPA_PRODUCT}" ]; then
|
27
|
+
echo "error: app product directory '${APP_PRODUCT}' or ipa file '${IPA_PRODUCT}' must exist." 1>&2
|
28
|
+
exit 1
|
29
|
+
fi
|
30
|
+
fi
|
31
|
+
}
|
32
|
+
|
33
|
+
#############
|
34
|
+
|
35
|
+
function checkWorkingCopyIsClean {
|
36
|
+
if [ ${WORKING_COPY_IS_CLEAN} -eq 1 ]; then
|
37
|
+
echo "Working copy is clean. Continuing..."
|
38
|
+
else
|
39
|
+
echo "error: working copy must not have local modifications." 1>&2
|
40
|
+
echo "You must add following files and folders to .gitignore:"
|
41
|
+
echo "$(git status --porcelain)"
|
42
|
+
exit 1
|
43
|
+
fi
|
44
|
+
}
|
45
|
+
|
46
|
+
#############
|
47
|
+
|
48
|
+
# set some default values to vars to catch errors quickly:
|
49
|
+
REVISION="unknown_revision"
|
50
|
+
PROJECT="unknown_project"
|
51
|
+
BUILT_PRODUCTS_DIR="unknown_build_prodcuts_dir"
|
52
|
+
OBJECTS_NORMAL_DIR="unknown_objects_normal_dir"
|
53
|
+
EXECUTABLE_NAME="unknown_executable_name"
|
54
|
+
APP_PRODUCT="unknown_app_product"
|
55
|
+
IPA_PRODUCT="unknown_ipa_product"
|
56
|
+
APP_DSYM="unknown_app_dsym"
|
57
|
+
APP_INFOPLIST_FILE="unknown_app_infoplist_file"
|
58
|
+
EMBEDDED_PROFILE="unknown_embedded_profile"
|
59
|
+
TARGET_NAME="unknown_target_name"
|
60
|
+
CONFIGURATION="unknown_configuration"
|
61
|
+
SDK_NAME="unknown_sdk_name"
|
62
|
+
IPA_BUNDLE_ID="unknwon_ipa_bundle_id"
|
63
|
+
RESIGNED_BUNDLE_ID="unknown_resigned_bundle_id"
|
64
|
+
RESIGNED_BUNDLE_NAME="unknown_resigned_bundle_name"
|
65
|
+
RESIGNED_ENTITLEMENTS_PATH="unknown_resigned_entitlements_path"
|
66
|
+
NAME_FOR_DEPLOYMENT="unknown_name_for_deployment"
|
67
|
+
|
68
|
+
# these files should be already generated
|
69
|
+
LAST_REVISION_FILE="_last_revision.sh"
|
70
|
+
LAST_BUILD_VARS_FILE="_last_build_vars.sh"
|
71
|
+
|
72
|
+
checkFileExists ${LAST_REVISION_FILE}
|
73
|
+
checkFileExists ${LAST_BUILD_VARS_FILE}
|
74
|
+
|
75
|
+
source ${LAST_REVISION_FILE}
|
76
|
+
source ${LAST_BUILD_VARS_FILE}
|
77
|
+
|
78
|
+
echo "REVISION = ${REVISION}"
|
79
|
+
echo "MONOTONIC_REVISION = ${MONOTONIC_REVISION}"
|
80
|
+
echo "PROJECT = ${PROJECT}"
|
81
|
+
echo "BUILT_PRODUCTS_DIR = ${BUILT_PRODUCTS_DIR}"
|
82
|
+
echo "OBJECTS_NORMAL_DIR = ${OBJECTS_NORMAL_DIR}"
|
83
|
+
echo "EXECUTABLE_NAME = ${EXECUTABLE_NAME}"
|
84
|
+
echo "APP_PRODUCT = ${APP_PRODUCT}"
|
85
|
+
echo "IPA_PRODUCT = ${IPA_PRODUCT}"
|
86
|
+
echo "APP_DSYM = ${APP_DSYM}"
|
87
|
+
echo "APP_INFOPLIST_FILE = ${APP_INFOPLIST_FILE}"
|
88
|
+
echo "EMBEDDED_PROFILE = ${EMBEDDED_PROFILE}"
|
89
|
+
echo "TARGET_NAME = ${TARGET_NAME}"
|
90
|
+
echo "CONFIGURATION = ${CONFIGURATION}"
|
91
|
+
echo "SDK_NAME = ${SDK_NAME}"
|
92
|
+
echo "IPA_BUNDLE_ID = ${IPA_BUNDLE_ID}"
|
93
|
+
echo "RESIGNED_BUNDLE_ID = ${RESIGNED_BUNDLE_ID}"
|
94
|
+
echo "RESIGNED_BUNDLE_NAME = ${RESIGNED_BUNDLE_NAME}"
|
95
|
+
echo "RESIGNED_ENTITLEMENTS_PATH = ${RESIGNED_ENTITLEMENTS_PATH}"
|
96
|
+
echo "NAME_FOR_DEPLOYMENT = ${NAME_FOR_DEPLOYMENT}"
|
97
|
+
|
98
|
+
checkDirExists "${BUILT_PRODUCTS_DIR}" "build products dir"
|
99
|
+
checkAppOrIPAProductExists
|
100
|
+
checkFileExists "${APP_INFOPLIST_FILE}" "app info plist"
|
101
|
+
|
102
|
+
if [ -f "${EMBEDDED_PROFILE}" ]; then
|
103
|
+
# get name of embedded provisioning profile; see http://stackoverflow.com/questions/2327257/name-of-provisioning-profile-used-to-sign-an-iphone-app
|
104
|
+
EMBEDDED_PROFILE_NAME=$(security cms -D -i "${EMBEDDED_PROFILE}" > /tmp/tmp.plist && /usr/libexec/PlistBuddy -c 'Print :Name' /tmp/tmp.plist)
|
105
|
+
else
|
106
|
+
EMBEDDED_PROFILE_NAME="SIMULATOR"
|
107
|
+
fi
|
108
|
+
|
109
|
+
echo "EMBEDDED_PROFILE_NAME = ${EMBEDDED_PROFILE_NAME}"
|
110
|
+
|
111
|
+
CURRENT_APP_VERSION="`/usr/libexec/PlistBuddy -c 'Print CFBundleShortVersionString' \
|
112
|
+
"${APP_INFOPLIST_FILE}"`"
|
113
|
+
CURRENT_BUILD_VERSION=${MONOTONIC_REVISION}
|
114
|
+
|
115
|
+
echo "CURRENT_APP_VERSION = ${CURRENT_APP_VERSION}"
|
116
|
+
echo "CURRENT_BUILD_VERSION = ${CURRENT_BUILD_VERSION}"
|
data/legacy/MakeTag.sh
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
#!/bin/sh -e
|
2
|
+
|
3
|
+
# Created by Yuri Govorushchenko on 11/15/10.
|
4
|
+
# Copyright 2010 nix. All rights reserved.
|
5
|
+
|
6
|
+
# Script creates SVN/git tag
|
7
|
+
# Note that the SVN source code snapshot will be taken from the repository, not the working copy
|
8
|
+
|
9
|
+
if [[ $# < 2 ]]; then
|
10
|
+
echo "usage: $0 USERNAME PASSWORD (specify empty username and password in order to indicate that script must use default credentials)"
|
11
|
+
exit 1
|
12
|
+
fi
|
13
|
+
|
14
|
+
# load variables
|
15
|
+
username=$1
|
16
|
+
password=$2
|
17
|
+
|
18
|
+
USE_DEFAULT_CREDENTIALS=0
|
19
|
+
if [ "${username}" == "" -a "${password}" == "" ]; then
|
20
|
+
echo "--- Username and password are not specified, using default SCM credentials"
|
21
|
+
USE_DEFAULT_CREDENTIALS=1
|
22
|
+
fi
|
23
|
+
|
24
|
+
currentScriptDir=$(cd "$(dirname "$0")"; pwd)
|
25
|
+
source "${currentScriptDir}/LoadBuildEnvVars.sh"
|
26
|
+
|
27
|
+
# make sure developer tags the same source snapshot as in the working copy
|
28
|
+
checkWorkingCopyIsClean
|
29
|
+
|
30
|
+
TAG_NAME="${PROJECT}-${CURRENT_APP_VERSION}b${CURRENT_BUILD_VERSION}"
|
31
|
+
|
32
|
+
SCM_TYPE=$("${currentScriptDir}/DetectSCM.sh")
|
33
|
+
|
34
|
+
# Subversion
|
35
|
+
if [[ "${SCM_TYPE}" = "svn" ]]; then
|
36
|
+
SVN_URL="$(svn info | grep '^URL:' | sed -e 's/^URL: //')"
|
37
|
+
SVN_ROOT_URL="$(svn info | grep '^URL:' | sed -e 's/^URL: //' | (sed -e 's/\/branches\/.*//' | sed -e 's/\/trunk\/.*//'))"
|
38
|
+
TAG_DIR="${SVN_ROOT_URL}/tags/${TAG_NAME}"
|
39
|
+
|
40
|
+
echo "--- Check if tag exists at '${TAG_DIR}'"
|
41
|
+
|
42
|
+
if [ ${USE_DEFAULT_CREDENTIALS} == 0 ]; then
|
43
|
+
TAG_CONTENTS=$(svn list "${TAG_DIR}" --username="${username}" --password="${password}" 2>/dev/null || true)
|
44
|
+
else
|
45
|
+
TAG_CONTENTS=$(svn list "${TAG_DIR}" 2>/dev/null || true)
|
46
|
+
fi
|
47
|
+
|
48
|
+
if [ "${TAG_CONTENTS}" == "" ]; then
|
49
|
+
echo "--- Make tag at '${TAG_DIR}'"
|
50
|
+
|
51
|
+
if [ ${USE_DEFAULT_CREDENTIALS} == 0 ]; then
|
52
|
+
perl "${currentScriptDir}/svncopy.pl" --revision "${REVISION}" --tag --verbose "${SVN_URL}" "${TAG_DIR}" --username="${username}" --password="${password}"
|
53
|
+
else
|
54
|
+
perl "${currentScriptDir}/svncopy.pl" --revision "${REVISION}" --tag --verbose "${SVN_URL}" "${TAG_DIR}"
|
55
|
+
fi
|
56
|
+
|
57
|
+
echo "--- Tag from branch '${SVN_URL}' was created at '${TAG_DIR}'"
|
58
|
+
else
|
59
|
+
echo "--- Tag from branch '${SVN_URL}' already exists at '${TAG_DIR}'"
|
60
|
+
fi
|
61
|
+
|
62
|
+
# git
|
63
|
+
elif [[ "${SCM_TYPE}" = "git" ]]; then
|
64
|
+
GIT_ORIGINAL_REMOTE_URL="$(git remote -v | head -n1 | sed 's/.*http/http/; s/ .*//')"
|
65
|
+
GIT_ROOT_URL="$(echo $GIT_ORIGINAL_REMOTE_URL | sed 's/.*\/\///; s/ .*//')"
|
66
|
+
|
67
|
+
if [ ${USE_DEFAULT_CREDENTIALS} == 0 ]; then
|
68
|
+
# set remote url credentials
|
69
|
+
git config remote.origin.url https://${username}:${password}@${GIT_ROOT_URL}
|
70
|
+
|
71
|
+
# original username and password must be restored
|
72
|
+
trap 'git config remote.origin.url "${GIT_ORIGINAL_REMOTE_URL}"' EXIT
|
73
|
+
fi
|
74
|
+
|
75
|
+
BRANCH_NAME="$(git rev-parse --abbrev-ref HEAD)"
|
76
|
+
PROJECT_TAGS="$(git ls-remote --tags)"
|
77
|
+
|
78
|
+
if [[ "${PROJECT_TAGS}" != *"${TAG_NAME}"* ]]; then
|
79
|
+
git tag -a ${TAG_NAME} "${REVISION}" -m 'create tag ${TAG_NAME}'
|
80
|
+
git push --tags
|
81
|
+
|
82
|
+
echo "--- Tag '${TAG_NAME}' from branch '${BRANCH_NAME}' with revision '${REVISION}' was created"
|
83
|
+
else
|
84
|
+
echo "--- Tag '${TAG_NAME}' from branch '${BRANCH_NAME}' with revision '${REVISION}' already exists"
|
85
|
+
fi
|
86
|
+
|
87
|
+
# mercurial
|
88
|
+
elif [[ "${SCM_TYPE}" = "mercurial" ]]; then
|
89
|
+
echo "make tag doesn't work for mercurial"
|
90
|
+
|
91
|
+
else
|
92
|
+
echo "error: tag was not created, because script must be run from a working copy" 1>&2
|
93
|
+
exit 1
|
94
|
+
fi
|
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/bin/sh -e
|
2
|
+
|
3
|
+
# Created by Yuri Govorushchenko on 6/24/11.
|
4
|
+
# Copyright 2011 nix. All rights reserved.
|
5
|
+
|
6
|
+
# Script which saves next vars into _last_revision.sh:
|
7
|
+
# SCM revision of working copy
|
8
|
+
# "monotonic" revision (good for build numbers) of working copy
|
9
|
+
# checks if working copy is not modified
|
10
|
+
|
11
|
+
currentScriptDir=$(cd "$(dirname "$0")"; pwd)
|
12
|
+
SCM_TYPE=$("${currentScriptDir}/DetectSCM.sh")
|
13
|
+
|
14
|
+
# Subversion
|
15
|
+
if [[ "${SCM_TYPE}" = "svn" ]]; then
|
16
|
+
echo "SVN working copy detected"
|
17
|
+
CURRENT_REVISION="$(svnversion)"
|
18
|
+
CURRENT_MONOTONIC_REVISION=${CURRENT_REVISION} # SVN revision is already an incrementing number
|
19
|
+
|
20
|
+
# simply check that the SVN version is a digit
|
21
|
+
if [[ ${CURRENT_REVISION} =~ ^[0-9]+$ ]]; then
|
22
|
+
WORKING_COPY_IS_CLEAN=1
|
23
|
+
else
|
24
|
+
echo "Working copy is not clean because of svnversion returning ${CURRENT_REVISION}"
|
25
|
+
WORKING_COPY_IS_CLEAN=0
|
26
|
+
fi
|
27
|
+
|
28
|
+
# git
|
29
|
+
elif [[ "${SCM_TYPE}" = "git" ]]; then
|
30
|
+
echo "GIT working copy detected"
|
31
|
+
CURRENT_REVISION="$(git rev-parse HEAD | xargs)"
|
32
|
+
LAST_REVISION_IN_REPO="$(git rev-list --all | head -n 1 | xargs)"
|
33
|
+
|
34
|
+
if [[ $CURRENT_REVISION == $LAST_REVISION_IN_REPO ]]; then
|
35
|
+
UNLESS_STARTS_FROM=1
|
36
|
+
else
|
37
|
+
UNLESS_STARTS_FROM=2
|
38
|
+
fi
|
39
|
+
|
40
|
+
CURRENT_MONOTONIC_REVISION=$(git rev-list --all | perl -ne "print unless $UNLESS_STARTS_FROM../$CURRENT_REVISION/" | wc -l | xargs) # number of pushes before current
|
41
|
+
|
42
|
+
if [[ $UNLESS_STARTS_FROM == 1 ]]; then
|
43
|
+
CURRENT_MONOTONIC_REVISION=$(($CURRENT_MONOTONIC_REVISION + 1))
|
44
|
+
fi
|
45
|
+
|
46
|
+
STATUS="$(git status --porcelain)"
|
47
|
+
|
48
|
+
if [[ "${STATUS}" = "" ]]; then
|
49
|
+
WORKING_COPY_IS_CLEAN=1
|
50
|
+
else
|
51
|
+
# ignore changes to build folder, because it's created by Xcode before the script runs as a build phase
|
52
|
+
LINES_COUNT=$(echo "$STATUS" | wc -l)
|
53
|
+
|
54
|
+
if [ ${LINES_COUNT} != 1 ]; then
|
55
|
+
printf "Working copy is not clean because of status:\n${STATUS}"
|
56
|
+
WORKING_COPY_IS_CLEAN=0
|
57
|
+
else
|
58
|
+
MODIFIED_PATH=$(echo "$STATUS" | colrm 1 3)
|
59
|
+
WC_ROOT=$(git rev-parse --show-toplevel)
|
60
|
+
ABS_MODIFIED_PATH="${WC_ROOT}/${MODIFIED_PATH}"
|
61
|
+
|
62
|
+
# compare path to Xcode env var
|
63
|
+
if [[ "${ABS_MODIFIED_PATH}" -ef "${BUILD_ROOT}" ]]; then
|
64
|
+
WORKING_COPY_IS_CLEAN=1
|
65
|
+
else
|
66
|
+
printf "Working copy is not clean because of status:\n${STATUS}"
|
67
|
+
WORKING_COPY_IS_CLEAN=0
|
68
|
+
fi
|
69
|
+
fi
|
70
|
+
fi
|
71
|
+
|
72
|
+
# mercurial
|
73
|
+
elif [[ "${SCM_TYPE}" = "mercurial" ]]; then
|
74
|
+
echo "Mercurial working copy detected"
|
75
|
+
CURRENT_REVISION="$(hg id -i)"
|
76
|
+
CURRENT_MONOTONIC_REVISION="$(hg log --template '{rev}:{node|short} {desc|firstline} ({author})\n' | wc -l | tr -d ' ')" # number of pushes in current branch
|
77
|
+
|
78
|
+
STATUS="$(hg status)"
|
79
|
+
|
80
|
+
if [[ "${STATUS}" = "" ]]; then
|
81
|
+
WORKING_COPY_IS_CLEAN=1
|
82
|
+
else
|
83
|
+
# ignore changes to build folder, because it's created by Xcode before the script runs as a build phase
|
84
|
+
LINES_COUNT=$(echo "$STATUS" | wc -l)
|
85
|
+
|
86
|
+
if [ ${LINES_COUNT} != 1 ]; then
|
87
|
+
printf "Working copy is not clean because of status:\n${STATUS}"
|
88
|
+
WORKING_COPY_IS_CLEAN=0
|
89
|
+
else
|
90
|
+
MODIFIED_PATH=$(echo "$STATUS" | colrm 1 3)
|
91
|
+
WC_ROOT=$(git rev-parse --show-toplevel)
|
92
|
+
ABS_MODIFIED_PATH="${WC_ROOT}/${MODIFIED_PATH}"
|
93
|
+
|
94
|
+
# compare path to Xcode env var
|
95
|
+
if [[ "${ABS_MODIFIED_PATH}" -ef "${BUILD_ROOT}" ]]; then
|
96
|
+
WORKING_COPY_IS_CLEAN=1
|
97
|
+
else
|
98
|
+
printf "Working copy is not clean because of status:\n${STATUS}"
|
99
|
+
WORKING_COPY_IS_CLEAN=0
|
100
|
+
fi
|
101
|
+
fi
|
102
|
+
fi
|
103
|
+
|
104
|
+
# undefined SCM
|
105
|
+
else
|
106
|
+
echo "warning: script must be run from working copy. Revision is undefined."
|
107
|
+
|
108
|
+
CURRENT_REVISION="undefined"
|
109
|
+
CURRENT_MONOTONIC_REVISION="undefined"
|
110
|
+
WORKING_COPY_IS_CLEAN=0
|
111
|
+
fi
|
112
|
+
|
113
|
+
OUTPUT="
|
114
|
+
REVISION=\"${CURRENT_REVISION}\"
|
115
|
+
MONOTONIC_REVISION=\"${CURRENT_MONOTONIC_REVISION}\"
|
116
|
+
WORKING_COPY_IS_CLEAN=\"${WORKING_COPY_IS_CLEAN}\"
|
117
|
+
"
|
118
|
+
|
119
|
+
echo "${OUTPUT}"
|
120
|
+
echo "#!/bin/sh
|
121
|
+
### AUTOGENERATED BY SaveRevision.sh; DO NOT EDIT ###
|
122
|
+
${OUTPUT}" > _last_revision.sh
|