Remove darcs functionality :(

2376512fc3745b47f8cb9446f92c85d3fe25488b

Tucker McKnight <tucker@pangolin.lan> | Sun Oct 12 2025

Remove darcs functionality :(

I'd like to come back to darcs later, when I've come up with a
way of making some kind of plugin system for making this work
with multiple VCSes.

In the meantime, development will be faster if I just focus
on git.
frontend/main.ts:62
Before
61
62
63
64
65
66
67
68
69
70
71
72

  const copyPull = (event) => {
    const hash = event.target.dataset.hash
    const isDarcs = event.target.dataset.vcs === "darcs"
    const copiedPrefix = isDarcs ? `darcs pull ${jsVars.baseUrl} -h ` : ""
    const originalInnerHtml = event.target.innerHTML
    const copiedAlert = document.createElement('span')
    copiedAlert.innerText = "Copied"

    navigator.clipboard.writeText(`${copiedPrefix}${hash}`).then(() => {
      event.target.parentElement.appendChild(copiedAlert)
    })
After
61
62
63


64
65
66
67
68
69
70

  const copyPull = (event) => {
    const hash = event.target.dataset.hash
⁣
⁣
    const originalInnerHtml = event.target.innerHTML
    const copiedAlert = document.createElement('span')
    copiedAlert.innerText = "Copied"

    navigator.clipboard.writeText(hash).then(() => {
      event.target.parentElement.appendChild(copiedAlert)
    })
main.ts:55
Before
After
main.ts:210
Before
209
210
211
212
213
214
215
216
217
218
219
220
221

  eleventyConfig.addAsyncFilter("getFileContents", async (repo, branch, filename) => {
    const location = getLocation(reposConfiguration, branch, repo)
    let command = ''
    const config = reposConfiguration.repos[repo]
    if (config._type === "git") {
      command = `git show ${branch}:${filename}`
    }
    else if (config._type === "darcs") {
      command = `darcs show contents ${filename}`
    }
    const res = await exec(`(cd ${location} && ${command})`)
    return res.stdout
  })
After
209
210
211

212

213




214
215

  eleventyConfig.addAsyncFilter("getFileContents", async (repo, branch, filename) => {
    const location = getLocation(reposConfiguration, branch, repo)
⁣
    const config = reposConfiguration.repos[repo]
⁣
    const command = `git show ${branch}:${filename}`
⁣
⁣
⁣
⁣
    const res = await exec(`(cd ${location} && ${command})`)
    return res.stdout
  })
main.ts:237
Before
236
237
238
239
240
241
242
243
244
245
246
247
  eleventyConfig.addAsyncFilter("getReadMe", async (repoName, branchName) => {
    const location = getLocation(reposConfiguration, branchName, repoName)
    const config = reposConfiguration.repos[repoName]
    let command = ''
    if (config._type === "git") {
      command = `git show ${branchName}:README.md`
    }
    else if (config._type === "darcs") {
      command = `darcs show contents README.md`
    }
    try {
      const res = await exec(`(cd ${location} && ${command})`)
      return res.stdout
After
236
237
238


239




240
241
  eleventyConfig.addAsyncFilter("getReadMe", async (repoName, branchName) => {
    const location = getLocation(reposConfiguration, branchName, repoName)
    const config = reposConfiguration.repos[repoName]
⁣
⁣
    const command = `git show ${branchName}:README.md`
⁣
⁣
⁣
⁣
    try {
      const res = await exec(`(cd ${location} && ${command})`)
      return res.stdout
partial_templates/main_top.njk:10
Before
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    
        window.jsVars['nav'] = {{nav | jsonStringify | safe}};
    
        window.jsVars['cloneDiv'] = `{%- if reposConfig.repos[nav.repoName]._type == "darcs" -%}{% set url = repos[nav.repoName].cloneUrl + (nav.branchName | slugify) %}
<label class="form-label">HTTPS URL</label>
<div class="input-group d-flex flex-nowrap">
  <span class="clone overflow-hidden input-group-text">
    {{ url }}
  </span>
  <button data-clone-url="{{url}}" class="btn btn-primary" id="clone-button">Copy</button>
</div>{%- elif reposConfig.repos[nav.repoName]._type == "git" -%}<label class="form-label">HTTPS URL</label>
<div class="input-group d-flex flex-nowrap">
  <span class="clone overflow-hidden input-group-text">
    {% set url = repos[nav.repoName].cloneUrl %}
    {{ url }}
  </span>
  <button data-clone-url="{{url}}" class="btn btn-primary" id="clone-button">Copy</button>
</div>
{%- endif -%}`;
    
      {% endif %}
    </script>
After
9
10
11

12
13
14






15
16
17
18

19
20
21
    
        window.jsVars['nav'] = {{nav | jsonStringify | safe}};
    
⁣
        window.jsVars['cloneDiv'] = `<label class="form-label">HTTPS URL</label>
<div class="input-group d-flex flex-nowrap">
  <span class="clone overflow-hidden input-group-text">
⁣
⁣
⁣
⁣
⁣
⁣
    {% set url = repos[nav.repoName].cloneUrl %}
    {{ url }}
  </span>
  <button data-clone-url="{{url}}" class="btn btn-primary" id="clone-button">Copy</button>
⁣
</div>`;
    
      {% endif %}
    </script>
schemas/ReposConfiguration.json:137
Before
136
137
138
139
140
141
    },
    "ReposConfiguration": {
      "additionalProperties": false,
      "description": "The ReposConfiguration object contains information about your local repositories, like their name and location on your local filesystem. Add repositories to this configuration object to make a static site for them.\n\nThis static site generator works with both git and darcs repositories. Because of the differences between these two version control systems, the configuration for them looks a little different. Both types of configuration objects can be nested underneath the  {@link  ReposConfiguration.repos }  key.\n\nYou will also need to set the  {@link  ReposConfiguration.baseUrl }  to the URL of your live website.",
      "properties": {
        "baseUrl": {
          "description": "The root URL where this website will be. E.g.: https://blog.example.com/repos. This URL will be used when a clone or pull command is being shown on your site.",
After
136
137
138
139
140
141
    },
    "ReposConfiguration": {
      "additionalProperties": false,
      "description": "The ReposConfiguration object contains information about your local repositories, like their name and location on your local filesystem. Add repositories to this configuration object to make a static site for them.\n\nYou will also need to set the  {@link  ReposConfiguration.baseUrl }  to the URL of your live website.",
      "properties": {
        "baseUrl": {
          "description": "The root URL where this website will be. E.g.: https://blog.example.com/repos. This URL will be used when a clone or pull command is being shown on your site.",
schemas/ReposConfiguration.json:149
Before
148
149
150
151
152
153
154
155
156
157
158
159
160
161
        },
        "repos": {
          "additionalProperties": {
            "anyOf": [
              {
                "$ref": "#/definitions/GitConfig"
              },
              {
                "$ref": "#/definitions/DarcsConfig"
              }
            ],
            "description": "An object containing the configuration for your repositories. Each key in this object is a repository name, and the value has several config options for that repository. The required config options describe the path to the repository and which branches should be pulled. See the specific definitions of  {@link  GitConfig }  and  {@link  DarcsConfig }  for more details about what goes in these configuration objects."
          },
          "type": "object"
        }
After
148
149
150



151




152
153
154
        },
        "repos": {
          "additionalProperties": {
⁣
⁣
⁣
            "$ref": "#/definitions/GitConfig",
⁣
⁣
⁣
⁣
            "description": "An object containing the configuration for your repositories. Each key in this object is a repository name, and the value has several config options for that repository. The required config options describe the path to the repository and which branches should be pulled. See the specific definition of  {@link  GitConfig }  for more details about what goes in these configuration objects."
          },
          "type": "object"
        }
src/configTypes.ts:40
Before
39
40
41
42
43
44
45
46
47
    * Each key in this object is a repository name, and the value has several
    * config options for that repository. The required config options describe
    * the path to the repository and which branches should be pulled. See the specific
    * definitions of {@link GitConfig} and {@link DarcsConfig} for more details
    * about what goes in these configuration objects.
    */
    [repoName: string]: GitConfig | DarcsConfig
  },
  /**
  * The root URL where this website will be. E.g.: https://blog.example.com/repos.
After
39
40
41
42
43
44
45
46
47
    * Each key in this object is a repository name, and the value has several
    * config options for that repository. The required config options describe
    * the path to the repository and which branches should be pulled. See the specific
    * definition of {@link GitConfig} for more details
    * about what goes in these configuration objects.
    */
    [repoName: string]: GitConfig
  },
  /**
  * The root URL where this website will be. E.g.: https://blog.example.com/repos.
src/repos.ts:1
Before
0
1
2
3
import {
  type DarcsConfig,
  type GitConfig,
} from './configTypes.ts'
import {type BranchInfo} from './dataTypes.ts'
After
0

1
2
import {
⁣
  type GitConfig,
} from './configTypes.ts'
import {type BranchInfo} from './dataTypes.ts'
src/repos.ts:20
Before
19
20
21
22
23
24
25
26
27
28
29
30
  }
}

const getBranchNames = (repoConfig: DarcsConfig | GitConfig): Array<string> => {
  if (repoConfig._type === 'darcs') {
    return Object.keys(repoConfig.branches)
  }
  else if (repoConfig._type === 'git') {
    return repoConfig.branchesToPull
  }
}

let cachedRepos = null
After
19
20
21
22




23
24
25
  }
}

const getBranchNames = (repoConfig: GitConfig): Array<string> => {
⁣
⁣
⁣
⁣
  return repoConfig.branchesToPull
}

⁣
let cachedRepos = null
src/vcses/darcs/helpers.ts:1
Before
0
1
2
3
export default {
    cloneUrl: (baseUrl: string, repoName: string) => {
        return `${baseUrl}/${repoName.toLowerCase().replaceAll(" ", "-")}/branches/`
    }
}
After


⁣
⁣
⁣
⁣
src/vcses/helpers.ts:1
Before
0
1
2
3
4
5
6
import gitHelpers from './git/helpers.ts'
import darcsHelpers from './darcs/helpers.ts'

export default {
    git: gitHelpers,
    darcs: darcsHelpers
}
After
0
1

2
3

4
import gitHelpers from './git/helpers.ts'

⁣
export default {
    git: gitHelpers,
⁣
}
src/vcses/operations.ts:3
Before
2
3
4
5
6
7
8
9
10
11
  getFileList as getGitFileList,
  getFileLastTouchInfo as getGitFileLastTouchInfo,
} from './git/operations.ts'
import {
  getBranchInfo as getDarcsBranchInfo,
  getFileList as getDarcsFileList,
  getFileLastTouchInfo as getDarcsFileLastTouchInfo,
} from './darcs/operations.ts'
import {type BranchInfo} from '../dataTypes.ts'

type RepoOperationsType = {
After
2
3
4





5
6
  getFileList as getGitFileList,
  getFileLastTouchInfo as getGitFileLastTouchInfo,
} from './git/operations.ts'
⁣
⁣
⁣
⁣
⁣
import {type BranchInfo} from '../dataTypes.ts'

type RepoOperationsType = {
src/vcses/operations.ts:24
Before
23
24
25
26
27
28
29
30
31
32
    getFileList: getGitFileList,
    getFileLastTouchInfo: getGitFileLastTouchInfo,
  },
  darcs: {
    getBranchInfo: getDarcsBranchInfo,
    getFileList: getDarcsFileList,
    getFileLastTouchInfo: getDarcsFileLastTouchInfo,
  }
}

export default repoOperations
After
23
24
25




26
27
    getFileList: getGitFileList,
    getFileLastTouchInfo: getGitFileLastTouchInfo,
  },
⁣
⁣
⁣
⁣
}

⁣
export default repoOperations
templates/patch.njk:10
Before
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  <div class="row">
    <div class="col-auto">
      <p class="font-monospace fw-bold text-secondary">{{patchInfo.patch.hash}}</p>
      {% if reposConfig.repos[patchInfo.repoName]._type == "darcs" %}
      <div class="input-group mb-3 d-flex flex-nowrap">
        <span id="clone-command" class="clone input-group-text overflow-hidden">
          {% set url = [reposConfig.baseUrl, reposPath, "/", patchInfo.repoName | slugify, "/branches/", patchInfo.branchName | slugify] | join | url %}
          darcs pull {{ url }} -h {{patchInfo.patch.hash}}
        </span>
        <button class="btn btn-primary" id="clone-button" onclick="copyCommand()">Copy</button>
      </div>
      {% endif %}
    </div>
  </div>
</div>
After
9
10
11









12
13
  <div class="row">
    <div class="col-auto">
      <p class="font-monospace fw-bold text-secondary">{{patchInfo.patch.hash}}</p>
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
    </div>
  </div>
</div>
templates/repo.njk:24
Before
23
24
25
26
27
28
29
30
31
32
33
34
35
36
            <p class="card-text">{{patch.description | truncate(150)}}</p>
          </div>
          <div class="card-footer">
            {% if reposConfig.repos[branch.repoName]._type == "darcs" %}
            <button data-hash="{{patch.hash}}" data-vcs="darcs" class="copy-btn btn btn-sm btn-outline-primary ms-2">
              <i class="bi-copy bi me-1"></i>darcs pull {{patch.hash | truncate(6, true, "")}}
            </button>
            {% elif reposConfig.repos[branch.repoName]._type == "git" %}
            <button data-hash="{{patch.hash}}" data-vcs="git" class="copy-btn btn btn-sm btn-outline-primary">
              {{patch.hash | truncate(8, true, "")}} <i class="bi-copy bi me-1"></i>
            </button>
            {% endif %}
          </div>
        </div>
        {% endfor %}
After
23
24
25





26
27
28

29
30
            <p class="card-text">{{patch.description | truncate(150)}}</p>
          </div>
          <div class="card-footer">
⁣
⁣
⁣
⁣
⁣
            <button data-hash="{{patch.hash}}" data-vcs="git" class="copy-btn btn btn-sm btn-outline-primary">
              {{patch.hash | truncate(8, true, "")}} <i class="bi-copy bi me-1"></i>
            </button>
⁣
          </div>
        </div>
        {% endfor %}