コード例 #1
0
 async _getDBFlagsAndDirForSrc(
   src: string,
   compilationDBFile: ?NuclideUri,
 ): Promise<{
   dbFlags: ?Map<string, ClangFlags>,
   dbDir: ?string,
 }> {
   let dbFlags = null;
   let dbDir = null;
   if (compilationDBFile != null) {
     // Look for a compilation database provided by the client.
     dbFlags = await this._loadFlagsFromCompilationDatabase(compilationDBFile);
     dbDir = nuclideUri.dirname(compilationDBFile);
   } else {
     // Look for a manually provided compilation database.
     dbDir = await fsPromise.findNearestFile(
       COMPILATION_DATABASE_FILE,
       nuclideUri.dirname(src),
     );
     if (dbDir != null) {
       const dbFile = nuclideUri.join(dbDir, COMPILATION_DATABASE_FILE);
       dbFlags = await this._loadFlagsFromCompilationDatabase(dbFile);
     }
   }
   return {dbFlags, dbDir};
 }
コード例 #2
0
async function handleNodeModule(
  root: NuclideUri,
  packageJsonFile: string,
  exportCache: ExportCache,
): Promise<?ExportUpdateForFile> {
  const file = nuclideUri.join(root, packageJsonFile);
  try {
    const fileContents = await fsPromise.readFile(file, 'utf8');
    const packageJson = JSON.parse(fileContents);
    const entryPoint = require.resolve(
      nuclideUri.join(nuclideUri.dirname(file), packageJson.main || ''),
    );
    const entryContents = await fsPromise.readFile(entryPoint, 'utf8');
    const sha1 = crypto
      .createHash('sha1')
      .update(entryContents)
      .digest('hex');
    const cachedUpdate = exportCache.get({filePath: entryPoint, sha1});
    if (cachedUpdate != null) {
      return {
        updateType: 'setExports',
        file: entryPoint,
        sha1,
        exports: cachedUpdate,
      };
    }
    // TODO(hansonw): How do we handle haste modules inside Node modules?
    // For now we'll just treat them as usual.
    const update = await getExportsForFile(
      entryPoint,
      {
        isHaste: false,
        useNameReducers: false,
        nameReducers: [],
        nameReducerBlacklist: [],
        nameReducerWhitelist: [],
      },
      entryContents,
    );
    return update
      ? decorateExportUpdateWithMainDirectory(
          update,
          nuclideUri.join(root, nuclideUri.dirname(packageJsonFile)),
        )
      : update;
  } catch (error) {
    // Some modules just can't be required; that's perfectly normal.
    if (error.code !== 'MODULE_NOT_FOUND') {
      logger.warn(`Couldn't index ${file}`, error);
    }
    return null;
  }
}
コード例 #3
0
async function canFindFlow(flowPath: string): Promise<boolean> {
  if (process.platform === 'win32') {
    // On Windows, if the flow path is configured as a full path rather than just "flow" or
    // "flow.exe", format the path correctly to pass to `where <flow>`
    const dirPath = nuclideUri.dirname(flowPath);
    if (dirPath != null && dirPath !== '' && dirPath !== '.') {
      const whichPath = `${nuclideUri.dirname(flowPath)}:${nuclideUri.basename(flowPath)}`;
      return (await which(whichPath)) != null;
    }
  }

  return (await which(flowPath)) != null;
}
コード例 #4
0
ファイル: hhvmDebugger.js プロジェクト: JoelMarcey/nuclide
  async _launchTargetInTerminal(requestMessage: launchRequest): Promise<void> {
    const launchConfig: HHVMLaunchConfig = requestMessage.arguments;
    // This is a launch in terminal request. Perform the launch and then
    // return an attach configuration.
    const startupArgs = await getLaunchArgs(launchConfig);

    // Terminal args require everything to be a string, but debug port
    // is typed as a number.
    const terminalArgs = [startupArgs.hhvmPath];
    for (const arg of startupArgs.hhvmArgs) {
      terminalArgs.push(String(arg));
    }
    const runInTerminalArgs: DebugProtocol.RunInTerminalRequestArguments = {
      kind: 'integrated',
      cwd: nuclideUri.dirname(launchConfig.targetUri),
      args: terminalArgs,
    };

    this._writeOutputWithHeader({
      seq: ++this._sequenceNumber,
      type: 'request',
      command: 'runInTerminal',
      arguments: runInTerminalArgs,
    });
    this._runInTerminalRequest = new Deferred();
    await this._runInTerminalRequest.promise;

    const attachConfig: HHVMAttachConfig = {
      targetUri: launchConfig.targetUri,
      action: 'attach',
      debugPort: startupArgs.debugPort,
    };
    await this._attachTarget({...requestMessage, arguments: attachConfig});
  }
