Skip to content

Commit

Permalink
Merge pull request #82 from readdle/fix-switch-pre-post-s7
Browse files Browse the repository at this point in the history
Fix switch between pre-s7 and s7 commits in repo.
  • Loading branch information
pastey authored Jul 16, 2024
2 parents 20ce589 + 9784d7d commit 3e94589
Show file tree
Hide file tree
Showing 7 changed files with 173 additions and 15 deletions.
22 changes: 21 additions & 1 deletion system7-tests/bootstrapTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#import <XCTest/XCTest.h>

#import "S7BootstrapCommand.h"
#import "S7InitCommand.h"

#import "TestReposEnvironment.h"

Expand All @@ -34,7 +35,7 @@ - (void)runBootstrap {
S7BootstrapCommand *command = [S7BootstrapCommand new];
command.runFakeFilter = YES;
const int exitCode = [command runWithArguments:@[]];
XCTAssertEqual(0, exitCode);
XCTAssertEqual(S7ExitCodeSuccess, exitCode);
}

- (BOOL)doesPostCheckoutHookContainInitCall {
Expand Down Expand Up @@ -108,5 +109,24 @@ - (void)testOnLFSRepoWithUnidentifiedPythonHooksInstalled {
});
}

- (void)testOnInitializedS7Repo {
executeInDirectory(self.env.pasteyRd2Repo.absolutePath, ^int{
S7InitCommand *command = [S7InitCommand new];
XCTAssertEqual(S7ExitCodeSuccess, [command runWithArguments:@[]]);

// drop the .s7control. Emulating the behaviour that we used to have:
// switch to a commit before s7 used to drop .s7control, but left post-checkout hook installed.
// So, this is to fix an existing bug first of all.
// And then, in theory, this is also valid if a user drops .s7control by hand.
//
XCTAssertTrue([NSFileManager.defaultManager removeItemAtPath:S7ControlFileName error:nil]);

[self runBootstrap];

XCTAssertFalse([self doesPostCheckoutHookContainInitCall]);

return S7ExitCodeSuccess;
});
}

@end
45 changes: 45 additions & 0 deletions system7-tests/integration/case-switchBetweenPreS7AndS7Commits.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/sh

git clone github/rd2 pastey/rd2

cd pastey/rd2

COMMIT_WITHOUT_S7="$(git rev-parse HEAD)"

assert s7 init
assert git add .
assert git commit -m "\"init s7\""

assert s7 add --stage Dependencies/RDPDFKit '"$S7_ROOT/github/RDPDFKit"'

git commit -m"add pdfkit subrepo"

COMMIT_WITH_S7="$(git rev-parse HEAD)"

# switch back to pre-s7 times
git checkout "$COMMIT_WITHOUT_S7"

assert test -z "$(git status --porcelain)"
grep -q "s7" .gitignore
assert test 1 -eq $?
assert test ! -f .git/hooks/post-checkout

# to s7 again
git checkout "$COMMIT_WITH_S7"

assert test -z "$(git status --porcelain)"
grep -q "s7" .gitignore
assert test 0 -eq $?
grep "s7" .git/hooks/post-checkout
assert test 0 -eq $?
# bootstrap init must not get stuck on back and forth switches
grep "init" .git/hooks/post-checkout
assert test 1 -eq $?

# and to pre-s7 one more time
git checkout "$COMMIT_WITHOUT_S7"

assert test -z "$(git status --porcelain)"
grep -q "s7" .gitignore
assert test 1 -eq $?
assert test ! -f .git/hooks/post-checkout
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/sh

git clone github/rd2 pastey/rd2

cd pastey/rd2

COMMIT_WITHOUT_S7="$(git rev-parse HEAD)"

cat <<EOT > .git/hooks/post-checkout
#!/bin/sh
echo "Git LFS was here"
EOT

assert s7 init
assert git add .
assert git commit -m "\"init s7\""

assert s7 add --stage Dependencies/RDPDFKit '"$S7_ROOT/github/RDPDFKit"'

git commit -m"add pdfkit subrepo"

COMMIT_WITH_S7="$(git rev-parse HEAD)"

# switch back to pre-s7 times
git checkout "$COMMIT_WITHOUT_S7"

assert test -z "$(git status --porcelain)"
grep -q "s7" .gitignore
assert test 1 -eq $?
grep -q -i "lfs" .git/hooks/post-checkout
assert test 0 -eq $?
grep "s7" .git/hooks/post-checkout
assert test 1 -eq $?

# to s7 again
git checkout "$COMMIT_WITH_S7"

assert test -z "$(git status --porcelain)"
grep -q "s7" .gitignore
assert test 0 -eq $?
grep -q -i "lfs" .git/hooks/post-checkout
assert test 0 -eq $?
grep "s7" .git/hooks/post-checkout
assert test 0 -eq $?
# bootstrap init must not get stuck on back and forth switches
grep "init" .git/hooks/post-checkout
assert test 1 -eq $?

