Skip to content

Commit 9c49312

Browse files
committed
release version 0.0.6.1
1 parent 9fcb7c4 commit 9c49312

18 files changed

Lines changed: 284 additions & 22 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ You can download the latest pre-compiled binaries for Windows and Linux from the
4242

4343
### Windows MSI Package
4444
```powershell
45-
.\installer\build-msi.ps1 -Version "0.0.6.0" -SkipSign
45+
.\installer\build-msi.ps1 -Version "0.0.6.1" -SkipSign
4646
```
4747

4848
### Linux

docs/site/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
<!-- Hero Section -->
5959
<header class="hero" id="hero">
6060
<div class="hero-content">
61-
<div class="hero-badge">Open Source &bull; Free Forever &bull; <span id="app-version">v0.0.6.0</span></div>
61+
<div class="hero-badge">Open Source &bull; Free Forever &bull; <span id="app-version">v0.0.6.1</span></div>
6262
<h1 class="hero-title">
6363
Your Desktop.<br />
6464
<span class="gradient-text">Your Weather.</span><br>

installer/AppxManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
-->
1616
<Identity Name="47955afa-afc7-46ee-abc1-02ab2632b4ad"
1717
Publisher="CN=47955afa-afc7-46ee-abc1-02ab2632b4ad"
18-
Version="0.0.6.0"
18+
Version="0.0.6.1"
1919
ProcessorArchitecture="x64" />
2020

2121
<Properties>

installer/build-msi.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
# ============================================================================
44
# Usage:
55
# # Sign with certificate from Windows certificate store (by thumbprint):
6-
# .\installer\build-msi.ps1 -Version "0.0.5.0" -CertThumbprint "A9D97675327F7BF344BA308A357E91141A1DDE50"
6+
# .\installer\build-msi.ps1 -Version "0.0.6.1" -CertThumbprint "A9D97675327F7BF344BA308A357E91141A1DDE50"
77
#
88
# # Sign with a .pfx file:
9-
# .\installer\build-msi.ps1 -Version "0.0.5.0" -CertPath "cert.pfx" -CertPassword "pass"
9+
# .\installer\build-msi.ps1 -Version "0.0.6.1" -CertPath "cert.pfx" -CertPassword "pass"
1010
#
1111
# # Build without signing (for testing only):
12-
# .\installer\build-msi.ps1 -Version "0.0.5.0" -SkipSign
12+
# .\installer\build-msi.ps1 -Version "0.0.6.1" -SkipSign
1313
#
1414
# Prerequisites:
1515
# - Go 1.25+ with CGO enabled (for Fyne)

