DEV Community

project-laguardia
project-laguardia

Posted on

LuCI on MGMT - Wk 2 - Day 08

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
Enter fullscreen mode Exit fullscreen mode

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
    }
}
Enter fullscreen mode Exit fullscreen mode

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)