コード例 #5
0
ファイル: PythonService.js プロジェクト: JoelMarcey/nuclide
async function runLinterCommand(src: NuclideUri): Promise<string> {
  const dirName = nuclideUri.dirname(src);

  let result;
  let runFlake8;
  try {
    // $FlowFB
    runFlake8 = require('./fb/run-flake8').default;
  } catch (e) {
    // Ignore.
  }

  if (runFlake8 != null) {
    result = await runFlake8(src);
    if (result != null) {
      return result;
    }
  }

  const command =
    (global.atom && atom.config.get('nuclide.nuclide-python.pathToFlake8')) ||
    'flake8';

  invariant(typeof command === 'string');
  return runCommand(command, [src], {
    cwd: dirName,
    // 1 indicates unclean lint result (i.e. has errors/warnings).
    isExitError: exit => exit.exitCode == null || exit.exitCode > 1,
  }).toPromise();
}
コード例 #6
0
function getTopLevelModulePath(src: string): Promise<?string> {
  return fsPromise.findFurthestFile(
    '__init__.py',
    nuclideUri.dirname(src),
    true /* stopOnMissing */,
  );
}
コード例 #7
0
ファイル: utils.js プロジェクト: ev1stensberg/nuclide
function processGrepResult(
  result: string,
  headerFile: string,
  includeRegex: RegExp,
): ?string {
  const splitIndex = result.indexOf('\0');
  if (splitIndex === -1) {
    return null;
  }
  const filename = result.substr(0, splitIndex);
  if (!isSourceFile(filename)) {
    return null;
  }
  const match = includeRegex.exec(result.substr(splitIndex + 1));
  if (match == null) {
    return null;
  }
  // Source-relative includes have to be verified.
  // Relative paths will match the (../)* rule (at index 2).
  if (match[2] != null) {
    const includePath = nuclideUri.normalize(
      nuclideUri.join(nuclideUri.dirname(filename), match[1]),
    );
    if (includePath !== headerFile) {
      return null;
    }
  }
  return filename;
}
コード例 #8
0
ファイル: RpcProcess-spec.js プロジェクト: JoelMarcey/nuclide
  beforeEach(() => {
    const PROCESS_PATH = nuclideUri.join(
      __dirname,
      'fixtures/dummy-service/dummyioserver.py',
    );
    const OPTS = {
      cwd: nuclideUri.dirname(PROCESS_PATH),
      stdio: 'pipe',
      detached: false,
    };

    const serviceRegistry = new ServiceRegistry(
      [],
      [
        {
          name: 'dummy',
          definition: nuclideUri.join(
            __dirname,
            'fixtures/dummy-service/DummyService.js',
          ),
          implementation: nuclideUri.join(
            __dirname,
            'fixtures/dummy-service/DummyService.js',
          ),
          preserveFunctionNames: true,
        },
      ],
    );

    const processStream = spawn('python', [PROCESS_PATH], OPTS)
      // For the sake of our tests, simulate creating the process asynchronously.
      .subscribeOn(Scheduler.async);
    server = new RpcProcess('Dummy IO Server', serviceRegistry, processStream);
  });
コード例 #9
0
ファイル: fs.js プロジェクト: JoelMarcey/nuclide
/**
 * Simultaneously looks at directories between `startDir` and `stopDir` (or root dir),
 * passing them to the provided `matcher` function and returning the string returned
 * by the logically first (nearest) matcher, or `null` if no matchers matched.
 * @param matcher: a function that returns the matched path if a match is found; otherwise null
 * @param startDir: Where to begin the search
 * @param stopDir: Where to stop the search (e.g., repository root), or null for filesystem root
 * @return the nearest matched path to startDir if a match is found; otherwise null
 */