installer/check-versions.js

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
const fs = require('fs');
2+
const path = require('path');
3+
4+
// Check CLI arguments for update flag
5+
const shouldUpdate = process.argv.includes('--update') || process.argv.includes('-u');
6+
7+
// Resolve project root relative to this script (which is inside installer/)
8+
const projectRoot = path.resolve(__dirname, '..');
9+
const releaseFilePath = path.join(projectRoot, 'release');
10+
11+
// Helper for colors
12+
const colors = {
13+
reset: '\x1b[0m',
14+
bright: '\x1b[1m',
15+
green: '\x1b[32m',
16+
yellow: '\x1b[33m',
17+
red: '\x1b[31m',
18+
cyan: '\x1b[36m',
19+
gray: '\x1b[90m',
20+
};
21+
22+
function logInfo(msg) {
23+
console.log(`${colors.cyan}[INFO]${colors.reset} ${msg}`);
24+
}
25+
26+
function logSuccess(msg) {
27+
console.log(`${colors.green}[SUCCESS]${colors.reset} ${msg}`);
28+
}
29+
30+
function logWarning(msg) {
31+
console.log(`${colors.yellow}[WARNING]${colors.reset} ${msg}`);
32+
}
33+
34+
function logError(msg) {
35+
console.error(`${colors.red}[ERROR]${colors.reset} ${msg}`);
36+
}
37+
38+
// 1. Read release version
39+
if (!fs.existsSync(releaseFilePath)) {
40+
logError(`Release file not found at: ${releaseFilePath}`);
41+
process.exit(1);
42+
}
43+
44+
const targetVersion = fs.readFileSync(releaseFilePath, 'utf8').trim();
45+
if (!targetVersion) {
46+
logError(`Release file at ${releaseFilePath} is empty.`);
47+
process.exit(1);
48+
}
49+
50+
logInfo(`Target version from release file: ${colors.bright}${targetVersion}${colors.reset}`);
51+
if (shouldUpdate) {
52+
logWarning(`Update mode is ENABLED. Mismatching files will be automatically modified.\n`);
53+
} else {
54+
logInfo(`Running in dry-run mode. Pass ${colors.bright}--update${colors.reset} or ${colors.bright}-u${colors.reset} to apply changes.\n`);
55+
}
56+
57+
// Extract prefix to avoid matching external versions (like Windows SDK 10.0.x or Go versions)
58+
// If targetVersion is "0.0.6.1", prefix is "0.0"
59+
const segments = targetVersion.split('.');
60+
if (segments.length < 2) {
61+
logError(`Invalid version format in release file: ${targetVersion}`);
62+
process.exit(1);
63+
}
64+
const prefix = segments.slice(0, 2).join('.');
65+
const escapedPrefix = prefix.replace(/\./g, '\\.');
66+
67+
// Regex matches:
68+
// - (?<![\d.]) -> negative lookbehind to ensure version is not part of a larger number/IP/SDK version (e.g. not preceded by digit or dot)
69+
// - [vV]? -> optional 'v' or 'V' prefix
70+
// - prefix -> the major/minor prefix (e.g. 0.0)
71+
// - \.\d+(?:\.\d+)* -> dot followed by digits, optionally followed by more dot-digits
72+
// - (?![\d.]) -> negative lookahead to ensure it doesn't end with a dot or digits (part of a larger version)
73+
const versionRegex = new RegExp(`(?<![\\d.])[vV]?${escapedPrefix}\\.\\d+(?:\\.\\d+)*(?![\\d.])`, 'g');
74+
75+
logInfo(`Scanning files for version pattern matching prefix "${prefix}"...\n`);
76+
77+
// Excluded directories and file extensions
78+
const excludedDirs = new Set([
79+
'.git',
80+
'.github',
81+
'.kiro',
82+
'.vscode',
83+
'node_modules',
84+
'build',
85+
'assets',
86+
'images',
87+
'store-assets'
88+
]);
89+
90+
const excludedExtensions = new Set([
91+
'.exe',
92+
'.msi',
93+
'.msix',
94+
'.msixupload',
95+
'.syso',
96+
'.png',
97+
'.jpg',
98+
'.jpeg',
99+
'.gif',
100+
'.ico',
101+
'.pfx',
102+
'.zip',
103+
'.gz',
104+
'.tgz',
105+
'.mod', // Exclude go.mod
106+
'.sum' // Exclude go.sum
107+
]);
108+
109+
let totalFilesScanned = 0;
110+
let totalMatches = 0;
111+
let totalMismatches = 0;
112+
let totalFilesUpdated = 0;
113+
114+
function shouldScanFile(filePath, fileName) {
115+
const ext = path.extname(fileName).toLowerCase();
116+
if (excludedExtensions.has(ext)) return false;
117+
if (fileName === 'go.mod' || fileName === 'go.sum') return false;
118+
119+
// Skip binary/large files or this script itself
120+
if (fileName === 'check-versions.js') return false;
121+
122+
return true;
123+
}
124+
125+
function scanDir(dirPath) {
126+
const items = fs.readdirSync(dirPath, { withFileTypes: true });
127+
128+
for (const item of items) {
129+
const fullPath = path.join(dirPath, item.name);
130+
131+
if (item.isDirectory()) {
132+
if (excludedDirs.has(item.name)) continue;
133+
scanDir(fullPath);
134+
} else if (item.isFile()) {
135+
if (shouldScanFile(fullPath, item.name)) {
136+
checkFile(fullPath);
137+
}
138+
}
139+
}
140+
}
141+
142+
function checkFile(filePath) {
143+
totalFilesScanned++;
144+
let content;
145+
try {
146+
// Read file. If it contains null bytes, it might be binary; skip it.
147+
const buffer = fs.readFileSync(filePath);
148+
if (buffer.includes(0)) {
149+
return; // Skip binary files
150+
}
151+
content = buffer.toString('utf8');
152+
} catch (err) {
153+
// Ignore read errors
154+
return;
155+
}
156+
157+
const lines = content.split(/\r?\n/);
158+
const relativePath = path.relative(projectRoot, filePath);
159+
let filePrinted = false;
160+
let fileModified = false;
161+
162+
const updatedLines = lines.map((line, lineIndex) => {
163+
// Reset regex index for safety
164+
versionRegex.lastIndex = 0;
165+
166+
let match;
167+
let lineMatches = [];
168+
169+
while ((match = versionRegex.exec(line)) !== null) {
170+
const foundFull = match[0];
171+
// Strip 'v' or 'V' prefix to get the raw version number
172+
const foundVersion = foundFull.replace(/^[vV]/, '');
173+
174+
const isMatch = (foundVersion === targetVersion);
175+
lineMatches.push({
176+
foundFull,
177+
foundVersion,
178+
isMatch,
179+
index: match.index
180+
});
181+
}
182+
183+
if (lineMatches.length > 0) {
184+
if (!filePrinted) {
185+
console.log(`${colors.bright}${colors.cyan}./${relativePath.replace(/\\/g, '/')}${colors.reset}`);
186+
filePrinted = true;
187+
}
188+
189+
// We want to highlight the match on the line.
190+
let formattedLine = '';
191+
let lastIndex = 0;
192+
193+
lineMatches.forEach(m => {
194+
// Add part before match
195+
formattedLine += line.substring(lastIndex, m.index);
196+
197+
// Add highlighted match
198+
if (m.isMatch) {
199+
formattedLine += `${colors.green}${m.foundFull}${colors.reset}`;
200+
totalMatches++;
201+
} else {
202+
formattedLine += `${colors.red}${colors.bright}${m.foundFull}${colors.reset}`;
203+
totalMismatches++;
204+
fileModified = true;
205+
}
206+
207+
lastIndex = m.index + m.foundFull.length;
208+
});
209+
210+
formattedLine += line.substring(lastIndex);
211+
212+
// Print line info
213+
const lineNumberStr = String(lineIndex + 1).padStart(4, ' ');
214+
console.log(` ${colors.gray}${lineNumberStr}:${colors.reset} ${formattedLine.trim()}`);
215+
216+
if (shouldUpdate && fileModified) {
217+
// Replace all mismatching occurrences on the line
218+
versionRegex.lastIndex = 0;
219+
return line.replace(versionRegex, (m) => {
220+
const hasV = m.match(/^[vV]/);
221+
return (hasV ? hasV[0] : '') + targetVersion;
222+
});
223+
}
224+
}
225+
226+
return line;
227+
});
228+
229+
if (shouldUpdate && fileModified) {
230+
try {
231+
const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
232+
fs.writeFileSync(filePath, updatedLines.join(lineEnding), 'utf8');
233+
console.log(` ${colors.green}${colors.bright}[UPDATED]${colors.reset} Saved changes to ./${relativePath.replace(/\\/g, '/')}`);
234+
totalFilesUpdated++;
235+
} catch (err) {
236+
logError(`Failed to write updates to ./${relativePath.replace(/\\/g, '/')}: ${err.message}`);
237+
}
238+
}
239+
}
240+
241+
// Start scanning
242+
scanDir(projectRoot);
243+
244+
console.log('\n' + '='.repeat(60));
245+
console.log(`${colors.bright}Scan Summary:${colors.reset}`);
246+
console.log(` Total files scanned: ${totalFilesScanned}`);
247+
console.log(` Matching versions: ${colors.green}${totalMatches}${colors.reset}`);
248+
console.log(` Mismatching versions: ${totalMismatches > 0 ? colors.red + colors.bright : colors.gray}${totalMismatches}${colors.reset}`);
249+
if (shouldUpdate) {
250+
console.log(` Total files updated: ${colors.green}${totalFilesUpdated}${colors.reset}`);
251+
}
252+
console.log('='.repeat(60));
253+
254+
if (totalMismatches > 0) {
255+
if (shouldUpdate) {
256+
logSuccess(`Successfully updated all ${totalMismatches} mismatches across ${totalFilesUpdated} files.`);
257+
} else {
258+
logWarning(`Found ${totalMismatches} version strings that do not match the target version (${targetVersion}). Run with --update to fix them.`);
259+
}
260+
} else {
261+
logSuccess(`All version strings match the target version (${targetVersion})!`);
262+
}

