nixenvironment 0.0.59 → 0.0.60
Sign up to get free protection for your applications and to get access to all the features.
- 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
|