async function findNearest(
  matcher: (candidate: string) => Promise<?string>,
  startDir: string,
  stopDir: ?string,
): Promise<?string> {
  const candidates = [];
  let candidateDir = startDir;
  while (candidateDir !== stopDir) {
    candidates.push(candidateDir);
    const parentDir = nuclideUri.dirname(candidateDir);
    if (parentDir === candidateDir) {
      // filesystem root reached
      break;
    } else {
      candidateDir = parentDir;
    }
  }
  const results = await Promise.all(candidates.map(matcher));
  for (const result of results) {
    if (result != null) {
      return result;
    }
  }
  return null;
}
コード例 #10
0
  async _getModifiedFlags(
    src: string,
    originalFlags: Array<string>,
  ): Promise<Array<string>> {
    // Look for the project-wide flags
    const projectFlagsDir = await fsPromise.findNearestFile(
      PROJECT_CLANG_FLAGS_FILE,
      nuclideUri.dirname(src),
    );
    if (projectFlagsDir == null) {
      return originalFlags;
    }
    const projectFlagsFile = nuclideUri.join(
      projectFlagsDir,
      PROJECT_CLANG_FLAGS_FILE,
    );
    const projectFlags = await this._loadProjectCompilerFlags(projectFlagsFile);
    if (projectFlags == null) {
      return originalFlags;
    }

    return originalFlags
      .filter(flag => projectFlags.ignoredCompilerFlags.indexOf(flag) === -1)
      .concat(projectFlags.extraCompilerFlags);
  }
コード例 #11
0
  static async _findSourceFileForHeader(
    header: string,
    projectRoot: string,
  ): Promise<?string> {
    // Basic implementation: look at files in the same directory for paths
    // with matching file names.
    const dir = nuclideUri.dirname(header);
    const files = await fsPromise.readdir(dir);
    const basename = ClangFlagsManager._getFileBasename(header);
    for (const file of files) {
      if (
        isSourceFile(file) &&
        ClangFlagsManager._getFileBasename(file) === basename
      ) {
        return nuclideUri.join(dir, file);
      }
    }

    // Try searching all subdirectories for source files that include this header.
    // Give up after INCLUDE_SEARCH_TIMEOUT.
    return findIncludingSourceFile(header, projectRoot)
      .timeout(INCLUDE_SEARCH_TIMEOUT)
      .catch(() => Observable.of(null))
      .toPromise();
  }
コード例 #12
0
const getPackageJson = memoize(async (dir: NuclideUri) => {
  // Bail out at the FS root.
  const parent = nuclideUri.dirname(dir);
  if (parent === dir) {
    return null;
  }

  const packageJson = nuclideUri.join(dir, 'package.json');
  let fileContents;
  try {
    fileContents = await fsPromise.readFile(packageJson, 'utf8');
  } catch (err) {
    return getPackageJson(parent);
  }
  try {
    return {
      dirname: dir,
      main: nuclideUri.resolve(
        dir,
        JSON.parse(fileContents).main || 'index.js',
      ),
    };
  } catch (err) {
    return null;
  }
});
コード例 #13
0
/**
 * Returns the directory of the nearest package.json if `file` matches the "main" field.
 * This ensures that e.g. package/index.js can be imported as just "package".
 */
async function checkIfMain(file: NuclideUri): Promise<?NuclideUri> {
  const pkgJson = await getPackageJson(nuclideUri.dirname(file));
  return pkgJson != null &&
    nuclideUri.stripExtension(pkgJson.main) === nuclideUri.stripExtension(file)
    ? pkgJson.dirname
    : null;
}
コード例 #14
0
ファイル: hg-repository.js プロジェクト: JoelMarcey/nuclide
/**
 * This function returns HgRepositoryDescription filled with a repoPath and
 * originURL iff it finds that the given directory is within an Hg repository.
 */
