refactor: remove the unused project ID

Closes #7
This commit is contained in:
jychoi4 committed 2026-11-09 13:16:00 +09:00
1 parent 916b79e5d6
commit 8cd38f5ba4
7 files changed
+17 -14

No files matched your search

+3 -3
View File
@@ -8,7 +8,7 @@ import { renderSigningEditor, signingStatus, type DeveloperCertificate, type Sig
import { setupWindowChrome } from './window-chrome';
type Project = {
schemaVersion: number; projectId: string;
schemaVersion: number;
product: { displayName: string; manufacturer: string; displayVersion: string };
sources: { alias: string }[];
files: { id: string; source: string; include: string[]; exclude: string[]; targetRelativePath: string; required: boolean }[];
@@ -174,7 +174,7 @@ function content() {
if (!doc) return '';
const p = doc.project, m = p.formats.msix, a = m.applications[0];
if (tab === 6) return renderRegistryEditor(p.registry ?? [], busy || jsonDraft !== null);
if (tab === 0) return `<div class="form-grid">${field('앱 표시명', 'product.displayName', p.product.displayName)}${field('게시자 표시명', 'product.manufacturer', p.product.manufacturer)}${field('프로젝트 ID', 'projectId', p.projectId)}${field('제품 표시 버전', 'product.displayVersion', p.product.displayVersion, '패키지의 4부분 버전과 별도로 관리합니다.')}</div><div class="callout">프로젝트에는 제품 설정을, 로컬 설정에는 이 PC의 소스·SDK 경로를 저장합니다.</div>`;
if (tab === 0) return `<div class="form-grid">${field('앱 표시명', 'product.displayName', p.product.displayName)}${field('게시자 표시명', 'product.manufacturer', p.product.manufacturer)}${field('제품 표시 버전', 'product.displayVersion', p.product.displayVersion, '패키지의 4부분 버전과 별도로 관리합니다.')}</div><div class="callout">프로젝트에는 제품 설정을, 로컬 설정에는 이 PC의 소스·SDK 경로를 저장합니다.</div>`;
if (tab === 1) return `<h3>소스 폴더</h3>${p.sources.map(s => `<div class="source-row"><div><strong>${esc(s.alias)}</strong><code>${esc(doc!.local.sources[s.alias] ?? '폴더가 연결되지 않았습니다.')}</code></div><button data-action="source:${esc(s.alias)}" ${disabled()}>폴더 선택</button></div>`).join('')}
<h3>실행 항목과 자산</h3>${a ? `<div class="form-grid">${field('실행 파일', 'formats.msix.applications.0.executable', a.executable, '소스 경로가 아닌 패키지 내부 경로입니다.')}${field('앱 ID', 'formats.msix.applications.0.id', a.id)}${field('작은 로고 · 44 × 44 PNG', 'formats.msix.applications.0.square44x44Logo', a.square44x44Logo)}${field('타일 로고 · 150 × 150 PNG', 'formats.msix.applications.0.square150x150Logo', a.square150x150Logo)}</div>` : '<p class="warning">실행 항목이 없습니다. 프로젝트 JSON에서 추가하세요.</p>'}
<h3>포함 규칙</h3><div class="rules">${p.files.map(r => `<div><strong>${esc(r.id)}</strong><code>${esc(r.source)} → ${esc(r.targetRelativePath || '/')}</code><span>포함 ${esc(r.include.join(', '))} · 제외 ${esc(r.exclude.join(', ') || '없음')}</span></div>`).join('')}</div><p class="muted">규칙·소스 alias·의존성은 아래 프로젝트 JSON에서 편집할 수 있습니다.</p>`;
@@ -227,7 +227,7 @@ function render() {
}));
root.querySelectorAll<HTMLButtonElement>('[data-location]').forEach(el => el.addEventListener('click', () => {
const path = el.dataset.location!;
tab = path.startsWith('signing') ? 3 : path.startsWith('registry') ? 6 : path.startsWith('product') || path === 'projectId' ? 0 : path.startsWith('files') || path.startsWith('sources') || path.includes('applications') ? 1 : 2;
tab = path.startsWith('signing') ? 3 : path.startsWith('registry') ? 6 : path.startsWith('product') ? 0 : path.startsWith('files') || path.startsWith('sources') || path.includes('applications') ? 1 : 2;
render(); root.querySelector<HTMLInputElement>(`[data-field="${CSS.escape(path)}"]`)?.focus();
}));
root.querySelector<HTMLInputElement>('#file-filter')?.addEventListener('change', e => { fileFilter = (e.target as HTMLInputElement).value; render(); });
-2
View File
@@ -15,7 +15,6 @@ macro_rules! model {
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct Project {
pub schema_version: u32,
pub project_id: String,
pub product: Product,
pub sources: Vec<Source>,
pub files: Vec<FileRule>,
@@ -143,7 +142,6 @@ pub fn validate(project: &Project) -> Vec<Diagnostic> {
"schemaVersion",
"v2 MSIX 프로젝트만 지원합니다. 자동 변환하지 않습니다.",
);
check(identifier(&project.project_id), "InvalidId", "projectId", "Project ID must use letters, digits, dots or hyphens.");
check(
!project.product.display_name.trim().is_empty(),
"Required",
@@ -10,7 +10,7 @@ fn new_projects_normalize_extension_and_roundtrip_local_settings_and_backups() {
assert!(serde_json::from_slice::<serde_json::Value>(&original)
.unwrap()
.get("projectId")
.is_some());
.is_none());
doc.project.product.display_name = "변경된 제품".into();
doc.local
.sources
@@ -93,7 +93,18 @@ fn no_legacy_local_fallback_and_no_overwrite_of_orphan_local_settings() {
assert!(!path.exists());
}
#[test]
fn removed_project_id_is_rejected_without_modifying_the_file() {
let temp = tempfile::tempdir().unwrap();
let doc = infra::create_project(&temp.path().join("old-field.isproj")).unwrap();
let mut value = serde_json::to_value(&doc.project).unwrap();
value["projectId"] = "legacy-id".into();
let bytes = serde_json::to_vec_pretty(&value).unwrap();
fs::write(&doc.path, &bytes).unwrap();
let error = infra::open_project(&doc.path).unwrap_err();
assert!(format!("{error:#}").contains("unknown field `projectId`"));
assert_eq!(fs::read(&doc.path).unwrap(), bytes);
}
#[test]
fn local_revision_conflicts_and_failed_backup_preserve_both_files() {
-1
View File
@@ -1,6 +1,5 @@
{
"schemaVersion": 2,
"projectId": "sample-msix-app",
"product": {
"displayName": "Sample Desktop Tool",
"manufacturer": "Example Publisher",
-4
View File
@@ -44,15 +44,11 @@
"items": {
"$ref": "#/$defs/Target"
}
},
"projectId": {
"type": "string"
}
},
"additionalProperties": false,
"required": [
"schemaVersion",
"projectId",
"product",
"sources",
"files",
-1
View File
@@ -23,7 +23,6 @@ foreach ($name in @('FixtureAlpha', 'FixtureBeta')) {
Copy-Item -LiteralPath (Join-Path $sourceRoot 'apps/desktop/src-tauri/icons/Square44x44Logo.png') -Destination (Join-Path $assetRoot 'Logo44.png')
Copy-Item -LiteralPath (Join-Path $sourceRoot 'apps/desktop/src-tauri/icons/Square150x150Logo.png') -Destination (Join-Path $assetRoot 'Logo150.png')
$project = Get-Content -Raw -Encoding UTF8 (Join-Path $sourceRoot 'fixtures/InstallerProject.isproj') | ConvertFrom-Json
$project.projectId = $name
$project.product.displayName = $name
$project.formats.msix.identity.name = "ExamplePublisher.$name"
$project.formats.msix.identity.publisher = 'CN=Example Publisher'
+1 -1
View File
@@ -165,7 +165,7 @@ def main():
rules.append({"id": "sample-assets", "source": "sample-assets", "include": ["Logo44.png", "Logo150.png"],
"exclude": [], "targetRelativePath": "Assets", "required": True})
project = {
"schemaVersion": 2, "projectId": "egbim-ism-msix-sample",
"schemaVersion": 2,
"product": {"displayName": "EG-BIM MSIX Sample", "manufacturer": props["Manufacturer"],
"displayVersion": props["ProductVersion"]},
"sources": sources, "files": rules,