Skip to content

Commit ffc65ee

Browse files
committed
project level publish options
1 parent ae005b4 commit ffc65ee

File tree

10 files changed

+201
-5
lines changed

10 files changed

+201
-5
lines changed

src/command/command.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function commands(): Command<any>[] {
3030
convertCommand,
3131
checkCommand,
3232
installCommand,
33-
// publishCommand,
33+
publishCommand,
3434
capabilitiesCommand,
3535
inspectCommand,
3636
toolsCommand,

src/command/publish/cmd.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@ import { PublishOptions, PublishProvider } from "../../publish/provider.ts";
1717
import { netlifyProvider } from "../../publish/netlify/netlify.ts";
1818

1919
import { handleUnauthorized, resolveAccount } from "./account.ts";
20+
import { initYamlIntelligenceResourcesFromFilesystem } from "../../core/schema/utils.ts";
2021

2122
const kPublishProviders = [netlifyProvider];
2223

2324
export const publishCommand = withProviders(
2425
new Command()
2526
.name("publish")
27+
.hidden()
2628
.arguments("[path:string]")
2729
.option(
2830
"--no-render",
@@ -36,6 +38,9 @@ export const publishCommand = withProviders(
3638
"Publish a document or project to a variety of destinations.",
3739
// deno-lint-ignore no-explicit-any
3840
).action(async (options: any, path?: string) => {
41+
// init yaml intelligence
42+
await initYamlIntelligenceResourcesFromFilesystem();
43+
3944
// shared options
4045
const publishOptions = {
4146
path: path || Deno.cwd(),

src/project/project-context.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
kProjectOutputDir,
2525
kProjectPostRender,
2626
kProjectPreRender,
27+
kProjectPublish,
2728
kProjectRender,
2829
kProjectType,
2930
ProjectConfig,
@@ -66,6 +67,7 @@ import { gitignoreEntries } from "./project-gitignore.ts";
6667
import {
6768
ignoreFieldsForProjectType,
6869
projectConfigFile,
70+
projectPublishFile,
6971
projectVarsFile,
7072
toInputRelativePaths,
7173
} from "./project-shared.ts";
@@ -152,6 +154,14 @@ export async function projectContext(
152154
);
153155
}
154156

157+
// read publish and merge into the project
158+
const publishFile = projectPublishFile(dir);
159+
if (publishFile) {
160+
configFiles.push(publishFile);
161+
const publish = readYaml(publishFile) as Metadata;
162+
projectConfig[kProjectPublish] = publish;
163+
}
164+
155165
// resolve translations
156166
const translationFiles = await resolveLanguageTranslations(
157167
projectConfig,
@@ -384,13 +394,16 @@ export async function projectMetadataForInputFile(
384394
}
385395

386396
if (project?.dir && project?.config) {
397+
// remove 'publish' from config (its not merged)
398+
const projectConfig = ld.cloneDeep(project.config) as ProjectConfig;
399+
delete projectConfig[kProjectPublish];
387400
// If there is directory and configuration information
388401
// process paths
389402
return toInputRelativePaths(
390403
projectType(project?.config?.project?.[kProjectType]),
391404
project.dir,
392405
dirname(input),
393-
project.config,
406+
projectConfig,
394407
) as Metadata;
395408
} else {
396409
// Just return the config or empty metadata

src/project/project-shared.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ export function projectVarsFile(dir: string): string | undefined {
5151
.find(existsSync);
5252
}
5353

54+
export function projectPublishFile(dir: string): string | undefined {
55+
return ["_publish.yml", "_publish.yaml"]
56+
.map((file) => join(dir, file))
57+
.find(existsSync);
58+
}
59+
5460
export function projectOffset(context: ProjectContext, input: string) {
5561
const projDir = Deno.realPathSync(context.dir);
5662
const inputDir = Deno.realPathSync(dirname(input));

src/project/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ export const kProjectResources = "resources";
2323

2424
export const kProjectWatchInputs = "watch-inputs";
2525

26+
export const kProjectPublish = "publish";
27+
export const kProjectPublishNetlify = "netlify";
28+
2629
export interface ProjectContext {
2730
dir: string;
2831
engines: string[];
@@ -42,6 +45,10 @@ export interface ProjectContext {
4245
) => Promise<FormatExtras>;
4346
}
4447

48+
export interface ProjectPublish {
49+
netlify?: string | string[];
50+
}
51+
4552
export interface ProjectConfig {
4653
project: {
4754
[kProjectType]?: string;
@@ -54,6 +61,7 @@ export interface ProjectConfig {
5461
[kProjectResources]?: string[];
5562
preview?: ProjectPreview;
5663
};
64+
publish?: ProjectPublish;
5765
[key: string]: unknown;
5866
}
5967

src/publish/config.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* config.ts
3+
*
4+
* Copyright (C) 2022 by RStudio, PBC
5+
*
6+
*/
7+
8+
import { stringify } from "encoding/yaml.ts";
9+
10+
import { Metadata } from "../config/types.ts";
11+
import { mergeConfigs } from "../core/config.ts";
12+
import { readYaml } from "../core/yaml.ts";
13+
import { projectContext } from "../project/project-context.ts";
14+
import {
15+
projectConfigFile,
16+
projectPublishFile,
17+
} from "../project/project-shared.ts";
18+
import { ProjectContext, ProjectPublish } from "../project/types.ts";
19+
import { lines } from "../core/text.ts";
20+
21+
export async function projectPublishConfig(
22+
target: string | ProjectContext,
23+
): Promise<ProjectPublish | undefined> {
24+
let project: ProjectContext | undefined;
25+
if (typeof (target) === "string") {
26+
if (target === ".") {
27+
target = Deno.cwd();
28+
}
29+
project = await projectContext(target);
30+
} else {
31+
project = target;
32+
}
33+
return project ? project?.config?.publish : undefined;
34+
}
35+
36+
export async function updateProjectPublishConfig(
37+
projectDir: string,
38+
config: ProjectPublish,
39+
) {
40+
const publishFile = projectPublishFile(projectDir);
41+
if (publishFile) {
42+
const baseConfig = (publishFile ? readYaml(publishFile) : {}) as Metadata;
43+
const updatedConfig = mergeConfigs(baseConfig, config);
44+
Deno.writeTextFileSync(
45+
publishFile,
46+
stringifyPublishConfig(updatedConfig, 2),
47+
);
48+
} else {
49+
// read existing config and merge
50+
const baseConfig = await projectPublishConfig(projectDir) || {};
51+
const updatedConfig = mergeConfigs(baseConfig, config) as ProjectPublish;
52+
53+
// read proj config and detect indent level
54+
const projConfig = projectConfigFile(projectDir)!;
55+
const projConfigYaml = Deno.readTextFileSync(projConfig);
56+
const indent = detectIndentLevel(projConfigYaml);
57+
58+
// yaml to write
59+
const configYaml = stringifyPublishConfig(
60+
{ publish: updatedConfig },
61+
indent,
62+
);
63+
64+
// do line based scan for update
65+
const yamlLines = lines(projConfigYaml.trimEnd());
66+
const publishLine = yamlLines.findIndex((line) =>
67+
line.match(/^publish:\s*$/)
68+
);
69+
let updatedYamlLines = yamlLines;
70+
if (publishLine !== -1) {
71+
updatedYamlLines = yamlLines.slice(0, publishLine).concat(configYaml);
72+
// find the next top level key
73+
const nextKeyLine = yamlLines.slice(publishLine + 1).findIndex((line) =>
74+
line.match(/^[^ \t]/)
75+
);
76+
if (nextKeyLine !== -1) {
77+
updatedYamlLines.push(
78+
...yamlLines.slice(publishLine + 1 + nextKeyLine),
79+
);
80+
}
81+
} else {
82+
updatedYamlLines.push("");
83+
updatedYamlLines = yamlLines.concat(configYaml);
84+
}
85+
Deno.writeTextFileSync(projConfig, updatedYamlLines.join("\n"));
86+
}
87+
}
88+
89+
function stringifyPublishConfig(config: Metadata, indent: number) {
90+
return stringify(
91+
config,
92+
{
93+
indent,
94+
sortKeys: false,
95+
skipInvalid: true,
96+
},
97+
);
98+
}
99+
100+
function detectIndentLevel(yaml: string) {
101+
const spaceMatch = yaml.match(/\n(\s+)/);
102+
return spaceMatch ? spaceMatch[1].length : 2;
103+
}

src/resources/editor/tools/vs-code.mjs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16155,6 +16155,21 @@ var require_yaml_intelligence_resources = __commonJS({
1615516155
}
1615616156
}
1615716157
},
16158+
{
16159+
name: "publish",
16160+
description: "Project publishing configuration",
16161+
schema: {
16162+
object: {
16163+
properties: {
16164+
netlify: {
16165+
maybeArrayOf: "string",
16166+
description: "Published Netlify site urls"
16167+
}
16168+
},
16169+
additionalProperties: false
16170+
}
16171+
}
16172+
},
1615816173
{
1615916174
name: "website",
1616016175
description: "MISSING_DESCRIPTION",
@@ -18731,7 +18746,9 @@ var require_yaml_intelligence_resources = __commonJS({
1873118746
"Download buttons for other formats to include on navbar or sidebar\n(one or more of <code>pdf</code>, <code>epub</code>, and `docx)",
1873218747
"Download buttons for other formats to include on navbar or sidebar\n(one or more of <code>pdf</code>, <code>epub</code>, and `docx)",
1873318748
"Custom tools for navbar or sidebar",
18734-
"internal-schema-hack"
18749+
"internal-schema-hack",
18750+
"Project publishing configuration",
18751+
"Published Netlify site urls"
1873518752
],
1873618753
"schema/external-schemas.yml": [
1873718754
{

src/resources/editor/tools/yaml/web-worker.js

Lines changed: 18 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/resources/editor/tools/yaml/yaml-intelligence-resources.json

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9134,6 +9134,21 @@
91349134
}
91359135
}
91369136
},
9137+
{
9138+
"name": "publish",
9139+
"description": "Project publishing configuration",
9140+
"schema": {
9141+
"object": {
9142+
"properties": {
9143+
"netlify": {
9144+
"maybeArrayOf": "string",
9145+
"description": "Published Netlify site urls"
9146+
}
9147+
},
9148+
"additionalProperties": false
9149+
}
9150+
}
9151+
},
91379152
{
91389153
"name": "website",
91399154
"description": "MISSING_DESCRIPTION",
@@ -11710,7 +11725,9 @@
1171011725
"Download buttons for other formats to include on navbar or sidebar\n(one or more of <code>pdf</code>, <code>epub</code>, and `docx)",
1171111726
"Download buttons for other formats to include on navbar or sidebar\n(one or more of <code>pdf</code>, <code>epub</code>, and `docx)",
1171211727
"Custom tools for navbar or sidebar",
11713-
"internal-schema-hack"
11728+
"internal-schema-hack",
11729+
"Project publishing configuration",
11730+
"Published Netlify site urls"
1171411731
],
1171511732
"schema/external-schemas.yml": [
1171611733
{

src/resources/schema/project.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@
3434
schema:
3535
ref: project-preview
3636

37+
- name: publish
38+
description: Project publishing configuration
39+
schema:
40+
object:
41+
properties:
42+
netlify:
43+
maybeArrayOf: string
44+
description: Published Netlify site urls
45+
additionalProperties: false
46+
3747
- name: website
3848
description: MISSING_DESCRIPTION
3949
schema:

0 commit comments

Comments
 (0)