export default function findHgRepository(
  startDirectoryPath: string,
): ?HgRepositoryDescription {
  if (!nuclideUri.isLocal(startDirectoryPath)) {
    return null;
  }
  let workingDirectoryPath = startDirectoryPath;
  for (;;) {
    const repoPath = nuclideUri.join(workingDirectoryPath, '.hg');
    if (tryIsDirectorySync(repoPath)) {
      let originURL = null;
      // Note that .hg/hgrc will not exist in a local repo created via `hg init`, for example.
      const hgrc = tryReadFileSync(nuclideUri.join(repoPath, 'hgrc'));
      if (hgrc != null) {
        const config = ini.parse(hgrc);
        if (
          typeof config.paths === 'object' &&
          typeof config.paths.default === 'string'
        ) {
          originURL = config.paths.default;
        }
      }
      return {repoPath, originURL, workingDirectoryPath};
    }
    const parentDir = nuclideUri.dirname(workingDirectoryPath);
    if (parentDir === workingDirectoryPath) {
      return null;
    } else {
      workingDirectoryPath = parentDir;
    }
  }
}
コード例 #15
0
ファイル: RemoteFile.js プロジェクト: ev1stensberg/nuclide
 getParent(): RemoteDirectory {
   const directoryPath = nuclideUri.dirname(this._path);
   const remoteConnection = this._server.getRemoteConnectionForUri(this._path);
   const hgRepositoryDescription = remoteConnection != null
     ? remoteConnection.getHgRepositoryDescription()
     : null;
   return this._server.createDirectory(directoryPath, hgRepositoryDescription);
 }
コード例 #16
0
export async function findNearestCompilationDbDir(
  source: NuclideUri,
): Promise<?NuclideUri> {
  return fs.findNearestFile(
    COMPILATION_DATABASE_FILE,
    nuclideUri.dirname(source),
  );
}
コード例 #17
0
 ].reduce((acc, servicePath) => {
   if (fs.existsSync(servicePath)) {
     const basedir = nuclideUri.dirname(servicePath);
     const src = fs.readFileSync(servicePath, 'utf8');
     const jsonConfig: Array<Object> = JSON.parse(src);
     acc.push(...createServiceConfigObject(basedir, jsonConfig));
   }
   return acc;
 }, []);
