Skip to content

Commit

Permalink
rewrite fp-ts import paths in es6 dir on post build (#33)
Browse files Browse the repository at this point in the history
* rewrite fp-ts import paths in es6 dir on post build

* use 'Eff<A>' as parameter type

* rename 'Monad' names
  • Loading branch information
StefanoMagrassi authored and gcanti committed Dec 5, 2019
1 parent 46bb471 commit b87b1d8
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 53 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"posttest": "npm run docs",
"prebuild": "rm -rf ./lib ./es6",
"build": "tsc -p ./tsconfig.build.json && tsc -p ./tsconfig.build-es6.json",
"postbuild": "ts-node scripts/rewrite-es6-paths",
"docs": "docs-ts",
"postdocs": "ts-node scripts/docs-index"
},
Expand All @@ -53,6 +54,7 @@
},
"devDependencies": {
"@types/blessed": "^0.1.8",
"@types/glob": "^7.1.1",
"@types/history": "^4.6.2",
"@types/jest": "^24.0.18",
"@types/node": "^8.10.54",
Expand All @@ -62,6 +64,7 @@
"blessed": "^0.1.81",
"docs-ts": "^0.2.0",
"fp-ts": "^2.0.2",
"glob": "^7.1.6",
"husky": "^3.0.8",
"io-ts": "^2.0.0",
"jest": "^24.9.0",
Expand Down
60 changes: 19 additions & 41 deletions scripts/docs-index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { chain, map, mapLeft, rightIO, taskify } from 'fp-ts/lib/TaskEither'
import { flow } from 'fp-ts/lib/function'
import * as TE from 'fp-ts/lib/TaskEither'
import { pipe } from 'fp-ts/lib/pipeable'
import * as fs from 'fs'
import * as path from 'path'
import { Eff, Program, run } from './program'
import { FileSystem, fileSystemNode } from './helpers/fs'
import { Logger, loggerConsole } from './helpers/logger'
import { Program, run } from './helpers/program'

const README_FILE = 'README.md'
const DOCS_INDEX_FILE = 'docs/index.md'
Expand All @@ -13,47 +12,26 @@ nav_order: 1
---
`
interface MonadProcess {
cwd: Eff<string>
}

interface MonadFileSystem {
readonly readFile: (path: string) => Eff<string>
readonly writeFile: (path: string, content: string) => Eff<void>
}
interface Capabilities extends FileSystem, Logger {}

interface Capabilities extends MonadProcess, MonadFileSystem {}
interface AppEff<A> extends Program<Capabilities, A> {}

const readFileTE = taskify<fs.PathLike, string, NodeJS.ErrnoException, string>(fs.readFile)
const writeFileTE = taskify<fs.PathLike, string, NodeJS.ErrnoException, void>(fs.writeFile)
const withHeadline = (content: string): string => `${HEADLINE}${content}`

const capabilities: Capabilities = {
cwd: rightIO(() => process.cwd()),

readFile: path =>
pipe(
readFileTE(path, 'utf8'),
mapLeft(e => e.message)
),

writeFile: flow(
writeFileTE,
mapLeft(e => e.message)
)
}

const main: Program<Capabilities, string> = C =>
const main: AppEff<void> = C =>
pipe(
C.cwd,
map(dir => [path.join(dir, README_FILE), path.join(dir, DOCS_INDEX_FILE)] as const),
chain(([input, output]) =>
pipe(
C.readFile(input),
chain(data => C.writeFile(output, `${HEADLINE}${data}`))
)
),
map(() => 'Docs index updated')
C.info(`Copy content of ${README_FILE} into ${DOCS_INDEX_FILE}...`),
TE.chain(() => C.readFile(README_FILE)),
TE.map(withHeadline),
TE.chain(content => C.writeFile(DOCS_INDEX_FILE, content)),
TE.chainFirst(() => C.log('Docs index updated'))
)

// --- Run the program
run(main(capabilities))
run(
main({
...fileSystemNode,
...loggerConsole
})
)
36 changes: 36 additions & 0 deletions scripts/helpers/fs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { mapLeft, taskify } from 'fp-ts/lib/TaskEither'
import { flow } from 'fp-ts/lib/function'
import { pipe } from 'fp-ts/lib/pipeable'
import * as fs from 'fs'
import Glob from 'glob'
import { Eff } from './program'

export interface FileSystem {
readonly readFile: (path: string) => Eff<string>
readonly writeFile: (path: string, content: string) => Eff<void>
readonly glob: (pattern: string) => Eff<string[]>
}

const readFileTE = taskify<fs.PathLike, string, NodeJS.ErrnoException, string>(fs.readFile)
const writeFileTE = taskify<fs.PathLike, string, NodeJS.ErrnoException, void>(fs.writeFile)
const globTE = taskify<string, Error, string[]>(Glob)
const toError = (e: Error): string => e.message

export const fileSystemNode: FileSystem = {
readFile: path =>
pipe(
readFileTE(path, 'utf8'),
mapLeft(toError)
),

writeFile: flow(
writeFileTE,
mapLeft(toError)
),

glob: pattern =>
pipe(
globTE(pattern),
mapLeft(toError)
)
}
13 changes: 13 additions & 0 deletions scripts/helpers/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { info, log } from 'fp-ts/lib/Console'
import { rightIO } from 'fp-ts/lib/TaskEither'
import { Eff } from './program'

export interface Logger {
readonly info: (s: string) => Eff<void>
readonly log: (s: string) => Eff<void>
}

export const loggerConsole: Logger = {
info: s => rightIO(info(`> ${s}`)),
log: s => rightIO(log(`\n> ${s}`))
}
18 changes: 9 additions & 9 deletions scripts/program.ts → scripts/helpers/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ export interface Eff<A> extends TE.TaskEither<string, A> {}

export interface Program<C, A> extends RTE.ReaderTaskEither<C, string, A> {}

export function run(te: TE.TaskEither<string, string>): void {
te()
export function run<A>(eff: Eff<A>): void {
eff()
.then(
fold(
e => {
console.error(e)

process.exitCode = 1
throw e
},
r => {
console.log(r)

_ => {
process.exitCode = 0
}
)
)
.catch(e => console.error('Unexpected error', e))
.catch(e => {
console.error('[ERROR]', e)

process.exitCode = 1
})
}
44 changes: 44 additions & 0 deletions scripts/rewrite-es6-paths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { array } from 'fp-ts/lib/Array'
import * as RTE from 'fp-ts/lib/ReaderTaskEither'
import * as TE from 'fp-ts/lib/TaskEither'
import { pipe } from 'fp-ts/lib/pipeable'
import { FileSystem, fileSystemNode } from './helpers/fs'
import { Logger, loggerConsole } from './helpers/logger'
import { Program, run } from './helpers/program'

const PATH_REGEXP = /(\s(?:from|module)\s['|"]fp-ts)\/lib\/([\w-\/]+['|"])/gm
const ES6_GLOB_PATTERN = 'es6/**/*.@(ts|js)'

const traverseRTE = array.traverse(RTE.readerTaskEither)

interface Capabilities extends FileSystem, Logger {}

interface AppEff<A> extends Program<Capabilities, A> {}

const getES6Paths: AppEff<string[]> = C => C.glob(ES6_GLOB_PATTERN)

const replacePath = (content: string): string => content.replace(PATH_REGEXP, '$1/es6/$2')

const rewritePaths = (file: string): AppEff<void> => C =>
pipe(
C.info(`Rewriting file ${file}`),
TE.chain(() => C.readFile(file)),
TE.map(replacePath),
TE.chain(content => C.writeFile(file, content))
)

const log = (s: string): AppEff<void> => C => C.log(s)

const main: AppEff<void[]> = pipe(
getES6Paths,
RTE.chain(files => traverseRTE(files, rewritePaths)),
RTE.chainFirst(() => log('ES6 import paths rewritten'))
)

// --- Run the program
run(
main({
...fileSystemNode,
...loggerConsole
})
)
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"sourceMap": false,
"declaration": true,
Expand Down

0 comments on commit b87b1d8

Please sign in to comment.