Skip to content

Commit

Permalink
Merge pull request #87 from Blissfully/fix_under_circle
Browse files Browse the repository at this point in the history
Apply Elm Format in single, dir-wide step
  • Loading branch information
dillonkearns authored Nov 27, 2018
2 parents 1155434 + 7af9f81 commit 2785c92
Show file tree
Hide file tree
Showing 16 changed files with 141 additions and 129 deletions.
15 changes: 15 additions & 0 deletions CHANGELOG-NPM-PACKAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Fixed

- `elm-format` failed to run during the code generation in some configurations.
The new solution uses [an NPM peer dependency](https://nodejs.org/en/blog/npm/peer-dependencies/)
of `elm-format`. That means that it will make you install it if it's not already
in your dependencies in your `package.json`. With that as a local dependency, we
can safely call [`npx`](https://www.npmjs.com/package/npx) to run your local
elm-format version. Note that this requires `npm >= 5.2.0`.
See [#87](https://github.com/dillonkearns/elm-graphql/pull/87) and
[#91](https://github.com/dillonkearns/elm-graphql/issues/91) for more details.
- The `elm-format` binary was previously run for each individual file asynchronously, which
could cause performance issues in some environments. Now, `elm-format` is run
as a single step on the entire generated directory after files are generated.
This is more performant and more reliable.

## [1.0.7] - 2018-11-06

### Changed
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Interface.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Interface exposing (..)
module Api.Interface exposing (placeholder)


placeholder : String
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Mutation.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Mutation exposing (..)
module Api.Mutation exposing (createComment, createPost, selection)

import Api.Interface
import Api.Object
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Object.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Object exposing (..)
module Api.Object exposing (Comment(..), Post(..))


type Comment
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Object/Comment.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Object.Comment exposing (..)
module Api.Object.Comment exposing (body, created_at, id, selection)

import Api.Interface
import Api.Object
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Object/Post.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Object.Post exposing (..)
module Api.Object.Post exposing (body, comments, id, selection, title)

import Api.Interface
import Api.Object
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Query.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Query exposing (..)
module Api.Query exposing (comments, post, posts, selection)

import Api.Interface
import Api.Object
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Scalar.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Scalar exposing (..)
module Api.Scalar exposing (Id(..))


type Id
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Subscription.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Subscription exposing (..)
module Api.Subscription exposing (commentAdded, postAdded, selection)

import Api.Interface
import Api.Object
Expand Down
2 changes: 1 addition & 1 deletion ete_tests/src/Api/Union.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
-- https://github.com/dillonkearns/elm-graphql


module Api.Union exposing (..)
module Api.Union exposing (placeholder)


placeholder : String
Expand Down
2 changes: 1 addition & 1 deletion examples/src/Github/Object/User.elm
Original file line number Diff line number Diff line change
Expand Up @@ -568,7 +568,7 @@ type alias RepositoriesContributedToOptionalArguments =
- orderBy - Ordering options for repositories returned from the connection
- isLocked - If non-null, filters repositories according to whether they have been locked
- includeUserRepositories - If true, include user repositories
- contributionTypes - If non-null, include only the specified types of contributions. The GitHub.com UI uses [COMMIT, ISSUE, PULL\_REQUEST, REPOSITORY][COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]
- contributionTypes - If non-null, include only the specified types of contributions. The GitHub.com UI uses [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]
-}
repositoriesContributedTo : (RepositoriesContributedToOptionalArguments -> RepositoriesContributedToOptionalArguments) -> SelectionSet decodesTo Github.Object.RepositoryConnection -> Field decodesTo Github.Object.User
Expand Down
121 changes: 74 additions & 47 deletions generator/src/elm-graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { GraphQLClient } from "graphql-request";
import * as http from "http";
import * as minimist from "minimist";
import * as request from "request";
import { writeFile } from "./formatted-write";
import { applyElmFormat } from "./formatted-write";
import { introspectionQuery } from "./introspection-query";
import * as glob from "glob";
import * as path from "path";
Expand All @@ -24,30 +24,6 @@ const usage = `Usage:
elm-graphql --version # print the current @dillonkearns/elm-graphql version and target elm package version
elm-graphql url [--header 'headerKey: header value'...] # you can supply multiple header args`;

function isGenerated(path: string): boolean {
return (
fs
.readFileSync(path)
.indexOf("Do not manually edit this file, it was auto-generated by") >= 0
);
}
function warnIfContainsNonGenerated(path: string): void {
const files: string[] = glob.sync(path + "/**/*.elm");
const nonGenerated = files.filter(file => !isGenerated(file));

if (nonGenerated.length > 0) {
console.log(
"@dillonkearns/elm-graphql found some files that it did not generate. Please move or delete the following files and run @dillonkearns/elm-graphql again.",
nonGenerated
);
process.exit(1);
}
}

function removeGenerated(path: string): void {
glob.sync(path + "/**/*.elm").forEach(fs.unlinkSync);
}

const targetComment = `-- Do not manually edit this file, it was auto-generated by dillonkearns/elm-graphql
-- https://github.com/dillonkearns/elm-graphql
`;
Expand Down Expand Up @@ -100,30 +76,9 @@ if (!(graphqlUrl || introspectionFile)) {
console.log(usage);
process.exit(0);
}

warnIfContainsNonGenerated(prependBasePath("/"));

const onDataAvailable = (data: {}) => {
console.log("Generating files...");
let app = Elm.Main.init({ flags: { data, baseModule } });
app.ports.generatedFiles.subscribe(function(generatedFile: any) {
removeGenerated(prependBasePath("/"));
fs.mkdirpSync(prependBasePath("InputObject"));
fs.mkdirpSync(prependBasePath("Object"));
fs.mkdirpSync(prependBasePath("Interface"));
fs.mkdirpSync(prependBasePath("Union"));
fs.mkdirpSync(prependBasePath("Enum"));
for (let key in generatedFile) {
let filePath = path.join(outputPath, key);
let value = generatedFile[key];
writeFile(filePath, targetComment + value);
}
fs.writeFileSync(
prependBasePath("elm-graphql-metadata.json"),
`{"targetElmPackageVersion": "${elmPackageVersion}", "generatedByNpmPackageVersion": "${npmPackageVersion}"}`
);
console.log("Success!");
});
};
if (introspectionFile) {
const introspectionFileJson = JSON.parse(
fs.readFileSync(introspectionFile).toString()
Expand All @@ -144,3 +99,75 @@ if (introspectionFile) {
process.exit(1);
});
}

function makeEmptyDirectories(directoryNames: string[]): void {
directoryNames.forEach(dir => {
fs.mkdirpSync(prependBasePath(dir));
});
}

function onDataAvailable(data: {}) {
console.log("Generating files...");
let app = Elm.Main.init({ flags: { data, baseModule } });
app.ports.generatedFiles.subscribe(async function(generatedFile: {
[s: string]: string;
}) {
removeGenerated(prependBasePath("/"));
makeEmptyDirectories([
"InputObject",
"Object",
"Interface",
"Union",
"Enum"
]);
await Promise.all(writeGeneratedFiles(generatedFile));
writeIntrospectionFile();
applyElmFormat(outputPath);
console.log("Success!");
});
}

function isGenerated(path: string): boolean {
return (
fs
.readFileSync(path)
.indexOf("Do not manually edit this file, it was auto-generated by") >= 0
);
}

function warnIfContainsNonGenerated(path: string): void {
const files: string[] = glob.sync(path + "/**/*.elm");
const nonGenerated = files.filter(file => !isGenerated(file));

if (nonGenerated.length > 0) {
console.log(
"@dillonkearns/elm-graphql found some files that it did not generate. Please move or delete the following files and run @dillonkearns/elm-graphql again.",
nonGenerated
);
process.exit(1);
}
}

function removeGenerated(path: string): void {
glob.sync(path + "/**/*.elm").forEach(fs.unlinkSync);
}

function writeGeneratedFiles(generatedFile: {
[s: string]: string;
}): Promise<void>[] {
return Object.entries(generatedFile).map(([fileName, fileContents]) => {
const filePath = path.join(outputPath, fileName);
const fileToWritePromise = fs.writeFile(
filePath,
targetComment + fileContents
);
return fileToWritePromise;
});
}

function writeIntrospectionFile() {
fs.writeFile(
prependBasePath("elm-graphql-metadata.json"),
`{"targetElmPackageVersion": "${elmPackageVersion}", "generatedByNpmPackageVersion": "${npmPackageVersion}"}`
);
}
60 changes: 3 additions & 57 deletions generator/src/formatted-write.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,9 @@
import { spawn } from "child_process";
import { execSync } from "child_process";
import * as fs from "fs-extra";

const globalInstallPath = `${__dirname}/../node_modules/.bin/elm-format`;
const localInstallPath = `${__dirname}/../../.bin/elm-format`;

export const writeFile = (path: string, value: string): void => {
const elmFormatPath = findElmFormatPath();

if (elmFormatPath) {
writeWithElmFormat(path, value, elmFormatPath);
} else {
writeWithoutFormatting(path, value);
}
};

const writeWithElmFormat = (
path: string,
value: string,
elmFormatPath: string
): void => {
const elmFormat = spawn(
elmFormatPath,
["--stdin", "--elm-version=0.19", "--output", path],
{
shell: true
}
);

elmFormat.stdin.write(value);
elmFormat.stdin.end();

elmFormat.stdout.on("data", data => {
console.log(data.toString());
});

elmFormat.stderr.on("data", data => {
console.log(data.toString());
});

elmFormat.on("close", code => {
if (code !== 0) {
console.log(`elm-format process exited with code ${code}.
Was attempting to write to path ${path} with contents:
${value}`);
process.exit(code);
}
});
};

const writeWithoutFormatting = (path: string, value: string) => {
fs.writeFileSync(path, value);
};

const findElmFormatPath = (): string | null => {
if (fs.existsSync(globalInstallPath)) {
return globalInstallPath;
} else if (fs.existsSync(localInstallPath)) {
return localInstallPath;
} else {
return null;
}
export const applyElmFormat = (fileOrFolderToFormat: string): void => {
execSync(`npx elm-format --elm-version=0.19 --yes ${fileOrFolderToFormat}/`);
};
Loading

0 comments on commit 2785c92

Please sign in to comment.