コード例 #18
0
      const selectedPaths = nodes.map(node => {
        const nodePath = FileTreeHelpers.keyToPath(node.uri);
        const parentOfRoot = nuclideUri.dirname(node.rootUri);

        // Fix Windows paths to avoid end of filename truncation
        return isRunningInWindows()
          ? nuclideUri.relative(parentOfRoot, nodePath).replace(/\//g, '\\')
          : nuclideUri.relative(parentOfRoot, nodePath);
      });
コード例 #19
0
ファイル: CtagsService.js プロジェクト: JoelMarcey/nuclide
  findTags(
    query: string,
    options?: {
      caseInsensitive?: boolean,
      partialMatch?: boolean,
      limit?: number,
    },
  ): Promise<Array<CtagsResult>> {
    let ctags;
    try {
      ctags = require('nuclide-prebuilt-libs/ctags');
    } catch (e) {
      getLogger('nuclide-ctags-rpc').error(
        'Could not load the ctags package:',
        e,
      );
      return Promise.resolve([]);
    }

    const dir = nuclideUri.dirname(this._tagsPath);
    return new Promise((resolve, reject) => {
      ctags.findTags(
        this._tagsPath,
        query,
        options,
        async (error, tags: Array<Object>) => {
          if (error != null) {
            reject(error);
          } else {
            const processed = await Promise.all(
              tags.map(async tag => {
                // Convert relative paths to absolute ones.
                tag.file = nuclideUri.join(dir, tag.file);
                // Tag files are often not perfectly in sync - filter out missing files.
                if (await fsPromise.exists(tag.file)) {
                  if (tag.fields != null) {
                    const map = new Map();
                    for (const key in tag.fields) {
                      map.set(key, tag.fields[key]);
                    }
                    tag.fields = map;
                  }
                  return tag;
                }
                return null;
              }),
            );
            // $FlowFixMe(>=0.55.0) Flow suppress
            resolve(arrayCompact(processed));
          }
        },
      );
    });
  }
コード例 #20
0
ファイル: RemoteDirectory.js プロジェクト: JoelMarcey/nuclide
 getParent(): RemoteDirectory {
   if (this.isRoot()) {
     return this;
   } else {
     const uri = nuclideUri.createRemoteUri(
       this._host,
       nuclideUri.dirname(this._localPath),
     );
     return this._server.createDirectory(uri, this._hgRepositoryDescription);
   }
 }
コード例 #21
0
ファイル: Config.js プロジェクト: JoelMarcey/nuclide
function flowConfigToResolveDirnames(
  flowFile: string,
  flowFileContents: string,
): Array<string> {
  const resolveDirs = flowFileContents.match(
    /module.system.node.resolve_dirname=([^\s]+)/g,
  );
  return resolveDirs
    ? resolveDirs.map(dirString =>
        nuclideUri.join(nuclideUri.dirname(flowFile), dirString.split('=')[1]),
      )
    : [nuclideUri.join(nuclideUri.dirname(flowFile), 'node_modules')];
}
コード例 #22
0
  async _getDependencies(
    src: string,
    basePath: string,
    kind: string,
  ): Promise<Array<string>> {
    // Since we're doing string-based comparisons, resolve paths to their
    // real (symlinks followed) paths.
    const realBasePath = await fsPromise.realpath(basePath);
    const realSrcPath = await fsPromise.realpath(src);

    let currPath = nuclideUri.dirname(realSrcPath);

    while (nuclideUri.contains(realBasePath, currPath)) {
      const relativePath = nuclideUri.relative(realBasePath, currPath);
      if (relativePath === '.' || relativePath === '') {
        break;
      }
      const searchRoot = this._getBuckTargetForDir(relativePath);
      try {
        // Not using Promise.all since we want to break as soon as one query returns
        // a non-empty result, and we don't want concurrent buck queries.
        // eslint-disable-next-line no-await-in-loop
        const results = await BuckService.query(
          basePath,
          `kind(${kind}, rdeps(${searchRoot}, owner(${src})))`,
        );
        if (results.length > 0) {
          return results;
        }
      } catch (e) {
        // Ignore - most likely because the currPath doesn't contain a
        // BUCK/TARGETS file.
      }
      currPath = nuclideUri.dirname(currPath);
    }

    return [];
  }
コード例 #23
0
 _visitImport(serviceParser: ServiceParser, imp: Import): void {
   let resolved = resolveFrom(nuclideUri.dirname(this._fileName), imp.file);
   // Prioritize .flow files.
   if (fs.existsSync(resolved + '.flow')) {
     resolved += '.flow';
   }
   const importedFile = getFileParser(resolved);
   const exportNode = importedFile.getExports().get(imp.imported);
   invariant(
     exportNode != null,
     `Could not find export for ${imp.imported} in ${resolved}`,
   );
   importedFile.parseExport(serviceParser, exportNode);
 }
コード例 #24
0
ファイル: buildFiles.js プロジェクト: JoelMarcey/nuclide
export async function findNearestBuildFile(
  textEditorPath: NuclideUri,
): Promise<?NuclideUri> {
  const buckRoot = await getBuckProjectRoot(textEditorPath);
  if (buckRoot != null) {
    const buildFileName = await getBuildFileName(buckRoot);
    const fsService = getFileSystemServiceByNuclideUri(textEditorPath);
    return fsService.findNearestAncestorNamed(
      buildFileName,
      nuclideUri.dirname(textEditorPath),
    );
  }
  return null;
}
コード例 #25
0
  async _loadFlagsFromCompilationDatabase(
    dbFile: string,
  ): Promise<Map<string, ClangFlags>> {
    const cache = this._compilationDatabases.get(dbFile);
    if (cache != null) {
      return cache;
    }

    const flags = new Map();
    try {
      const contents = await fsPromise.readFile(dbFile, 'utf8');
      const data = JSON.parse(contents);
      invariant(data instanceof Array);
      const dbDir = nuclideUri.dirname(dbFile);
      await Promise.all(
        data.map(async entry => {
          const {command, file} = entry;
          const directory = await fsPromise.realpath(
            // Relative directories aren't part of the spec, but resolving them
            // relative to the compile_commands.json location seems reasonable.
            nuclideUri.resolve(dbDir, entry.directory),
            this._realpathCache,
          );
          const filename = nuclideUri.resolve(directory, file);
          if (await fsPromise.exists(filename)) {
            const realpath = await fsPromise.realpath(
              filename,
              this._realpathCache,
            );
            const result = {
              rawData: {
                flags: command,
                file,
                directory,
              },
              flagsFile: dbFile,
            };
            flags.set(realpath, result);
            this._pathToFlags.set(realpath, Promise.resolve(result));
          }
        }),
      );
      this._compilationDatabases.set(dbFile, flags);
    } catch (e) {
      logger.error(`Error reading compilation flags from ${dbFile}`, e);
    }
    return flags;
  }
コード例 #26
0
 beforeEach(() => {
   jasmine.useRealClock();
   // Simulated scribe_cat script which saves data into:
   //   ${process.env['SCRIBE_MOCK_PATH'] + category_name}
   // It terminates once we cut off the stdin stream.
   const scribeCatMockCommandPath = nuclideUri.join(
     nuclideUri.dirname(__filename),
     'scripts',
     'scribe_cat_mock',
   );
   waitsForPromise(async () => {
     tempDir = await fsPromise.tempdir();
     originalCommand = __test__.setScribeCatCommand(scribeCatMockCommandPath);
     process.env.SCRIBE_MOCK_PATH = tempDir;
   });
 });
コード例 #27
0
ファイル: utils.js プロジェクト: JoelMarcey/nuclide
export async function guessBuildFile(file: string): Promise<?string> {
  const dir = nuclideUri.dirname(file);
  let bestMatch = null;
  await Promise.all(
    [...BUCK_BUILD_FILES, 'compile_commands.json'].map(async name => {
      const nearestDir = await fsPromise.findNearestFile(name, dir);
      if (nearestDir != null) {
        const match = nuclideUri.join(nearestDir, name);
        // Return the closest (most specific) match.
        if (bestMatch == null || match.length > bestMatch.length) {
          bestMatch = match;
        }
      }
    }),
  );
  return bestMatch;
}
コード例 #28
0
 entries.forEach(entry => {
   const entryPath = nuclideUri.join(subscription.path, entry.name);
   const observer = entityObserver.get(entryPath);
   if (observer != null) {
     // TODO(most): handle `rename`, if needed.
     if (!entry.exists) {
       observer.next('delete');
     } else {
       observer.next('change');
     }
   }
   // A file watch event can also be considered a directory change
   // for the parent directory if a file was created or deleted.
   if (entry.new || !entry.exists) {
     directoryChanges.add(nuclideUri.dirname(entryPath));
   }
 });
コード例 #29
0
      (transientSettings, savedSettings) => {
        const {config} = props;
        const {
          cwdPropertyName,
          scriptPropertyName,
          launch,
          scriptExtension,
        } = config;
        const atomInputValues = new Map(savedSettings.atomInputValues || []);

        const scriptPath =
          (scriptPropertyName != null &&
            atomInputValues.get(scriptPropertyName)) ||
          (scriptExtension != null && getActiveScriptPath(scriptExtension)) ||
          '';
        if (cwdPropertyName != null) {
          const cwd =
            atomInputValues.get(cwdPropertyName) ||
            (scriptPath !== '' ? nuclideUri.dirname(scriptPath) : '');
          if (cwd !== '') {
            atomInputValues.set(cwdPropertyName, cwd);
          }
        }
        if (launch) {
          if (scriptPath !== '' && scriptPropertyName != null) {
            atomInputValues.set(scriptPropertyName, scriptPath);
          }
        }
        const booleanValues = new Map(savedSettings.booleanValues || []);
        const enumValues = new Map(savedSettings.enumValues || []);
        this._populateDefaultValues(
          config,
          atomInputValues,
          booleanValues,
          enumValues,
        );
        // do not serialize and deserialize processes
        const processTableValues = new Map();
        this.setState({
          atomInputValues,
          booleanValues,
          enumValues,
          processTableValues,
        });
      },
コード例 #30
0
ファイル: Config.js プロジェクト: JoelMarcey/nuclide
 .map(workspace => {
   // Yarn workspaces can be a glob pattern (folder/*) or specific paths.
   // Either way, getting the dirname should work for most cases.
   if (typeof workspace === 'string') {
     try {
       return nuclideUri.resolve(
         root,
         nuclideUri.dirname(workspace),
       );
     } catch (err) {
       getLogger('js-imports-server').error(
         `Could not parse Yarn workspace: ${workspace}`,
         err,
       );
       return null;
     }
   }
 })