# and to pre-s7 one more time
git checkout "$COMMIT_WITHOUT_S7"

assert test -z "$(git status --porcelain)"
grep -q "s7" .gitignore
assert test 1 -eq $?
grep -q -i "lfs" .git/hooks/post-checkout
assert test 0 -eq $?
grep "s7" .git/hooks/post-checkout
assert test 1 -eq $?
20 changes: 15 additions & 5 deletions system7-tests/integration/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,25 @@ setupAndRunCase() {

if [ 1 -eq $PARALLELIZE ]; then
S7_ROOT="$TEST_ROOT" sh -x "$SCRIPT_SOURCE_DIR/$CASE" >"$TEST_ROOT/log.txt" 2>&1

if [ -f "$TEST_ROOT/FAIL" ]; then
printf "${red}x${normal}"
else
printf "${green}v${normal}"
fi
else
echo
echo "$CASE"
echo "============="
S7_ROOT="$TEST_ROOT" sh -x "$SCRIPT_SOURCE_DIR/$CASE" 2>&1
echo
if [ -f "$TEST_ROOT/FAIL" ]; then
printf "❌\n"
else
printf "✅\n"
fi
fi

if [ -f "$TEST_ROOT/FAIL" ]; then
printf "${red}x${normal}"
else
printf "${green}v${normal}"
fi
}

for CASE in $TESTS_TO_RUN; do
Expand Down
26 changes: 26 additions & 0 deletions system7/Commands/S7BootstrapCommand.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ - (int)runWithArguments:(NSArray<NSString *> *)arguments {
}

- (BOOL)shouldInstallBootstrap {
if ([self isS7PostCheckoutAlreadyInstalled]) {
return NO;
}

if ([self willBootstrapConflictWithGitLFS]) {
return NO;
}
Expand All @@ -85,6 +89,28 @@ - (BOOL)shouldInstallBootstrap {
return YES;
}

- (BOOL)isS7PostCheckoutAlreadyInstalled {
if (NO == [NSFileManager.defaultManager fileExistsAtPath:@".git/hooks/post-checkout"]) {
return NO;
}

NSError *error = nil;
NSString *postCheckoutContent = [[NSString alloc] initWithContentsOfFile:@".git/hooks/post-checkout"
encoding:NSUTF8StringEncoding
error:&error];
if (nil != error) {
logError("s7 bootstrap: failed to read contents of the post-checkout hook file. Error: %s\n",
[[error description] cStringUsingEncoding:NSUTF8StringEncoding]);
return NO;
}

if ([postCheckoutContent containsString:@"s7 post-checkout"]) {
return YES;
}

return NO;
}

- (BOOL)willBootstrapConflictWithGitLFS {
NSError *error = nil;
NSString *gitattributesContent = [[NSString alloc] initWithContentsOfFile:@".gitattributes" encoding:NSUTF8StringEncoding error:&error];
Expand Down
15 changes: 7 additions & 8 deletions system7/Hooks/S7PostCheckoutHook.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "S7Diff.h"
#import "S7Utils.h"
#import "S7InitCommand.h"
#import "S7DeinitCommand.h"
#import "S7BootstrapCommand.h"
#import "S7Options.h"
#import "S7Logging.h"
Expand Down Expand Up @@ -132,14 +133,12 @@ + (int)checkoutSubreposForRepo:(GitRepository *)repo
return S7ExitCodeFileOperationFailed;
}
}
else if ([NSFileManager.defaultManager fileExistsAtPath:controlFileAbsolutePath]) {
NSError *error = nil;
if (NO == [NSFileManager.defaultManager removeItemAtPath:controlFileAbsolutePath error:&error]) {
logError("failed to remove %s. Error: %s\n",
S7ControlFileName.fileSystemRepresentation,
[[error description] cStringUsingEncoding:NSUTF8StringEncoding]);
return S7ExitCodeFileOperationFailed;
}
else {
// switch to a pre-s7 state. Let's call deinit.
// It will remove all untracked s7 system files, s7 hooks, merge driver, etc.
//
S7DeinitCommand *command = [S7DeinitCommand new];
return [command runWithArguments:@[]];
}

return S7ExitCodeSuccess;
Expand Down
2 changes: 1 addition & 1 deletion system7/git/Git.m
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ - (int)forceCheckoutLocalBranch:(NSString *)branchName revision:(NSString *)revi
// they have an easier ways than injections
// 2. anyway 'command' is then split into arguments and passed to git as an array, so git would most likely
// not accept these arguments; unless the user is super smart to build some fancy git command that allows
// exectuting different git commands (see point #1)
// executing different git commands (see point #1)
//
return [self runGitCommand:[NSString stringWithFormat:@"checkout -B %@ %@", branchName, revisions]
stdOutOutput:NULL
Expand Down

0 comments on commit 3e94589

Please sign in to comment.