Skip to content

Commit 7d604cd

Browse files
committed
feat: add support for Julia projects
1 parent d4ac83a commit 7d604cd

2 files changed

Lines changed: 212 additions & 0 deletions

File tree

src/strategies/julia.ts

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import {BaseStrategy, BuildUpdatesOptions, BaseStrategyOptions} from './base';
16+
import {Update} from '../update';
17+
import {Changelog} from '../updaters/changelog';
18+
import {ChangelogJson} from '../updaters/changelog-json';
19+
import {Version} from '../version';
20+
import {
21+
JuliaProject,
22+
parseJuliaProject,
23+
JuliaProjectToml,
24+
} from '../updaters/julia/project-toml';
25+
import {FileNotFoundError} from '../errors';
26+
import {filterCommits} from '../util/filter-commits';
27+
28+
const CHANGELOG_SECTIONS = [
29+
{type: 'feat', section: 'Features'},
30+
{type: 'fix', section: 'Bug Fixes'},
31+
{type: 'perf', section: 'Performance Improvements'},
32+
{type: 'deps', section: 'Dependencies'},
33+
{type: 'revert', section: 'Reverts'},
34+
{type: 'docs', section: 'Documentation'},
35+
{type: 'style', section: 'Styles', hidden: true},
36+
{type: 'chore', section: 'Miscellaneous Chores', hidden: true},
37+
{type: 'refactor', section: 'Code Refactoring', hidden: true},
38+
{type: 'test', section: 'Tests', hidden: true},
39+
{type: 'build', section: 'Build System', hidden: true},
40+
{type: 'ci', section: 'Continuous Integration', hidden: true},
41+
];
42+
43+
export class Julia extends BaseStrategy {
44+
constructor(options: BaseStrategyOptions) {
45+
options.changelogSections = options.changelogSections ?? CHANGELOG_SECTIONS;
46+
super(options);
47+
}
48+
49+
protected async buildUpdates(
50+
options: BuildUpdatesOptions
51+
): Promise<Update[]> {
52+
const updates: Update[] = [];
53+
const version = options.newVersion;
54+
55+
!this.skipChangelog &&
56+
updates.push({
57+
path: this.addPath(this.changelogPath),
58+
createIfMissing: true,
59+
updater: new Changelog({
60+
version,
61+
changelogEntry: options.changelogEntry,
62+
}),
63+
});
64+
65+
let parsedJuliaProject = await this.getJuliaProject(
66+
this.addPath('Project.toml')
67+
);
68+
69+
let juliaProject = parsedJuliaProject?.project;
70+
let projectName = this.component;
71+
if (juliaProject) {
72+
updates.push({
73+
path: this.addPath('Project.toml'),
74+
createIfMissing: false,
75+
updater: new JuliaProjectToml({
76+
version,
77+
}),
78+
});
79+
projectName = juliaProject.name;
80+
} else {
81+
this.logger.warn(
82+
parsedJuliaProject
83+
? 'invalid Project.toml'
84+
: `file ${this.addPath('Project.toml')} did not exist`
85+
);
86+
}
87+
88+
parsedJuliaProject = await this.getJuliaProject(
89+
this.addPath('JuliaProject.toml')
90+
);
91+
92+
93+
juliaProject = parsedJuliaProject?.project;
94+
95+
projectName = this.component;
96+
if (juliaProject) {
97+
updates.push({
98+
path: this.addPath('JuliaProject.toml'),
99+
createIfMissing: false,
100+
updater: new JuliaProjectToml({
101+
version,
102+
}),
103+
});
104+
projectName = juliaProject.name;
105+
} else {
106+
this.logger.warn(
107+
parsedJuliaProject
108+
? 'invalid JuliaProject.toml'
109+
: `file ${this.addPath('JuliaProject.toml')} did not exist`
110+
);
111+
}
112+
113+
if (!projectName) {
114+
this.logger.warn('No project/component found.');
115+
}
116+
117+
// If a machine readable changelog.json exists update it:
118+
const artifactName = projectName;
119+
if (options.commits && artifactName && !this.skipChangelog) {
120+
const commits = filterCommits(options.commits, this.changelogSections);
121+
updates.push({
122+
path: 'changelog.json',
123+
createIfMissing: false,
124+
updater: new ChangelogJson({
125+
artifactName,
126+
version,
127+
commits,
128+
language: 'JULIA',
129+
}),
130+
});
131+
}
132+
133+
return updates;
134+
}
135+
136+
private async getJuliaProject(path: string): Promise<JuliaProject | null> {
137+
try {
138+
const content = await this.github.getFileContentsOnBranch(
139+
path,
140+
this.targetBranch
141+
);
142+
return parseJuliaProject(content.parsedContent);
143+
} catch (e) {
144+
return null;
145+
}
146+
}
147+
148+
protected initialReleaseVersion(): Version {
149+
return Version.parse('0.1.0');
150+
}
151+
}

src/updaters/julia/project-toml.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2021 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import * as TOML from '@iarna/toml';
16+
import {logger as defaultLogger, Logger} from '../../util/logger';
17+
import {replaceTomlValue} from '../../util/toml-edit';
18+
import {DefaultUpdater} from '../default';
19+
20+
interface JuliaProjectContent {
21+
name: string;
22+
version: string;
23+
}
24+
25+
/**
26+
* A subset of the contents of a `pyproject.toml`
27+
*/
28+
export interface JuliaProject {
29+
project?: JuliaProjectContent;
30+
}
31+
32+
export function parseJuliaProject(content: string): JuliaProject {
33+
return TOML.parse(content) as JuliaProject;
34+
}
35+
36+
/**
37+
* Updates a pyproject.toml file
38+
*/
39+
export class JuliaProjectToml extends DefaultUpdater {
40+
/**
41+
* Given initial file contents, return updated contents.
42+
* @param {string} content The initial content
43+
* @returns {string} The updated content
44+
*/
45+
updateContent(content: string, logger: Logger = defaultLogger): string {
46+
const parsed = parseJuliaProject(content);
47+
const project = parsed.project;
48+
49+
if (!project?.version) {
50+
const msg = 'invalid file';
51+
logger.error(msg);
52+
throw new Error(msg);
53+
}
54+
55+
return replaceTomlValue(
56+
content,
57+
['version'],
58+
this.version.toString()
59+
);
60+
}
61+
}

0 commit comments

Comments
 (0)