Skip to content

Commit 4ea36c7

Browse files
authored
Merge pull request #310 from patinthehat/main
Enhance Author/Vendor Github username guessing
2 parents b4f5d4a + 01d86f4 commit 4ea36c7

File tree

1 file changed

+107
-7
lines changed

1 file changed

+107
-7
lines changed

configure.php

Lines changed: 107 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -141,19 +141,119 @@ function replaceForAllOtherOSes(): array
141141
return explode(PHP_EOL, run('grep -E -r -l -i ":author|:vendor|:package|VendorName|skeleton|migration_table_name|vendor_name|vendor_slug|[email protected]" --exclude-dir=vendor ./* ./.github/* | grep -v '.basename(__FILE__)));
142142
}
143143

144+
function getGitHubApiEndpoint(string $endpoint): ?stdClass
145+
{
146+
try {
147+
$curl = curl_init("https://api.github.com/{$endpoint}");
148+
curl_setopt_array($curl, [
149+
CURLOPT_RETURNTRANSFER => true,
150+
CURLOPT_FOLLOWLOCATION => true,
151+
CURLOPT_HTTPGET => true,
152+
CURLOPT_HTTPHEADER => [
153+
'User-Agent: spatie-configure-script/1.0',
154+
],
155+
]);
156+
157+
$response = curl_exec($curl);
158+
$statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
159+
160+
curl_close($curl);
161+
162+
if ($statusCode === 200) {
163+
return json_decode($response);
164+
}
165+
} catch (Exception $e) {
166+
// ignore
167+
}
168+
169+
return null;
170+
}
171+
172+
function searchCommitsForGitHubUsername(): string
173+
{
174+
$authorName = strtolower(trim(shell_exec('git config user.name')));
175+
176+
$committersRaw = shell_exec("git log --author='@users.noreply.github.com' --pretty='%an:%ae' --reverse");
177+
$committersLines = explode("\n", $committersRaw);
178+
$committers = array_filter(array_map(function ($line) use ($authorName) {
179+
$line = trim($line);
180+
[$name, $email] = explode(':', $line) + [null, null];
181+
182+
return [
183+
'name' => $name,
184+
'email' => $email,
185+
'isMatch' => strtolower($name) === $authorName && ! str_contains($name, '[bot]'),
186+
];
187+
}, $committersLines), fn ($item) => $item['isMatch']);
188+
189+
if (empty($committers)) {
190+
return '';
191+
}
192+
193+
$firstCommitter = reset($committers);
194+
195+
return explode('@', $firstCommitter['email'])[0] ?? '';
196+
}
197+
198+
function guessGitHubUsernameUsingCli()
199+
{
200+
try {
201+
if (preg_match('/ogged in to github\.com as ([a-zA-Z-_]+).+/', shell_exec('gh auth status -h github.com 2>&1'), $matches)) {
202+
return $matches[1];
203+
}
204+
} catch (Exception $e) {
205+
// ignore
206+
}
207+
208+
return '';
209+
}
210+
211+
function guessGitHubUsername(): string
212+
{
213+
$username = searchCommitsForGitHubUsername();
214+
if (! empty($username)) {
215+
return $username;
216+
}
217+
218+
$username = guessGitHubUsernameUsingCli();
219+
if (! empty($username)) {
220+
return $username;
221+
}
222+
223+
// fall back to using the username from the git remote
224+
$remoteUrl = shell_exec('git config remote.origin.url');
225+
$remoteUrlParts = explode('/', str_replace(':', '/', trim($remoteUrl)));
226+
227+
return $remoteUrlParts[1] ?? '';
228+
}
229+
230+
function guessGitHubVendorInfo($authorName, $username): array
231+
{
232+
$remoteUrl = shell_exec('git config remote.origin.url');
233+
$remoteUrlParts = explode('/', str_replace(':', '/', trim($remoteUrl)));
234+
235+
$response = getGitHubApiEndpoint("orgs/{$remoteUrlParts[1]}");
236+
237+
if ($response === null) {
238+
return [$authorName, $username];
239+
}
240+
241+
return [$response->name ?? $authorName, $response->login ?? $username];
242+
}
243+
144244
$gitName = run('git config user.name');
145245
$authorName = ask('Author name', $gitName);
146246

147247
$gitEmail = run('git config user.email');
148248
$authorEmail = ask('Author email', $gitEmail);
249+
$authorUsername = ask('Author username', guessGitHubUsername());
250+
251+
$guessGitHubVendorInfo = guessGitHubVendorInfo($authorName, $authorUsername);
149252

150-
$usernameGuess = explode(':', run('git config remote.origin.url'))[1];
151-
$usernameGuess = dirname($usernameGuess);
152-
$usernameGuess = basename($usernameGuess);
153-
$authorUsername = ask('Author username', $usernameGuess);
253+
$vendorName = ask('Vendor name', $guessGitHubVendorInfo[0]);
254+
$vendorUsername = ask('Vendor username', $guessGitHubVendorInfo[1] ?? slugify($vendorName));
255+
$vendorSlug = slugify($vendorUsername);
154256

155-
$vendorName = ask('Vendor name', $authorUsername);
156-
$vendorSlug = slugify($vendorName);
157257
$vendorNamespace = str_replace('-', '', ucwords($vendorName));
158258
$vendorNamespace = ask('Vendor namespace', $vendorNamespace);
159259

@@ -183,7 +283,7 @@ function replaceForAllOtherOSes(): array
183283
writeln("Class name : {$className}");
184284
writeln('---');
185285
writeln('Packages & Utilities');
186-
writeln('Use Laravel/Pint : '.($useLaravelPint ? 'yes' : 'no'));
286+
writeln('Use Laravel/Pint : '.($useLaravelPint ? 'yes' : 'no'));
187287
writeln('Use Larastan/PhpStan : '.($usePhpStan ? 'yes' : 'no'));
188288
writeln('Use Dependabot : '.($useDependabot ? 'yes' : 'no'));
189289
writeln('Use Ray App : '.($useLaravelRay ? 'yes' : 'no'));

0 commit comments

Comments
 (0)