internal/i18n/locales/de-DE.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"settings.save": "Speichern",
5454
"settings.dialog.saved": "Gespeichert",
5555
"settings.dialog.savedMsg": "Einstellungen erfolgreich gespeichert!",
56-
"settings.about.version": "**Version:** 0.0.6.0",
56+
"settings.about.version": "**Version:** 0.0.6.1",
5757
"settings.about.description": "Ein kompaktes, transparentes Zeit- und Wetter-Widget auf Ihrem Desktop.\nÜberwachen Sie bis zu 5 Städte auf einen Blick mit einer schönen, immer-oben-Überlagerung.",
5858
"settings.about.websiteLabel": "Website:",
5959
"settings.about.previewLabel": "Vorschau",

internal/i18n/locales/en-GB.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"settings.save": "Save",
5454
"settings.dialog.saved": "Saved",
5555
"settings.dialog.savedMsg": "Settings saved successfully!",
56-
"settings.about.version": "**Version:** 0.0.6.0",
56+
"settings.about.version": "**Version:** 0.0.6.1",
5757
"settings.about.description": "A compact, transparent time & weather widget that lives on your desktop.\nMonitor up to 5 cities at a glance with a beautiful, always-on-top overlay.",
5858
"settings.about.websiteLabel": "Website:",
5959
"settings.about.previewLabel": "Preview",

