Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add optional --fix-content-type TDE-859 #655

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,14 @@ list s3://linz-imagery/sample --include ".*.tiff$" --exclude "BG33.tiff$" --out

### `pretty-print`

Format all JSON files within a directory using `prettier`.
Format all JSON files within a directory using `prettier`. An optional flag `--fix-content-type` allows to set the content-type for s3 object with a value depending on the STAC object type.

#### Example

- Format and overwrite files:

```bash
pretty-print source/
pretty-print source/ [--fix-content-type]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The flag should be before the directory.

```

- Create a copy of the formatted file in another flatten directory (testing only - does not handle duplicate filenames):
Expand Down
17 changes: 17 additions & 0 deletions src/commands/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,20 @@ export function parseSize(size: string): number {
if (isNaN(fileSize)) throw new Error(`Failed to parse: ${size} as a file size`);
return Math.round(fileSize);
}

/**
* Guess the content type of a STAC file
*
* - application/geo+json - A STAC Item
* - application/json - A STAC Catalog
* - application/json - A STAC Collection
*
* Assumes anything ending with '.json' is a stac item
* @see {@link https://github.com/radiantearth/stac-spec/blob/master/catalog-spec/catalog-spec.md#stac-media-types}
*/
export function guessStacContentType(path: string): string | undefined {
if (path.endsWith('collection.json')) return 'application/json';
if (path.endsWith('catalog.json')) return 'application/json';
if (path.endsWith('.json')) return 'application/geo+json';
return;
}
22 changes: 16 additions & 6 deletions src/commands/format/pretty.print.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { fsa } from '@chunkd/fs';
import { command, option, optional, positional, string } from 'cmd-ts';
import { boolean, command, flag, option, optional, positional, string } from 'cmd-ts';
import { basename } from 'path';
import prettier from 'prettier';

import { CliInfo } from '../../cli.info.js';
import { logger } from '../../log.js';
import { getFiles } from '../../utils/chunk.js';
import { DEFAULT_PRETTIER_FORMAT } from '../../utils/config.js';
import { config, registerCli, verbose } from '../common.js';
import { config, guessStacContentType, registerCli, verbose } from '../common.js';

function isJson(x: string): boolean {
const search = x.toLowerCase();
Expand All @@ -16,7 +16,7 @@ function isJson(x: string): boolean {

export const commandPrettyPrint = command({
name: 'pretty-print',
description: 'Pretty print JSON files',
description: 'Pretty-print JSON files',
version: CliInfo.version,
args: {
config,
Expand All @@ -26,6 +26,13 @@ export const commandPrettyPrint = command({
long: 'target',
description: 'Use if files have to be saved somewhere else instead of overwriting the source (testing)',
}),
fixContentType: flag({
type: boolean,
defaultValue: () => false,
long: 'fix-content-type',
description: 'Append a guessed content-type to the S3 object.',
defaultValueIsSerializable: true,
}),
path: positional({ type: string, displayName: 'path', description: 'Path of the files to pretty print' }),
},

Expand All @@ -45,7 +52,7 @@ export const commandPrettyPrint = command({
if (jsonFiles[0]) await fsa.head(jsonFiles[0]);

// format files
await Promise.all(jsonFiles.map((f: string) => formatFile(f, args.target)));
await Promise.all(jsonFiles.map((f: string) => formatFile(f, args.target, args.fixContentType)));
logger.info({ fileCount: jsonFiles.length, duration: performance.now() - startTime }, 'PrettyPrint:Done');
},
});
Expand All @@ -55,16 +62,19 @@ export const commandPrettyPrint = command({
*
* @param path of the file to format
* @param target where to save the output. If not specified, overwrite the original file.
* @param fixContentType if true will set the `contentType` with a guessed value. @see guessStacContentType
*/
export async function formatFile(path: string, target = ''): Promise<void> {
export async function formatFile(path: string, target = '', fixContentType: boolean = false): Promise<void> {
logger.debug({ file: path }, 'PrettyPrint:RunPrettier');
const prettyPrinted = await prettyPrint(JSON.stringify(await fsa.readJson(path)), DEFAULT_PRETTIER_FORMAT);
if (target) {
// FIXME: can be duplicate files
path = fsa.join(target, basename(path));
}
let meta = {};
if (fixContentType) meta = { contentType: guessStacContentType(path) };

fsa.write(path, Buffer.from(prettyPrinted));
fsa.write(path, Buffer.from(prettyPrinted), meta);
}

/**
Expand Down
19 changes: 1 addition & 18 deletions src/commands/stac-sync/stac.sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { createHash } from 'crypto';

import { CliInfo } from '../../cli.info.js';
import { logger } from '../../log.js';
import { config, registerCli, verbose } from '../common.js';
import { config, guessStacContentType, registerCli, verbose } from '../common.js';

const S3Path: Type<string, URL> = {
async from(str) {
Expand Down Expand Up @@ -85,20 +85,3 @@ export async function uploadFileToS3(sourceFileInfo: FileInfo, path: URL): Promi
logger.debug({ path: path.href }, 'StacSync:FileUploaded');
return true;
}

/**
* Guess the content type of a STAC file
*
* - application/geo+json - A STAC Item
* - application/json - A STAC Catalog
* - application/json - A STAC Collection
*
* Assumes anything ending with '.json' is a stac item
* @see {@link https://github.com/radiantearth/stac-spec/blob/master/catalog-spec/catalog-spec.md#stac-media-types}
*/
function guessStacContentType(path: string): string | undefined {
if (path.endsWith('collection.json')) return 'application/json';
if (path.endsWith('catalog.json')) return 'application/json';
if (path.endsWith('.json')) return 'application/geo+json';
return;
}