index.js 4.26 KB
Newer Older
super-lin0's avatar
super-lin0 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
const fs = require("fs-extra");
const path = require("path");
const chalk = require("chalk");
const glob = require("glob");
const exec = require("execa");
const BasicGenerator = require("../../BasicGenerator");
const filterPkg = require("./filterPkg");
const prettier = require("prettier");
const sylvanas = require("sylvanas");
const sortPackage = require("sort-package-json");
const { getFastGithub } = require("umi-utils");

function log(...args) {
  console.log(`${chalk.gray(">")}`, ...args);
}

function globList(patternList, options) {
  let fileList = [];
  patternList.forEach(pattern => {
    fileList = [...fileList, ...glob.sync(pattern, options)];
  });

  return fileList;
}

const getGithubUrl = async () => {
  const fastGithub = await getFastGithub();
  if (fastGithub === "github.com.cnpmjs.org") {
    return "https://github.com.cnpmjs.org/ant-design/ant-design-pro";
  }
  return "https://github.com/ant-design/ant-design-pro";
};

const PRO_PATH =
  process.env.INIT_CWD || process.env.npm_rootpath || process.cwd();

class AntDesignProGenerator extends BasicGenerator {
  prompting() {
    if (this.opts.args.language) {
      this.prompts = {
        language: this.opts.args.language
      };
    } else {
      const prompts = [
        {
          name: "language",
          type: "list",
          message: "Which language do you want to use?",
          choices: ["TypeScript", "JavaScript"]
        }
      ];
      return this.prompt(prompts).then(props => {
        this.prompts = props;
      });
    }
  }

  async writing() {
    const { language } = this.prompts;
    const isTypeScript = language === "TypeScript";

    const projectName = this.opts.name || this.opts.env.cwd;

    console.log(`this.opts::::${JSON.stringify(this.opts)}`);

    const projectPath = path.resolve(projectName);

    const envOptions = {
      cwd: projectPath
    };

    const githubUrl = await getGithubUrl();
    const gitArgs = [`clone`, githubUrl, `--depth=1`];

    // Set branch if provided
    if (this.opts.args.branch) {
      gitArgs.push("--branch", this.opts.args.branch);
    }

    gitArgs.push(projectName);

    // Clone remote branch
    log(`git ${gitArgs.join(" ")}`);
    await exec(`git`, gitArgs);

    const packageJsonPath = path.resolve(projectPath, "package.json");
    const pkg = require(packageJsonPath);
    // Handle js version
    if (!isTypeScript) {
      log("[Sylvanas] Prepare js environment...");
      const tsFiles = globList(["**/*.tsx", "**/*.ts"], {
        ...envOptions,
        ignore: ["**/*.d.ts"]
      });

      sylvanas(tsFiles, {
        ...envOptions,
        action: "overwrite"
      });

      log("[JS] Clean up...");
      const removeTsFiles = globList(
        ["tsconfig.json", "**/*.d.ts"],
        envOptions
      );
      removeTsFiles.forEach(filePath => {
        const targetPath = path.resolve(projectPath, filePath);
        fs.removeSync(targetPath);
      });
    }

    // copy readme
    const babelConfig = path.resolve(__dirname, "README.md");
    fs.copySync(babelConfig, path.resolve(projectPath, "README.md"));

    // gen package.json
    if (pkg["create-nemean"]) {
      const { ignoreScript = [], ignoreDependencies = [] } = pkg[
        "create-nemean"
      ];
      // filter scripts and devDependencies
      const projectPkg = {
        ...pkg,
        version: "1.0.0",
        scripts: filterPkg(pkg.scripts, ignoreScript),
        devDependencies: filterPkg(pkg.devDependencies, ignoreDependencies)
      };
      // remove create-nemean config
      delete projectPkg["create-nemean"];
      fs.writeFileSync(
        path.resolve(projectPath, "package.json"),
        // 删除一个包之后 json会多了一些空行。sortPackage 可以删除掉并且排序
        // prettier 会容忍一个空行
        prettier.format(JSON.stringify(sortPackage(projectPkg)), {
          parser: "json"
        })
      );
    }

    // Clean up useless files
    if (pkg["create-nemean"] && pkg["create-nemean"].ignore) {
      log("Clean up...");
      const ignoreFiles = pkg["create-nemean"].ignore;
      const fileList = globList(ignoreFiles, envOptions);

      fileList.forEach(filePath => {
        const targetPath = path.resolve(projectPath, filePath);
        fs.removeSync(targetPath);
      });
    }
  }
}

module.exports = AntDesignProGenerator;