internal/i18n/locales/es-ES.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"settings.save": "Guardar",
5454
"settings.dialog.saved": "Guardado",
5555
"settings.dialog.savedMsg": "¡Configuración guardada correctamente!",
56-
"settings.about.version": "**Versión:** 0.0.6.0",
56+
"settings.about.version": "**Versión:** 0.0.6.1",
5757
"settings.about.description": "Un widget compacto y transparente de hora y clima en tu escritorio.\nMonitoriza hasta 5 ciudades a la vez con una superposición siempre visible.",
5858
"settings.about.websiteLabel": "Sitio web:",
5959
"settings.about.previewLabel": "Vista previa",

internal/i18n/locales/fr-FR.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"settings.save": "Enregistrer",
5454
"settings.dialog.saved": "Enregistré",
5555
"settings.dialog.savedMsg": "Paramètres enregistrés avec succès !",
56-
"settings.about.version": "**Version :** 0.0.6.0",
56+
"settings.about.version": "**Version :** 0.0.6.1",
5757
"settings.about.description": "Un widget de bureau compact et transparent affichant l'heure et la météo.\nSuivez jusqu'à 5 villes en un coup d'œil grâce à une superposition toujours visible.",
5858
"settings.about.websiteLabel": "Site web :",
5959
"settings.about.previewLabel": "Aperçu",

internal/i18n/locales/it-IT.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"settings.save": "Salva",
5454
"settings.dialog.saved": "Salvato",
5555
"settings.dialog.savedMsg": "Impostazioni salvate con successo!",
56-
"settings.about.version": "**Versione:** 0.0.6.0",
56+
"settings.about.version": "**Versione:** 0.0.6.1",
5757
"settings.about.description": "Un widget desktop compatto e trasparente per ora e meteo.\nMonitora fino a 5 città contemporaneamente con una sovrapposizione sempre visibile.",
5858
"settings.about.websiteLabel": "Sito web:",
5959
"settings.about.previewLabel": "Anteprima",

0 commit comments

Comments
 (0)