Hurdle 11: Prioritizing Ports and Setting Up VCS
Previously:
Task 1: Addressing Tracking Challenges:
We can identify what files were modified by the LuMI project what was modified upstream with:
git diff --name-only upstream/main..HEAD > upstream-changes.txt
We can also use cherry
, cherry-pick -n
, and tagging to help automate staging upstream changes.
However, in order for that to work, the root of our repo must also be the same root as LuCI. So we will be renaming this repo to lumi.working
and then creating a new repo called lumi
containing our ported files.
We may need to develop our own solution to ensure commits are properly staged. In order to better enforce this, we must also protect the main branch of the lumi
repo.
For now, the tag fork
has been created on lumi
to mark the point where we forked from LuCI.
git cherry
looks like it is going to be the most useful tool for tracking changes. However, it is still limited. It tells us all of the commits that haven't been applied to our branch. It doesn't provide us with a way to mark which commits have already been reviewed.
There are 2 ways we can handle this:
- We can use
git notes
to mark commits that have been reviewed. - We can use tags to mark the last reviewed commit.
Notes seem like a decent option, but they are not as visible as tags. I think I'm going to use tags. One problem will be that these get mixed in with release tags, so we will need to use a naming convention that makes it clear these are not release tags.
- To solve this, we can use a prefix like
reviewed/
for these tags. - We can also make sure they are lightweight tags (they don't need metadata).
Though, after thinking about it and deciding on review tags, I think the simplest solution is the best one. Instead of using git cherry
and dealing with its limitations, we can just track the changes between LuCI's head and the last reviewed commit. We will also need an in-progress tag though if we do this, to denote the last commit reviewed, but not yet merged/implemented.
Task 2: Setting Up VCS
For convenience, it may be best to dump the list of commits between reviewed, in-progress, and upstream head into a file. So we don't have to run the command every time we want to see what has changed.
function Get-UnmergedCommits {
param (
[string] $Upstream = "https://github.com/openwrt/luci",
[string] $Repo = "./lumi",
[switch] $InProgress, # reviewed .. in-progress
[switch] $Pending, # in-progress .. upstream head
[switch] $Verbose
)
pushd $Repo
# ensure upstream is set
# Hack to reset $LASTEXITCODE to 0
& (Resolve-Path "$PSHome\p*w*sh*" | Where-Object {
$Path = "$_"
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
return $false
}
if ($IsWindows) {
$ext = [IO.Path]::GetExtension($Path)
$pathext = ($env:PATHEXT -split ';') -replace '^\.', ''
return $pathext -contains $ext.TrimStart('.').ToUpperInvariant()
} else {
$escapedPath = $Path.Replace("'", "''")
# Prefer bash, fallback to sh
$shell = if (Get-Command bash -ErrorAction SilentlyContinue) { "bash" } else { "sh" }
& $shell -c "test -x '$escapedPath'"
return ($LASTEXITCODE -eq 0)
}
} | Select-Object -First 1) -v | Out-Null
$remotes = @{}
git remote -v 2>$null | ForEach-Object {
if ($_ -match '^(\S+)\s+(\S+)') {
$remotes[$matches[1]] = $matches[2]
}
}
$remote = $remotes.Keys | ForEach-Object { $_ } | Where-Object {
$remotes."$_" -eq $Upstream
}
If( "$remote".Trim() -eq "" ){
$remote = "upstream"
git remote set-url $remote $Upstream 2>&1 | ForEach-Object {
If( $LASTEXITCODE -ne 0 ){
throw "$_"
}
If( $_ -is [System.Management.Automation.ErrorRecord] ) {
throw $_.Exception
}
If( $Verbose ) {
If ( $_ -is [System.Management.Automation.WarningRecord] ) {
Write-Host $_.Message -ForegroundColor Yellow
} else {
Write-Host "$Repository`: $_" -ForegroundColor DarkGray
}
}
}
}
git remote set-url upstream $Upstream
git fetch --tags
$range = if (([bool]$InProgress) -eq ([bool]$Pending)) {
"full"
} elseif ($InProgress) {
"in-progress"
} else {
"pending"
}
$reviewed = git tag --list "reviewed/*" | Select-Object -Last 1
$in_progress = git tag --list "in-progress/*" | Select-Object -Last 1
$start = if( ($range -eq "pending") -and ("$in_progress".Trim() -ne "") ) {
$in_progress
} else {
if ("$reviewed".Trim() -ne "") {
$reviewed
} else {
"fork"
}
}
$end = if( ($range -eq "in-progress") -and ("$in_progress".Trim() -ne "")) {
$in_progress
} else {
"upstream/main"
}
$commits = git rev-list --reverse "$start..$end"
$diffs = [ordered]@{}
# get the diffs
foreach ($commit in $commits) {
$diff = git show --format= --no-prefix $sha
if ("$diff".Trim() -ne "") {
$diffs[$commit] = $diff
}
}
popd
return @{
Start = $start
End = $end
Range = $range
Commits = $commits
Diffs = $diffs
}
}
This script should give me a serializable hashtable that I can write to file for roadmapping upstream changes.
Task 2: Cleaning Up My Devtools
Since my repository now has a slew of new tools, I feel a need to clean them up and organize them into their own directory. I will create a sdk
directory here and move the ~search.ps1
script into it. This will help keep the root directory clean and make it easier to develop more tools in the future.
I also need to update my scripts to accept a repo and upstream as parameters at the file level. This should be an easy fix... and done.
My 2 tools are now in the sdk
directory:
-
unmerged.ps1
: This script will help me track unmerged commits between my fork and the upstream LuCI repository. -
search.ps1
: This script will help me search through the LuCI codebase for specific patterns or files. Useful for building out the initial roadmap
Last remark for Hurdle 11: unmerged.ps1
will likely not be needed for some time.
I will continue tomorrow with Task 3: Prioritizing Ports.
Top comments (0)